From 6c8378eaf1edbbefe6aaa3672b0127816a004fd7 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 23 Nov 2011 15:14:07 +0100 Subject: Say hello to QtQuick module This change moves the QtQuick 2 types and C++ API (including SceneGraph) to a new module (AKA library), QtQuick. 99% of this change is moving files from src/declarative to src/quick, and from tests/auto/declarative to tests/auto/qtquick2. The loading of QtQuick 2 ("import QtQuick 2.0") is now delegated to a plugin, src/imports/qtquick2, just like it's done for QtQuick 1. All tools, examples, and tests that use QtQuick C++ API have gotten "QT += quick" or "QT += quick-private" added to their .pro file. A few additional internal QtDeclarative classes had to be exported (via Q_DECLARATIVE_PRIVATE_EXPORT) since they're needed by the QtQuick 2 implementation. The old header locations (e.g. QtDeclarative/qquickitem.h) will still be supported for some time, but will produce compile-time warnings. (To avoid the QtQuick implementation using the compatibility headers (since QtDeclarative's includepath comes first), a few include statements were modified, e.g. from "#include " to "#include ".) There's a change in qtbase that automatically adds QtQuick to the module list if QtDeclarative is used. Together with the compatibility headers, this should help reduce the migration pain for existing projects. In theory, simply getting an existing QtDeclarative-based project to compile and link shouldn't require any changes for now -- but porting to the new scheme is of course recommended, and will eventually become mandatory. Task-number: QTBUG-22889 Reviewed-by: Lars Knoll Change-Id: Ia52be9373172ba2f37e7623231ecb060316c96a7 Reviewed-by: Kent Hansen Reviewed-by: Sergio Ahumada --- tests/auto/auto.pro | 1 + .../tst_qdeclarativedebugjs.cpp | 2 +- .../tst_qdeclarativedebugservice.cpp | 2 +- .../tst_qdeclarativedebugtrace.cpp | 2 +- .../qdeclarativeenginedebug.pro | 2 +- .../tst_qdeclarativeenginedebug.cpp | 2 +- .../debugger/qdeclarativeinspector/app/app.pro | 2 +- .../debugger/qdeclarativeinspector/app/main.cpp | 2 +- .../qv8profilerservice/tst_qv8profilerservice.cpp | 2 +- tests/auto/declarative/declarative.pro | 52 - tests/auto/declarative/examples/data/dummytest.qml | 6 - .../examples/data/webbrowser/webbrowser.qml | 6 - tests/auto/declarative/examples/examples.pro | 10 - tests/auto/declarative/examples/tst_examples.cpp | 253 - tests/auto/declarative/geometry/geometry.pro | 9 - tests/auto/declarative/geometry/tst_geometry.cpp | 181 - tests/auto/declarative/nodes/nodes.pro | 9 - tests/auto/declarative/nodes/tst_nodestest.cpp | 354 -- .../qdeclarativeanimations/data/Double.qml | 14 - .../qdeclarativeanimations/data/attached.qml | 34 - .../qdeclarativeanimations/data/badproperty1.qml | 21 - .../qdeclarativeanimations/data/badproperty2.qml | 21 - .../qdeclarativeanimations/data/badtype1.qml | 12 - .../qdeclarativeanimations/data/badtype2.qml | 12 - .../qdeclarativeanimations/data/badtype3.qml | 12 - .../qdeclarativeanimations/data/badtype4.qml | 27 - .../data/disabledTransition.qml | 30 - .../qdeclarativeanimations/data/dontAutoStart.qml | 18 - .../qdeclarativeanimations/data/dontStart.qml | 19 - .../qdeclarativeanimations/data/dontStart2.qml | 19 - .../qdeclarativeanimations/data/dotproperty.qml | 24 - .../data/doubleRegistrationBug.qml | 8 - .../qdeclarativeanimations/data/mixedtype1.qml | 25 - .../qdeclarativeanimations/data/mixedtype2.qml | 25 - .../data/nonTransitionBug.qml | 30 - .../qdeclarativeanimations/data/pathAnimation.qml | 27 - .../qdeclarativeanimations/data/pathAnimation2.qml | 26 - .../data/pathAnimationNoStart.qml | 27 - .../data/pathInterpolator.qml | 13 - .../data/pathInterpolatorBack.qml | 11 - .../qdeclarativeanimations/data/pathTransition.qml | 41 - .../data/pauseBindingBug.qml | 17 - .../qdeclarativeanimations/data/pauseBug.qml | 7 - .../qdeclarativeanimations/data/properties.qml | 14 - .../qdeclarativeanimations/data/properties2.qml | 14 - .../qdeclarativeanimations/data/properties3.qml | 14 - .../qdeclarativeanimations/data/properties4.qml | 14 - .../qdeclarativeanimations/data/properties5.qml | 14 - .../data/propertiesTransition.qml | 29 - .../data/propertiesTransition2.qml | 29 - .../data/propertiesTransition3.qml | 29 - .../data/propertiesTransition4.qml | 29 - .../data/propertiesTransition5.qml | 29 - .../data/propertiesTransition6.qml | 29 - .../data/propertiesTransition7.qml | 29 - .../data/registrationBug.qml | 18 - .../qdeclarativeanimations/data/rotation.qml | 48 - .../qdeclarativeanimations/data/runningTrueBug.qml | 30 - .../data/transitionAssignmentBug.qml | 12 - .../qdeclarativeanimations/data/valuesource.qml | 14 - .../qdeclarativeanimations/data/valuesource2.qml | 14 - .../qdeclarativeanimations.pro | 12 - .../tst_qdeclarativeanimations.cpp | 1106 ----- .../qdeclarativeapplication.pro | 7 - .../tst_qdeclarativeapplication.cpp | 143 - .../qdeclarativebehaviors/data/binding.qml | 26 - .../qdeclarativebehaviors/data/color.qml | 24 - .../qdeclarativebehaviors/data/cpptrigger.qml | 11 - .../data/delayedRegistration.qml | 25 - .../qdeclarativebehaviors/data/disabled.qml | 27 - .../qdeclarativebehaviors/data/dontStart.qml | 18 - .../qdeclarativebehaviors/data/empty.qml | 23 - .../qdeclarativebehaviors/data/explicit.qml | 26 - .../qdeclarativebehaviors/data/groupProperty.qml | 23 - .../qdeclarativebehaviors/data/groupProperty2.qml | 23 - .../data/groupedPropertyCrash.qml | 10 - .../qdeclarativebehaviors/data/loop.qml | 19 - .../qdeclarativebehaviors/data/nonSelecting2.qml | 26 - .../qdeclarativebehaviors/data/parent.qml | 28 - .../qdeclarativebehaviors/data/qtbug12295.qml | 17 - .../data/reassignedAnimation.qml | 32 - .../qdeclarativebehaviors/data/runningTrue.qml | 20 - .../qdeclarativebehaviors/data/scripttrigger.qml | 16 - .../qdeclarativebehaviors/data/simple.qml | 26 - .../data/startOnCompleted.qml | 15 - .../qdeclarativebehaviors/data/startup.qml | 17 - .../qdeclarativebehaviors/data/startup2.qml | 16 - .../qdeclarativebehaviors/data/valueType.qml | 13 - .../qdeclarativebehaviors.pro | 12 - .../tst_qdeclarativebehaviors.cpp | 474 -- .../qdeclarativebinding/qdeclarativebinding.pro | 2 +- .../tst_qdeclarativebinding.cpp | 4 +- .../qdeclarativechangeset.pro | 2 +- .../tst_qdeclarativecomponent.cpp | 3 +- .../qdeclarativeconnection.pro | 2 +- .../tst_qdeclarativeconnection.cpp | 2 +- .../tst_qdeclarativeconsole.cpp | 2 +- .../tst_qdeclarativecontext.cpp | 2 +- .../qdeclarativeecmascript.pro | 6 +- .../tst_qdeclarativeecmascript.cpp | 2 +- .../qdeclarativeerror/tst_qdeclarativeerror.cpp | 2 +- .../tst_qdeclarativeexpression.cpp | 2 +- .../tst_qdeclarativefolderlistmodel.cpp | 2 +- .../qdeclarativefontloader/data/daniel.ttf | Bin 51984 -> 0 bytes .../qdeclarativefontloader/data/dummy.ttf | 0 .../qdeclarativefontloader/data/qtbug-20268.qml | 27 - .../qdeclarativefontloader/data/tarzeau_ocr_a.ttf | Bin 24544 -> 0 bytes .../qdeclarativefontloader.pro | 14 - .../tst_qdeclarativefontloader.cpp | 254 - .../qdeclarativeimageprovider.pro | 2 +- .../tst_qdeclarativeincubator.cpp | 2 +- .../qdeclarativeinfo/tst_qdeclarativeinfo.cpp | 2 +- .../qdeclarativelanguage/qdeclarativelanguage.pro | 6 +- .../qdeclarativelistcompositor.pro | 2 +- .../qdeclarativelistmodel.pro | 2 +- .../tst_qdeclarativelistmodel.cpp | 6 +- .../tst_qdeclarativelistreference.cpp | 2 +- .../qdeclarativelocale/tst_qdeclarativelocale.cpp | 3 +- .../tst_qdeclarativemoduleplugin.cpp | 4 +- .../tst_qdeclarativemoduleplugin.pro | 4 +- .../auto/declarative/qdeclarativepath/data/arc.qml | 11 - .../declarative/qdeclarativepath/data/curve.qml | 9 - .../auto/declarative/qdeclarativepath/data/svg.qml | 5 - .../qdeclarativepath/qdeclarativepath.pro | 13 - .../qdeclarativepath/tst_qdeclarativepath.cpp | 164 - .../qdeclarativepixmapcache/data/exists.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/exists1.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/exists2.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists1.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists2.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists3.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists4.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists5.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists6.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists7.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/http/exists8.png | Bin 2738 -> 0 bytes .../qdeclarativepixmapcache/data/massive.png | Bin 31834 -> 0 bytes .../qdeclarativepixmapcache.pro | 20 - .../tst_qdeclarativepixmapcache.cpp | 458 -- .../tst_qdeclarativeproperty.cpp | 2 +- .../qdeclarativepropertymap.pro | 2 +- .../tst_qdeclarativepropertymap.cpp | 2 +- .../declarative/qdeclarativeqt/qdeclarativeqt.pro | 2 +- .../qdeclarativeqt/tst_qdeclarativeqt.cpp | 4 +- .../data/smoothedanimation1.qml | 3 - .../data/smoothedanimation2.qml | 5 - .../data/smoothedanimation3.qml | 6 - .../data/smoothedanimationBehavior.qml | 24 - .../data/smoothedanimationValueSource.qml | 13 - .../qdeclarativesmoothedanimation.pro | 13 - .../tst_qdeclarativesmoothedanimation.cpp | 211 - .../data/springanimation1.qml | 4 - .../data/springanimation2.qml | 9 - .../data/springanimation3.qml | 8 - .../qdeclarativespringanimation.pro | 13 - .../tst_qdeclarativespringanimation.cpp | 131 - .../qdeclarativesqldatabase.pro | 2 +- .../tst_qdeclarativesqldatabase.cpp | 4 +- .../qdeclarativestates/data/ExtendedRectangle.qml | 19 - .../data/Implementation/MyType.qml | 32 - .../data/Implementation/images/qt-logo.png | Bin 5149 -> 0 bytes .../qdeclarativestates/data/QTBUG-14830.qml | 29 - .../qdeclarativestates/data/anchorChanges1.qml | 23 - .../qdeclarativestates/data/anchorChanges2.qml | 21 - .../qdeclarativestates/data/anchorChanges3.qml | 29 - .../qdeclarativestates/data/anchorChanges4.qml | 22 - .../qdeclarativestates/data/anchorChanges5.qml | 22 - .../qdeclarativestates/data/anchorChangesCrash.qml | 14 - .../qdeclarativestates/data/anchorRewindBug.qml | 37 - .../qdeclarativestates/data/anchorRewindBug2.qml | 25 - .../data/attachedPropertyChanges.qml | 20 - .../data/autoStateAtStartupRestoreBug.qml | 18 - .../qdeclarativestates/data/avoidFastForward.qml | 17 - .../qdeclarativestates/data/basicBinding.qml | 12 - .../qdeclarativestates/data/basicBinding2.qml | 12 - .../qdeclarativestates/data/basicBinding3.qml | 13 - .../qdeclarativestates/data/basicBinding4.qml | 17 - .../qdeclarativestates/data/basicChanges.qml | 10 - .../qdeclarativestates/data/basicChanges2.qml | 15 - .../qdeclarativestates/data/basicChanges3.qml | 15 - .../qdeclarativestates/data/basicChanges4.qml | 19 - .../qdeclarativestates/data/basicExtension.qml | 16 - .../qdeclarativestates/data/deleting.qml | 11 - .../qdeclarativestates/data/deletingState.qml | 13 - .../qdeclarativestates/data/editProperties.qml | 34 - .../qdeclarativestates/data/explicit.qml | 15 - .../qdeclarativestates/data/extendsBug.qml | 26 - .../qdeclarativestates/data/fakeExtension.qml | 16 - .../qdeclarativestates/data/illegalObj.qml | 12 - .../qdeclarativestates/data/illegalTempState.qml | 21 - .../declarative/qdeclarativestates/data/image.png | Bin 173 -> 0 bytes .../qdeclarativestates/data/legalTempState.qml | 23 - .../qdeclarativestates/data/nonExistantProp.qml | 11 - .../qdeclarativestates/data/parentChange1.qml | 37 - .../qdeclarativestates/data/parentChange2.qml | 31 - .../qdeclarativestates/data/parentChange3.qml | 42 - .../qdeclarativestates/data/parentChange4.qml | 30 - .../qdeclarativestates/data/parentChange5.qml | 30 - .../qdeclarativestates/data/parentChange6.qml | 30 - .../qdeclarativestates/data/propertyErrors.qml | 10 - .../declarative/qdeclarativestates/data/reset.qml | 19 - .../qdeclarativestates/data/restoreEntryValues.qml | 14 - .../qdeclarativestates/data/returnToBase.qml | 21 - .../qdeclarativestates/data/revertListBug.qml | 47 - .../declarative/qdeclarativestates/data/script.qml | 10 - .../qdeclarativestates/data/signalOverride.qml | 18 - .../qdeclarativestates/data/signalOverride2.qml | 9 - .../data/signalOverrideCrash.qml | 15 - .../data/signalOverrideCrash2.qml | 24 - .../data/signalOverrideCrash3.qml | 27 - .../qdeclarativestates/data/unnamedWhen.qml | 14 - .../qdeclarativestates/data/urlResolution.qml | 12 - .../qdeclarativestates/data/whenOrdering.qml | 11 - .../qdeclarativestates/qdeclarativestates.pro | 12 - .../qdeclarativestates/tst_qdeclarativestates.cpp | 1596 ------- .../qdeclarativestyledtext.pro | 8 - .../tst_qdeclarativestyledtext.cpp | 101 - .../qdeclarativesystempalette.pro | 8 - .../tst_qdeclarativesystempalette.cpp | 185 - .../qdeclarativetimer/qdeclarativetimer.pro | 8 - .../qdeclarativetimer/tst_qdeclarativetimer.cpp | 334 -- .../tst_qdeclarativetranslation.cpp | 2 +- .../tst_qdeclarativevaluetypes.cpp | 2 +- .../tst_qdeclarativeworkerscript.cpp | 2 +- .../qdeclarativexmlhttprequest.pro | 6 +- .../tst_qdeclarativexmlhttprequest.cpp | 2 +- .../qdeclarativexmllistmodel/data/empty.xml | 0 .../qdeclarativexmllistmodel/data/get.qml | 61 - .../qdeclarativexmllistmodel/data/model.qml | 11 - .../qdeclarativexmllistmodel/data/model.xml | 54 - .../qdeclarativexmllistmodel/data/model2.xml | 14 - .../data/propertychanges.qml | 11 - .../qdeclarativexmllistmodel/data/recipes.qml | 11 - .../qdeclarativexmllistmodel/data/recipes.xml | 90 - .../qdeclarativexmllistmodel/data/roleCrash.qml | 8 - .../qdeclarativexmllistmodel/data/roleErrors.qml | 11 - .../qdeclarativexmllistmodel/data/roleKeys.qml | 13 - .../qdeclarativexmllistmodel/data/testtypes.qml | 8 - .../qdeclarativexmllistmodel/data/unique.qml | 9 - .../qdeclarativexmllistmodel.pro | 12 - .../tst_qdeclarativexmllistmodel.cpp | 961 ---- tests/auto/declarative/qmlmin/tst_qmlmin.cpp | 2 +- .../declarative/qquickanchors/data/anchors.qml | 162 - .../declarative/qquickanchors/data/centerin.qml | 12 - .../qquickanchors/data/centerinRotation.qml | 17 - .../auto/declarative/qquickanchors/data/crash1.qml | 11 - tests/auto/declarative/qquickanchors/data/fill.qml | 14 - .../declarative/qquickanchors/data/hvCenter.qml | 11 - .../auto/declarative/qquickanchors/data/loop1.qml | 8 - .../auto/declarative/qquickanchors/data/loop2.qml | 20 - .../declarative/qquickanchors/data/margins.qml | 13 - .../declarative/qquickanchors/qquickanchors.pro | 12 - .../qquickanchors/tst_qquickanchors.cpp | 692 --- .../qquickanimatedimage/data/colors.gif | Bin 505 -> 0 bytes .../qquickanimatedimage/data/colors.qml | 5 - .../qquickanimatedimage/data/hearts.gif | Bin 6524 -> 0 bytes .../qquickanimatedimage/data/hearts.qml | 6 - .../declarative/qquickanimatedimage/data/qmldir | 1 - .../qquickanimatedimage/data/qtbug-16520.qml | 17 - .../qquickanimatedimage/data/stickman.gif | Bin 164923 -> 0 bytes .../qquickanimatedimage/data/stickman.qml | 5 - .../qquickanimatedimage/data/stickmanerror1.qml | 6 - .../qquickanimatedimage/data/stickmanpause.qml | 7 - .../qquickanimatedimage/data/stickmanscaled.qml | 7 - .../qquickanimatedimage/data/stickmanstopped.qml | 6 - .../qquickanimatedimage/qquickanimatedimage.pro | 13 - .../tst_qquickanimatedimage.cpp | 378 -- .../qquickborderimage/data/colors-mirror.png | Bin 5554 -> 0 bytes .../qquickborderimage/data/colors-round-quotes.sci | 7 - .../qquickborderimage/data/colors-round-remote.sci | 7 - .../qquickborderimage/data/colors-round.sci | 7 - .../declarative/qquickborderimage/data/colors.png | Bin 1655 -> 0 bytes .../qquickborderimage/data/heart200.png | Bin 7943 -> 0 bytes .../declarative/qquickborderimage/data/invalid.sci | 7 - .../declarative/qquickborderimage/data/mirror.qml | 7 - .../qquickborderimage/qquickborderimage.pro | 14 - .../qquickborderimage/tst_qquickborderimage.cpp | 376 -- .../auto/declarative/qquickcanvas/data/window.qml | 9 - .../auto/declarative/qquickcanvas/qquickcanvas.pro | 8 - .../declarative/qquickcanvas/tst_qquickcanvas.cpp | 557 --- .../declarative/qquickcanvasitem/data/anim-gr.gif | Bin 241 -> 0 bytes .../declarative/qquickcanvasitem/data/anim-gr.png | Bin 460 -> 0 bytes .../qquickcanvasitem/data/anim-poster-gr.png | Bin 422 -> 0 bytes .../qquickcanvasitem/data/background.png | Bin 86 -> 0 bytes .../declarative/qquickcanvasitem/data/broken.png | Bin 87 -> 0 bytes .../qquickcanvasitem/data/ggrr-256x256.png | Bin 120 -> 0 bytes .../qquickcanvasitem/data/green-16x16.png | Bin 92 -> 0 bytes .../qquickcanvasitem/data/green-1x1.png | Bin 82 -> 0 bytes .../qquickcanvasitem/data/green-256x256.png | Bin 103 -> 0 bytes .../qquickcanvasitem/data/green-2x2.png | Bin 118 -> 0 bytes .../declarative/qquickcanvasitem/data/green.png | Bin 87 -> 0 bytes .../qquickcanvasitem/data/grgr-256x256.png | Bin 130 -> 0 bytes .../qquickcanvasitem/data/red-16x16.png | Bin 130 -> 0 bytes .../auto/declarative/qquickcanvasitem/data/red.png | Bin 87 -> 0 bytes .../qquickcanvasitem/data/redtransparent.png | Bin 109 -> 0 bytes .../qquickcanvasitem/data/rgrg-256x256.png | Bin 131 -> 0 bytes .../qquickcanvasitem/data/rrgg-256x256.png | Bin 120 -> 0 bytes .../qquickcanvasitem/data/testhelper.js | 18 - .../qquickcanvasitem/data/transparent.png | Bin 100 -> 0 bytes .../qquickcanvasitem/data/transparent50.png | Bin 155 -> 0 bytes .../declarative/qquickcanvasitem/data/tst_arc.qml | 487 -- .../qquickcanvasitem/data/tst_arcto.qml | 410 -- .../qquickcanvasitem/data/tst_canvas.qml | 274 -- .../qquickcanvasitem/data/tst_composite.qml | 380 -- .../qquickcanvasitem/data/tst_drawimage.qml | 662 --- .../qquickcanvasitem/data/tst_fillStyle.qml | 113 - .../qquickcanvasitem/data/tst_fillrect.qml | 23 - .../qquickcanvasitem/data/tst_gradient.qml | 981 ---- .../declarative/qquickcanvasitem/data/tst_line.qml | 831 ---- .../declarative/qquickcanvasitem/data/tst_path.qml | 1443 ------ .../qquickcanvasitem/data/tst_pattern.qml | 34 - .../qquickcanvasitem/data/tst_pixel.qml | 30 - .../qquickcanvasitem/data/tst_shadow.qml | 59 - .../qquickcanvasitem/data/tst_state.qml | 390 -- .../qquickcanvasitem/data/tst_strokeStyle.qml | 48 - .../declarative/qquickcanvasitem/data/tst_text.qml | 34 - .../qquickcanvasitem/data/tst_transform.qml | 487 -- .../declarative/qquickcanvasitem/data/yellow.png | Bin 95 -> 0 bytes .../declarative/qquickcanvasitem/data/yellow75.png | Bin 150 -> 0 bytes .../qquickcanvasitem/qquickcanvasitem.pro | 33 - .../qquickcanvasitem/tst_qquickcanvasitem.cpp | 42 - tests/auto/declarative/qquickdrag/qquickdrag.pro | 9 - .../auto/declarative/qquickdrag/tst_qquickdrag.cpp | 827 ---- .../declarative/qquickdroparea/qquickdroparea.pro | 9 - .../qquickdroparea/tst_qquickdroparea.cpp | 1117 ----- .../declarative/qquickflickable/data/disabled.qml | 30 - .../qquickflickable/data/flickable01.qml | 4 - .../qquickflickable/data/flickable02.qml | 14 - .../qquickflickable/data/flickable03.qml | 14 - .../qquickflickable/data/flickable04.qml | 22 - .../data/flickableqgraphicswidget.qml | 7 - .../declarative/qquickflickable/data/margins.qml | 19 - .../qquickflickable/data/nestedPressDelay.qml | 33 - .../declarative/qquickflickable/data/resize.qml | 27 - .../declarative/qquickflickable/data/wheel.qml | 25 - .../qquickflickable/qquickflickable.pro | 12 - .../qquickflickable/tst_qquickflickable.cpp | 662 --- .../auto/declarative/qquickflipable/data/crash.qml | 9 - .../qquickflipable/data/flipable-abort.qml | 10 - .../qquickflipable/data/test-flipable.qml | 9 - .../declarative/qquickflipable/qquickflipable.pro | 13 - .../qquickflipable/tst_qquickflipable.cpp | 150 - .../qquickfocusscope/data/canvasFocus.qml | 22 - .../declarative/qquickfocusscope/data/chain.qml | 28 - .../qquickfocusscope/data/forceActiveFocus.qml | 26 - .../qquickfocusscope/data/forcefocus.qml | 81 - .../qquickfocusscope/data/qtBug13380.qml | 24 - .../qquickfocusscope/data/signalEmission.qml | 33 - .../declarative/qquickfocusscope/data/test.qml | 77 - .../declarative/qquickfocusscope/data/test2.qml | 39 - .../declarative/qquickfocusscope/data/test3.qml | 52 - .../declarative/qquickfocusscope/data/test4.qml | 76 - .../declarative/qquickfocusscope/data/test5.qml | 84 - .../qquickfocusscope/qquickfocusscope.pro | 10 - .../qquickfocusscope/tst_qquickfocusscope.cpp | 668 --- .../qquickgridview/data/ComponentView.qml | 14 - .../qquickgridview/data/asyncloader.qml | 36 - .../qquickgridview/data/attachedSignals.qml | 27 - .../qquickgridview/data/creationContext.qml | 5 - .../qquickgridview/data/displaygrid.qml | 39 - .../declarative/qquickgridview/data/footer.qml | 48 - .../qquickgridview/data/gridview-enforcerange.qml | 58 - .../qquickgridview/data/gridview-initCurrent.qml | 66 - .../qquickgridview/data/gridview-noCurrent.qml | 52 - .../declarative/qquickgridview/data/gridview1.qml | 69 - .../declarative/qquickgridview/data/gridview2.qml | 26 - .../declarative/qquickgridview/data/gridview3.qml | 6 - .../declarative/qquickgridview/data/gridview4.qml | 11 - .../declarative/qquickgridview/data/header.qml | 40 - .../qquickgridview/data/manual-highlight.qml | 48 - .../declarative/qquickgridview/data/margins.qml | 55 - .../declarative/qquickgridview/data/mirroring.qml | 43 - .../qquickgridview/data/propertychangestest.qml | 69 - .../declarative/qquickgridview/data/resizeview.qml | 24 - .../declarative/qquickgridview/data/setindex.qml | 29 - .../declarative/qquickgridview/data/snapToRow.qml | 49 - .../declarative/qquickgridview/data/unaligned.qml | 15 - .../declarative/qquickgridview/qquickgridview.pro | 13 - .../qquickgridview/tst_qquickgridview.cpp | 3705 --------------- .../declarative/qquickimage/data/aspectratio.qml | 6 - tests/auto/declarative/qquickimage/data/big.jpeg | Bin 1700081 -> 0 bytes tests/auto/declarative/qquickimage/data/big256.png | Bin 3566 -> 0 bytes tests/auto/declarative/qquickimage/data/colors.png | Bin 1655 -> 0 bytes .../auto/declarative/qquickimage/data/colors1.png | Bin 1655 -> 0 bytes tests/auto/declarative/qquickimage/data/green.png | Bin 314 -> 0 bytes .../declarative/qquickimage/data/heart-win32.png | Bin 12621 -> 0 bytes tests/auto/declarative/qquickimage/data/heart.png | Bin 12577 -> 0 bytes tests/auto/declarative/qquickimage/data/heart.svg | 55 - .../qquickimage/data/heart200-win32.png | Bin 8062 -> 0 bytes .../auto/declarative/qquickimage/data/heart200.png | Bin 8063 -> 0 bytes .../auto/declarative/qquickimage/data/htiling.qml | 11 - tests/auto/declarative/qquickimage/data/mirror.qml | 11 - .../declarative/qquickimage/data/nullpixmap.qml | 6 - .../auto/declarative/qquickimage/data/pattern.png | Bin 1371 -> 0 bytes .../declarative/qquickimage/data/qtbug_16389.qml | 30 - .../declarative/qquickimage/data/qtbug_22125.qml | 44 - tests/auto/declarative/qquickimage/data/rect.png | Bin 171 -> 0 bytes .../auto/declarative/qquickimage/data/vtiling.qml | 11 - tests/auto/declarative/qquickimage/qquickimage.pro | 13 - .../declarative/qquickimage/tst_qquickimage.cpp | 732 --- tests/auto/declarative/qquickitem/data/order.1.qml | 7 - tests/auto/declarative/qquickitem/data/order.2.qml | 7 - tests/auto/declarative/qquickitem/qquickitem.pro | 12 - .../auto/declarative/qquickitem/tst_qquickitem.cpp | 1190 ----- .../qquickitem2/data/childrenProperty.qml | 14 - .../declarative/qquickitem2/data/childrenRect.qml | 27 - .../qquickitem2/data/childrenRectBug.qml | 23 - .../qquickitem2/data/childrenRectBug2.qml | 53 - .../qquickitem2/data/childrenRectBug3.qml | 15 - .../declarative/qquickitem2/data/implicitsize.qml | 19 - .../qquickitem2/data/keynavigationtest.qml | 87 - .../data/keynavigationtest_implicit.qml | 68 - .../declarative/qquickitem2/data/keyspriority.qml | 9 - .../auto/declarative/qquickitem2/data/keystest.qml | 24 - .../qquickitem2/data/layoutmirroring.qml | 54 - .../qquickitem2/data/mapCoordinates.qml | 84 - .../qquickitem2/data/propertychanges.qml | 10 - .../declarative/qquickitem2/data/qtbug_16871.qml | 5 - .../qquickitem2/data/resourcesProperty.qml | 21 - .../qquickitem2/data/transformCrash.qml | 13 - tests/auto/declarative/qquickitem2/qquickitem2.pro | 13 - .../declarative/qquickitem2/tst_qquickitem.cpp | 1254 ----- .../qquicklistview/data/ComponentView.qml | 16 - .../qquicklistview/data/asyncloader.qml | 36 - .../qquicklistview/data/attachedSignals.qml | 24 - .../qquicklistview/data/creationContext.qml | 5 - .../qquicklistview/data/displaylist.qml | 50 - .../data/fillModelOnComponentCompleted.qml | 36 - .../declarative/qquicklistview/data/footer.qml | 46 - .../declarative/qquicklistview/data/header.qml | 39 - .../qquicklistview/data/headerfooter.qml | 26 - .../declarative/qquicklistview/data/itemlist.qml | 46 - .../data/listview-enforcerange-nohighlight.qml | 61 - .../qquicklistview/data/listview-enforcerange.qml | 55 - .../qquicklistview/data/listview-initCurrent.qml | 64 - .../qquicklistview/data/listview-noCurrent.qml | 50 - .../qquicklistview/data/listview-sections.qml | 64 - .../data/listview-sections_delegate.qml | 71 - .../qquicklistview/data/listviewtest.qml | 133 - .../qquicklistview/data/manual-highlight.qml | 47 - .../declarative/qquicklistview/data/margins.qml | 47 - .../qquicklistview/data/propertychangestest.qml | 71 - .../qquicklistview/data/qtbug-21742.qml | 36 - .../declarative/qquicklistview/data/qtbug14821.qml | 31 - .../declarative/qquicklistview/data/qtbug16037.qml | 37 - .../declarative/qquicklistview/data/resizeview.qml | 22 - .../qquicklistview/data/rightToLeft.qml | 42 - .../qquicklistview/data/sizelessthan1.qml | 26 - .../declarative/qquicklistview/data/snapToItem.qml | 49 - .../qquicklistview/data/strictlyenforcerange.qml | 29 - .../qquicklistview/incrementalmodel.cpp | 89 - .../declarative/qquicklistview/incrementalmodel.h | 68 - .../declarative/qquicklistview/qquicklistview.pro | 13 - .../qquicklistview/tst_qquicklistview.cpp | 4379 ----------------- .../qquickloader/data/ActiveComponent.qml | 11 - .../qquickloader/data/AnchoredLoader.qml | 14 - .../declarative/qquickloader/data/BigComponent.qml | 5015 -------------------- .../declarative/qquickloader/data/BlueRect.qml | 8 - .../qquickloader/data/CreationContextLoader.qml | 15 - .../qquickloader/data/GraphicsWidget250x250.qml | 5 - .../declarative/qquickloader/data/GreenRect.qml | 7 - .../data/InitialPropertyValuesComponent.qml | 11 - .../qquickloader/data/InvalidSourceComponent.qml | 5 - .../declarative/qquickloader/data/NoResize.qml | 8 - .../qquickloader/data/NoResizeGraphicsWidget.qml | 9 - .../declarative/qquickloader/data/QTBUG_16928.qml | 23 - .../declarative/qquickloader/data/QTBUG_17114.qml | 18 - .../declarative/qquickloader/data/Rect120x60.qml | 6 - .../qquickloader/data/SetSourceComponent.qml | 9 - .../data/SizeGraphicsWidgetToLoader.qml | 7 - .../data/SizeLoaderToGraphicsWidget.qml | 5 - .../declarative/qquickloader/data/SizeToItem.qml | 5 - .../declarative/qquickloader/data/SizeToLoader.qml | 6 - .../declarative/qquickloader/data/VmeError.qml | 7 - .../declarative/qquickloader/data/active.1.qml | 31 - .../declarative/qquickloader/data/active.2.qml | 18 - .../declarative/qquickloader/data/active.3.qml | 18 - .../declarative/qquickloader/data/active.4.qml | 26 - .../declarative/qquickloader/data/active.5.qml | 18 - .../declarative/qquickloader/data/active.6.qml | 21 - .../declarative/qquickloader/data/active.7.qml | 14 - .../declarative/qquickloader/data/active.8.qml | 13 - .../declarative/qquickloader/data/asynchronous.qml | 16 - tests/auto/declarative/qquickloader/data/crash.qml | 14 - .../qquickloader/data/creationContext.qml | 8 - .../qquickloader/data/differentorigin.qml | 3 - .../declarative/qquickloader/data/implicitSize.qml | 28 - .../qquickloader/data/initialPropertyValues.1.qml | 22 - .../qquickloader/data/initialPropertyValues.2.qml | 20 - .../qquickloader/data/initialPropertyValues.3.qml | 18 - .../qquickloader/data/initialPropertyValues.4.qml | 22 - .../qquickloader/data/initialPropertyValues.5.qml | 20 - .../qquickloader/data/initialPropertyValues.6.qml | 25 - .../qquickloader/data/initialPropertyValues.7.qml | 29 - .../qquickloader/data/initialPropertyValues.8.qml | 20 - .../data/initialPropertyValues.binding.qml | 21 - .../data/initialPropertyValues.error.1.qml | 14 - .../data/initialPropertyValues.error.2.qml | 14 - .../data/initialPropertyValues.error.3.qml | 14 - .../data/initialPropertyValues.error.4.qml | 15 - .../auto/declarative/qquickloader/data/nonItem.qml | 5 - .../declarative/qquickloader/data/parented.qml | 21 - tests/auto/declarative/qquickloader/data/qmldir | 1 - .../qquickloader/data/sameorigin-load.qml | 3 - .../declarative/qquickloader/data/sameorigin.qml | 3 - .../declarative/qquickloader/data/vmeErrors.qml | 6 - .../auto/declarative/qquickloader/qquickloader.pro | 16 - .../declarative/qquickloader/tst_qquickloader.cpp | 969 ---- .../qquickmousearea/data/clickThrough.qml | 25 - .../qquickmousearea/data/clickThrough2.qml | 35 - .../qquickmousearea/data/clickandhold.qml | 13 - .../qquickmousearea/data/clicktwice.qml | 16 - .../qquickmousearea/data/doubleclick.qml | 16 - .../declarative/qquickmousearea/data/dragging.qml | 28 - .../qquickmousearea/data/dragproperties.qml | 28 - .../declarative/qquickmousearea/data/dragreset.qml | 28 - .../qquickmousearea/data/hoverPosition.qml | 17 - .../qquickmousearea/data/hoverPropagation.qml | 54 - .../qquickmousearea/data/noclickandhold.qml | 11 - .../qquickmousearea/data/pressedCanceled.qml | 18 - .../qquickmousearea/data/pressedOrdering.qml | 28 - .../qquickmousearea/data/preventstealing.qml | 24 - .../qquickmousearea/data/rejectEvent.qml | 28 - .../qquickmousearea/data/updateMousePosOnClick.qml | 20 - .../data/updateMousePosOnResize.qml | 43 - .../qquickmousearea/qquickmousearea.pro | 14 - .../qquickmousearea/tst_qquickmousearea.cpp | 824 ---- .../qquickmultipointtoucharea/data/inFlickable.qml | 25 - .../qquickmultipointtoucharea/data/nested.qml | 27 - .../data/nonOverlapping.qml | 32 - .../qquickmultipointtoucharea/data/properties.qml | 15 - .../qquickmultipointtoucharea/data/signalTest.qml | 25 - .../qquickmultipointtoucharea.pro | 11 - .../tst_qquickmultipointtoucharea.cpp | 586 --- .../qquickpathview/data/ComponentView.qml | 17 - .../qquickpathview/data/asyncloader.qml | 71 - .../declarative/qquickpathview/data/closedPath.qml | 24 - .../qquickpathview/data/creationContext.qml | 5 - .../declarative/qquickpathview/data/datamodel.qml | 38 - .../qquickpathview/data/displaypath.qml | 59 - .../declarative/qquickpathview/data/dragpath.qml | 19 - .../declarative/qquickpathview/data/emptymodel.qml | 5 - .../qquickpathview/data/missingPercent.qml | 9 - .../declarative/qquickpathview/data/openPath.qml | 10 - .../declarative/qquickpathview/data/pathUpdate.qml | 18 - .../data/pathUpdateOnStartChanged.qml | 38 - .../declarative/qquickpathview/data/pathline.qml | 48 - .../declarative/qquickpathview/data/pathtest.qml | 14 - .../declarative/qquickpathview/data/pathview0.qml | 85 - .../declarative/qquickpathview/data/pathview1.qml | 4 - .../declarative/qquickpathview/data/pathview2.qml | 57 - .../declarative/qquickpathview/data/pathview3.qml | 59 - .../qquickpathview/data/pathview_package.qml | 88 - .../qquickpathview/data/propertychanges.qml | 116 - .../declarative/qquickpathview/data/treemodel.qml | 19 - .../qquickpathview/data/undefinedpath.qml | 17 - tests/auto/declarative/qquickpathview/data/vdm.qml | 28 - .../declarative/qquickpathview/qquickpathview.pro | 12 - .../qquickpathview/tst_qquickpathview.cpp | 1629 ------- .../qquickpincharea/data/pinchproperties.qml | 50 - .../qquickpincharea/qquickpincharea.pro | 13 - .../qquickpincharea/tst_qquickpincharea.cpp | 395 -- .../qquickpositioners/data/allInvisible.qml | 44 - .../data/attachedproperties-column.qml | 50 - .../data/attachedproperties-dynamic.qml | 44 - .../data/attachedproperties-flow.qml | 50 - .../data/attachedproperties-grid.qml | 50 - .../data/attachedproperties-row.qml | 50 - .../data/flow-testimplicitsize.qml | 19 - .../data/flowtest-toptobottom.qml | 44 - .../qquickpositioners/data/flowtest.qml | 43 - .../qquickpositioners/data/grid-animated.qml | 64 - .../data/grid-row-column-spacing.qml | 43 - .../qquickpositioners/data/grid-spacing.qml | 41 - .../qquickpositioners/data/grid-toptobottom.qml | 41 - .../qquickpositioners/data/gridtest.qml | 42 - .../qquickpositioners/data/gridzerocolumns.qml | 40 - .../data/horizontal-animated-disabled.qml | 40 - .../qquickpositioners/data/horizontal-animated.qml | 47 - .../qquickpositioners/data/horizontal-spacing.qml | 31 - .../qquickpositioners/data/horizontal.qml | 29 - .../qquickpositioners/data/propertychangestest.qml | 39 - .../qquickpositioners/data/rectangleComponent.qml | 11 - .../qquickpositioners/data/repeatertest.qml | 38 - .../qquickpositioners/data/vertical-animated.qml | 41 - .../qquickpositioners/data/vertical-spacing.qml | 28 - .../qquickpositioners/data/vertical.qml | 27 - .../qquickpositioners/qquickpositioners.pro | 11 - .../qquickpositioners/tst_qquickpositioners.cpp | 1473 ------ .../qquickrepeater/data/asyncloader.qml | 32 - .../declarative/qquickrepeater/data/initparent.qml | 12 - .../declarative/qquickrepeater/data/intmodel.qml | 29 - .../declarative/qquickrepeater/data/itemlist.qml | 68 - .../qquickrepeater/data/modelChanged.qml | 26 - .../declarative/qquickrepeater/data/objlist.qml | 21 - .../declarative/qquickrepeater/data/properties.qml | 11 - .../declarative/qquickrepeater/data/repeater1.qml | 28 - .../declarative/qquickrepeater/data/repeater2.qml | 36 - .../declarative/qquickrepeater/qquickrepeater.pro | 12 - .../qquickrepeater/tst_qquickrepeater.cpp | 765 --- .../qquickshadereffect/qquickshadereffect.pro | 8 - .../qquickshadereffect/tst_qquickshadereffect.cpp | 320 -- .../declarative/qquickspriteimage/data/basic.qml | 60 - .../qquickspriteimage/data/squarefacesprite.png | Bin 496 -> 0 bytes .../qquickspriteimage/qquickspriteimage.pro | 12 - .../qquickspriteimage/tst_qquickspriteimage.cpp | 81 - .../declarative/qquicktext/data/alignments.qml | 41 - .../declarative/qquicktext/data/alignments_cb.png | Bin 496 -> 0 bytes .../declarative/qquicktext/data/alignments_cc.png | Bin 556 -> 0 bytes .../declarative/qquicktext/data/alignments_ct.png | Bin 533 -> 0 bytes .../declarative/qquicktext/data/alignments_lb.png | Bin 496 -> 0 bytes .../declarative/qquicktext/data/alignments_lc.png | Bin 535 -> 0 bytes .../declarative/qquicktext/data/alignments_lt.png | Bin 514 -> 0 bytes .../declarative/qquicktext/data/alignments_rb.png | Bin 505 -> 0 bytes .../declarative/qquicktext/data/alignments_rc.png | Bin 559 -> 0 bytes .../declarative/qquicktext/data/alignments_rt.png | Bin 539 -> 0 bytes .../qquicktext/data/embeddedImagesLocal.qml | 6 - .../qquicktext/data/embeddedImagesLocalError.qml | 6 - .../qquicktext/data/embeddedImagesRemote.qml | 6 - .../qquicktext/data/embeddedImagesRemoteError.qml | 6 - .../data/horizontalAlignment_RightToLeft.qml | 23 - .../declarative/qquicktext/data/http/exists.png | Bin 2738 -> 0 bytes .../auto/declarative/qquicktext/data/lineCount.qml | 15 - .../declarative/qquicktext/data/lineHeight.qml | 15 - .../declarative/qquicktext/data/lineLayout.qml | 35 - .../declarative/qquicktext/data/multilineelide.qml | 10 - .../declarative/qquicktext/data/qtbug_14734.qml | 10 - tests/auto/declarative/qquicktext/data/rotated.qml | 18 - tests/auto/declarative/qquicktext/qquicktext.pro | 17 - .../auto/declarative/qquicktext/tst_qquicktext.cpp | 1460 ------ .../declarative/qquicktextedit/data/CursorRect.qml | 8 - .../declarative/qquicktextedit/data/alignments.qml | 41 - .../qquicktextedit/data/alignments_cb.png | Bin 496 -> 0 bytes .../qquicktextedit/data/alignments_cc.png | Bin 556 -> 0 bytes .../qquicktextedit/data/alignments_ct.png | Bin 533 -> 0 bytes .../qquicktextedit/data/alignments_lb.png | Bin 496 -> 0 bytes .../qquicktextedit/data/alignments_lc.png | Bin 535 -> 0 bytes .../qquicktextedit/data/alignments_lt.png | Bin 514 -> 0 bytes .../qquicktextedit/data/alignments_rb.png | Bin 505 -> 0 bytes .../qquicktextedit/data/alignments_rc.png | Bin 559 -> 0 bytes .../qquicktextedit/data/alignments_rt.png | Bin 539 -> 0 bytes .../declarative/qquicktextedit/data/cursorTest.qml | 9 - .../qquicktextedit/data/cursorVisible.qml | 6 - .../qquicktextedit/data/geometrySignals.qml | 12 - .../data/horizontalAlignment_RightToLeft.qml | 24 - .../qquicktextedit/data/http/ErrItem.qml | 7 - .../qquicktextedit/data/http/NormItem.qml | 6 - .../qquicktextedit/data/http/cursorHttpTest.qml | 22 - .../data/http/cursorHttpTestFail1.qml | 18 - .../data/http/cursorHttpTestFail2.qml | 18 - .../data/http/cursorHttpTestPass.qml | 18 - .../declarative/qquicktextedit/data/http/qmldir | 4 - .../qquicktextedit/data/httpfail/FailItem.qml | 5 - .../qquicktextedit/data/httpslow/WaitItem.qml | 5 - .../qquicktextedit/data/inputContext.qml | 7 - .../qquicktextedit/data/inputMethodEvent.qml | 5 - .../qquicktextedit/data/inputmethodhints.qml | 6 - .../qquicktextedit/data/mouseselection_default.qml | 7 - .../qquicktextedit/data/mouseselection_false.qml | 7 - .../data/mouseselection_false_words.qml | 8 - .../qquicktextedit/data/mouseselection_true.qml | 7 - .../data/mouseselection_true_words.qml | 8 - .../data/mouseselectionmode_characters.qml | 8 - .../data/mouseselectionmode_default.qml | 7 - .../data/mouseselectionmode_words.qml | 8 - .../declarative/qquicktextedit/data/navigation.qml | 24 - .../qquicktextedit/data/openInputPanel.qml | 7 - .../declarative/qquicktextedit/data/positionAt.qml | 9 - .../qquicktextedit/data/qtbug-22058.qml | 39 - .../declarative/qquicktextedit/data/readOnly.qml | 12 - .../declarative/qquicktextedit/qquicktextedit.pro | 12 - .../qquicktextedit/tst_qquicktextedit.cpp | 3555 -------------- .../qquicktextinput/data/cursorTest.qml | 9 - .../qquicktextinput/data/cursorVisible.qml | 6 - .../declarative/qquicktextinput/data/echoMode.qml | 11 - .../qquicktextinput/data/geometrySignals.qml | 12 - .../qquicktextinput/data/halign_center.png | Bin 293 -> 0 bytes .../qquicktextinput/data/halign_left.png | Bin 291 -> 0 bytes .../qquicktextinput/data/halign_right.png | Bin 292 -> 0 bytes .../qquicktextinput/data/horizontalAlignment.qml | 22 - .../data/horizontalAlignment_RightToLeft.qml | 24 - .../qquicktextinput/data/inputContext.qml | 8 - .../qquicktextinput/data/inputMethodEvent.qml | 6 - .../qquicktextinput/data/inputmethods.qml | 7 - .../declarative/qquicktextinput/data/masks.qml | 7 - .../declarative/qquicktextinput/data/maxLength.qml | 7 - .../qquicktextinput/data/mouseselection_true.qml | 7 - .../data/mouseselectionmode_characters.qml | 8 - .../data/mouseselectionmode_default.qml | 7 - .../data/mouseselectionmode_words.qml | 8 - .../qquicktextinput/data/navigation.qml | 24 - .../qquicktextinput/data/openInputPanel.qml | 7 - .../qquicktextinput/data/positionAt.qml | 8 - .../qquicktextinput/data/preeditAutoScroll.qml | 7 - .../qquicktextinput/data/qtbug-19956double.qml | 15 - .../qquicktextinput/data/qtbug-19956int.qml | 15 - .../qquicktextinput/data/qtbug-19956regexp.qml | 13 - .../declarative/qquicktextinput/data/readOnly.qml | 12 - .../qquicktextinput/data/validators.qml | 22 - .../qquicktextinput/qquicktextinput.pro | 11 - .../qquicktextinput/tst_qquicktextinput.cpp | 3310 ------------- tests/auto/declarative/qquickview/data/error1.qml | 5 - .../declarative/qquickview/data/resizemodeitem.qml | 5 - tests/auto/declarative/qquickview/qquickview.pro | 11 - .../auto/declarative/qquickview/tst_qquickview.cpp | 207 - .../qquickvisualdatamodel/data/create.qml | 25 - .../data/datalist-package.qml | 20 - .../qquickvisualdatamodel/data/datalist.qml | 18 - .../qquickvisualdatamodel/data/groups-invalid.qml | 14 - .../qquickvisualdatamodel/data/groups-package.qml | 52 - .../qquickvisualdatamodel/data/groups.qml | 46 - .../data/itemsDestroyed_listView.qml | 13 - .../data/itemsDestroyed_package.qml | 42 - .../data/itemsDestroyed_pathView.qml | 18 - .../data/itemsDestroyed_repeater.qml | 15 - .../qquickvisualdatamodel/data/modelproperties.qml | 21 - .../data/modelproperties2.qml | 21 - .../qquickvisualdatamodel/data/objectlist.qml | 19 - .../qquickvisualdatamodel/data/onChanged.qml | 87 - .../qquickvisualdatamodel/data/singlerole1.qml | 10 - .../qquickvisualdatamodel/data/singlerole2.qml | 10 - .../qquickvisualdatamodel/data/visualdatamodel.qml | 12 - .../qquickvisualdatamodel.pro | 13 - .../tst_qquickvisualdatamodel.cpp | 1865 -------- tests/auto/declarative/shared/testhttpserver.cpp | 324 -- tests/auto/declarative/shared/testhttpserver.h | 93 - tests/auto/declarative/shared/util.h | 85 - tests/auto/declarative/v4/tst_v4.cpp | 2 +- tests/auto/particles/qquickage/qquickage.pro | 2 +- .../qquickangleddirection.pro | 2 +- .../qquickcumulativedirection.pro | 2 +- .../qquickcustomaffector/qquickcustomaffector.pro | 2 +- .../qquickcustomparticle/qquickcustomparticle.pro | 2 +- .../qquickellipseextruder.pro | 2 +- .../particles/qquickfriction/qquickfriction.pro | 2 +- .../auto/particles/qquickgravity/qquickgravity.pro | 2 +- .../qquickimageparticle/qquickimageparticle.pro | 2 +- .../qquickitemparticle/qquickitemparticle.pro | 2 +- .../qquicklineextruder/qquicklineextruder.pro | 2 +- .../qquickmaskextruder/qquickmaskextruder.pro | 2 +- .../qquickparticlegroup/qquickparticlegroup.pro | 2 +- .../qquickparticlesystem/qquickparticlesystem.pro | 2 +- .../qquickpointattractor/qquickpointattractor.pro | 2 +- .../qquickpointdirection/qquickpointdirection.pro | 2 +- .../qquickrectangleextruder.pro | 2 +- .../qquicktargetdirection.pro | 2 +- .../qquicktrailemitter/qquicktrailemitter.pro | 2 +- .../qquickturbulence/qquickturbulence.pro | 2 +- tests/auto/particles/qquickwander/qquickwander.pro | 2 +- tests/auto/particles/shared/particlestestsshared.h | 2 +- .../qdeclarativeanimatedimage.pro | 4 +- .../tst_qdeclarativeanimatedimage.cpp | 2 +- .../qdeclarativeborderimage.pro | 4 +- .../tst_qdeclarativeborderimage.cpp | 2 +- .../qdeclarativefontloader.pro | 4 +- .../tst_qdeclarativefontloader.cpp | 2 +- .../qdeclarativeimage/qdeclarativeimage.pro | 4 +- .../qdeclarativeimage/tst_qdeclarativeimage.cpp | 2 +- .../qdeclarativeloader/qdeclarativeloader.pro | 6 +- .../qdeclarativemousearea.pro | 4 +- .../qtquick1/qdeclarativetext/qdeclarativetext.pro | 6 +- .../qdeclarativetextedit/qdeclarativetextedit.pro | 4 +- .../tst_qdeclarativetextedit.cpp | 2 +- tests/auto/qtquick2/examples/data/dummytest.qml | 6 + .../examples/data/webbrowser/webbrowser.qml | 6 + tests/auto/qtquick2/examples/examples.pro | 10 + tests/auto/qtquick2/examples/tst_examples.cpp | 253 + tests/auto/qtquick2/geometry/geometry.pro | 9 + tests/auto/qtquick2/geometry/tst_geometry.cpp | 181 + tests/auto/qtquick2/nodes/nodes.pro | 9 + tests/auto/qtquick2/nodes/tst_nodestest.cpp | 354 ++ .../qdeclarativeanimations/data/Double.qml | 14 + .../qdeclarativeanimations/data/attached.qml | 34 + .../qdeclarativeanimations/data/badproperty1.qml | 21 + .../qdeclarativeanimations/data/badproperty2.qml | 21 + .../qdeclarativeanimations/data/badtype1.qml | 12 + .../qdeclarativeanimations/data/badtype2.qml | 12 + .../qdeclarativeanimations/data/badtype3.qml | 12 + .../qdeclarativeanimations/data/badtype4.qml | 27 + .../data/disabledTransition.qml | 30 + .../qdeclarativeanimations/data/dontAutoStart.qml | 18 + .../qdeclarativeanimations/data/dontStart.qml | 19 + .../qdeclarativeanimations/data/dontStart2.qml | 19 + .../qdeclarativeanimations/data/dotproperty.qml | 24 + .../data/doubleRegistrationBug.qml | 8 + .../qdeclarativeanimations/data/mixedtype1.qml | 25 + .../qdeclarativeanimations/data/mixedtype2.qml | 25 + .../data/nonTransitionBug.qml | 30 + .../qdeclarativeanimations/data/pathAnimation.qml | 27 + .../qdeclarativeanimations/data/pathAnimation2.qml | 26 + .../data/pathAnimationNoStart.qml | 27 + .../data/pathInterpolator.qml | 13 + .../data/pathInterpolatorBack.qml | 11 + .../qdeclarativeanimations/data/pathTransition.qml | 41 + .../data/pauseBindingBug.qml | 17 + .../qdeclarativeanimations/data/pauseBug.qml | 7 + .../qdeclarativeanimations/data/properties.qml | 14 + .../qdeclarativeanimations/data/properties2.qml | 14 + .../qdeclarativeanimations/data/properties3.qml | 14 + .../qdeclarativeanimations/data/properties4.qml | 14 + .../qdeclarativeanimations/data/properties5.qml | 14 + .../data/propertiesTransition.qml | 29 + .../data/propertiesTransition2.qml | 29 + .../data/propertiesTransition3.qml | 29 + .../data/propertiesTransition4.qml | 29 + .../data/propertiesTransition5.qml | 29 + .../data/propertiesTransition6.qml | 29 + .../data/propertiesTransition7.qml | 29 + .../data/registrationBug.qml | 18 + .../qdeclarativeanimations/data/rotation.qml | 48 + .../qdeclarativeanimations/data/runningTrueBug.qml | 30 + .../data/transitionAssignmentBug.qml | 12 + .../qdeclarativeanimations/data/valuesource.qml | 14 + .../qdeclarativeanimations/data/valuesource2.qml | 14 + .../qdeclarativeanimations.pro | 12 + .../tst_qdeclarativeanimations.cpp | 1106 +++++ .../qdeclarativeapplication.pro | 7 + .../tst_qdeclarativeapplication.cpp | 143 + .../qdeclarativebehaviors/data/binding.qml | 26 + .../qtquick2/qdeclarativebehaviors/data/color.qml | 24 + .../qdeclarativebehaviors/data/cpptrigger.qml | 11 + .../data/delayedRegistration.qml | 25 + .../qdeclarativebehaviors/data/disabled.qml | 27 + .../qdeclarativebehaviors/data/dontStart.qml | 18 + .../qtquick2/qdeclarativebehaviors/data/empty.qml | 23 + .../qdeclarativebehaviors/data/explicit.qml | 26 + .../qdeclarativebehaviors/data/groupProperty.qml | 23 + .../qdeclarativebehaviors/data/groupProperty2.qml | 23 + .../data/groupedPropertyCrash.qml | 10 + .../qtquick2/qdeclarativebehaviors/data/loop.qml | 19 + .../qdeclarativebehaviors/data/nonSelecting2.qml | 26 + .../qtquick2/qdeclarativebehaviors/data/parent.qml | 28 + .../qdeclarativebehaviors/data/qtbug12295.qml | 17 + .../data/reassignedAnimation.qml | 32 + .../qdeclarativebehaviors/data/runningTrue.qml | 20 + .../qdeclarativebehaviors/data/scripttrigger.qml | 16 + .../qtquick2/qdeclarativebehaviors/data/simple.qml | 26 + .../data/startOnCompleted.qml | 15 + .../qdeclarativebehaviors/data/startup.qml | 17 + .../qdeclarativebehaviors/data/startup2.qml | 16 + .../qdeclarativebehaviors/data/valueType.qml | 13 + .../qdeclarativebehaviors.pro | 12 + .../tst_qdeclarativebehaviors.cpp | 474 ++ .../qdeclarativefontloader/data/daniel.ttf | Bin 0 -> 51984 bytes .../qtquick2/qdeclarativefontloader/data/dummy.ttf | 0 .../qdeclarativefontloader/data/qtbug-20268.qml | 27 + .../qdeclarativefontloader/data/tarzeau_ocr_a.ttf | Bin 0 -> 24544 bytes .../qdeclarativefontloader.pro | 14 + .../tst_qdeclarativefontloader.cpp | 254 + tests/auto/qtquick2/qdeclarativepath/data/arc.qml | 11 + .../auto/qtquick2/qdeclarativepath/data/curve.qml | 9 + tests/auto/qtquick2/qdeclarativepath/data/svg.qml | 5 + .../qtquick2/qdeclarativepath/qdeclarativepath.pro | 13 + .../qdeclarativepath/tst_qdeclarativepath.cpp | 164 + .../qdeclarativepixmapcache/data/exists.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/exists1.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/exists2.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists1.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists2.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists3.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists4.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists5.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists6.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists7.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/http/exists8.png | Bin 0 -> 2738 bytes .../qdeclarativepixmapcache/data/massive.png | Bin 0 -> 31834 bytes .../qdeclarativepixmapcache.pro | 20 + .../tst_qdeclarativepixmapcache.cpp | 458 ++ .../data/smoothedanimation1.qml | 3 + .../data/smoothedanimation2.qml | 5 + .../data/smoothedanimation3.qml | 6 + .../data/smoothedanimationBehavior.qml | 24 + .../data/smoothedanimationValueSource.qml | 13 + .../qdeclarativesmoothedanimation.pro | 13 + .../tst_qdeclarativesmoothedanimation.cpp | 211 + .../data/springanimation1.qml | 4 + .../data/springanimation2.qml | 9 + .../data/springanimation3.qml | 8 + .../qdeclarativespringanimation.pro | 13 + .../tst_qdeclarativespringanimation.cpp | 131 + .../qdeclarativestates/data/ExtendedRectangle.qml | 19 + .../data/Implementation/MyType.qml | 32 + .../data/Implementation/images/qt-logo.png | Bin 0 -> 5149 bytes .../qdeclarativestates/data/QTBUG-14830.qml | 29 + .../qdeclarativestates/data/anchorChanges1.qml | 23 + .../qdeclarativestates/data/anchorChanges2.qml | 21 + .../qdeclarativestates/data/anchorChanges3.qml | 29 + .../qdeclarativestates/data/anchorChanges4.qml | 22 + .../qdeclarativestates/data/anchorChanges5.qml | 22 + .../qdeclarativestates/data/anchorChangesCrash.qml | 14 + .../qdeclarativestates/data/anchorRewindBug.qml | 37 + .../qdeclarativestates/data/anchorRewindBug2.qml | 25 + .../data/attachedPropertyChanges.qml | 20 + .../data/autoStateAtStartupRestoreBug.qml | 18 + .../qdeclarativestates/data/avoidFastForward.qml | 17 + .../qdeclarativestates/data/basicBinding.qml | 12 + .../qdeclarativestates/data/basicBinding2.qml | 12 + .../qdeclarativestates/data/basicBinding3.qml | 13 + .../qdeclarativestates/data/basicBinding4.qml | 17 + .../qdeclarativestates/data/basicChanges.qml | 10 + .../qdeclarativestates/data/basicChanges2.qml | 15 + .../qdeclarativestates/data/basicChanges3.qml | 15 + .../qdeclarativestates/data/basicChanges4.qml | 19 + .../qdeclarativestates/data/basicExtension.qml | 16 + .../qtquick2/qdeclarativestates/data/deleting.qml | 11 + .../qdeclarativestates/data/deletingState.qml | 13 + .../qdeclarativestates/data/editProperties.qml | 34 + .../qtquick2/qdeclarativestates/data/explicit.qml | 15 + .../qdeclarativestates/data/extendsBug.qml | 26 + .../qdeclarativestates/data/fakeExtension.qml | 16 + .../qdeclarativestates/data/illegalObj.qml | 12 + .../qdeclarativestates/data/illegalTempState.qml | 21 + .../qtquick2/qdeclarativestates/data/image.png | Bin 0 -> 173 bytes .../qdeclarativestates/data/legalTempState.qml | 23 + .../qdeclarativestates/data/nonExistantProp.qml | 11 + .../qdeclarativestates/data/parentChange1.qml | 37 + .../qdeclarativestates/data/parentChange2.qml | 31 + .../qdeclarativestates/data/parentChange3.qml | 42 + .../qdeclarativestates/data/parentChange4.qml | 30 + .../qdeclarativestates/data/parentChange5.qml | 30 + .../qdeclarativestates/data/parentChange6.qml | 30 + .../qdeclarativestates/data/propertyErrors.qml | 10 + .../qtquick2/qdeclarativestates/data/reset.qml | 19 + .../qdeclarativestates/data/restoreEntryValues.qml | 14 + .../qdeclarativestates/data/returnToBase.qml | 21 + .../qdeclarativestates/data/revertListBug.qml | 47 + .../qtquick2/qdeclarativestates/data/script.qml | 10 + .../qdeclarativestates/data/signalOverride.qml | 18 + .../qdeclarativestates/data/signalOverride2.qml | 9 + .../data/signalOverrideCrash.qml | 15 + .../data/signalOverrideCrash2.qml | 24 + .../data/signalOverrideCrash3.qml | 27 + .../qdeclarativestates/data/unnamedWhen.qml | 14 + .../qdeclarativestates/data/urlResolution.qml | 12 + .../qdeclarativestates/data/whenOrdering.qml | 11 + .../qdeclarativestates/qdeclarativestates.pro | 12 + .../qdeclarativestates/tst_qdeclarativestates.cpp | 1596 +++++++ .../qdeclarativestyledtext.pro | 8 + .../tst_qdeclarativestyledtext.cpp | 101 + .../qdeclarativesystempalette.pro | 8 + .../tst_qdeclarativesystempalette.cpp | 185 + .../qdeclarativetimer/qdeclarativetimer.pro | 8 + .../qdeclarativetimer/tst_qdeclarativetimer.cpp | 334 ++ .../qdeclarativexmllistmodel/data/empty.xml | 0 .../qtquick2/qdeclarativexmllistmodel/data/get.qml | 61 + .../qdeclarativexmllistmodel/data/model.qml | 11 + .../qdeclarativexmllistmodel/data/model.xml | 54 + .../qdeclarativexmllistmodel/data/model2.xml | 14 + .../data/propertychanges.qml | 11 + .../qdeclarativexmllistmodel/data/recipes.qml | 11 + .../qdeclarativexmllistmodel/data/recipes.xml | 90 + .../qdeclarativexmllistmodel/data/roleCrash.qml | 8 + .../qdeclarativexmllistmodel/data/roleErrors.qml | 11 + .../qdeclarativexmllistmodel/data/roleKeys.qml | 13 + .../qdeclarativexmllistmodel/data/testtypes.qml | 8 + .../qdeclarativexmllistmodel/data/unique.qml | 9 + .../qdeclarativexmllistmodel.pro | 12 + .../tst_qdeclarativexmllistmodel.cpp | 961 ++++ tests/auto/qtquick2/qquickanchors/data/anchors.qml | 162 + .../auto/qtquick2/qquickanchors/data/centerin.qml | 12 + .../qquickanchors/data/centerinRotation.qml | 17 + tests/auto/qtquick2/qquickanchors/data/crash1.qml | 11 + tests/auto/qtquick2/qquickanchors/data/fill.qml | 14 + .../auto/qtquick2/qquickanchors/data/hvCenter.qml | 11 + tests/auto/qtquick2/qquickanchors/data/loop1.qml | 8 + tests/auto/qtquick2/qquickanchors/data/loop2.qml | 20 + tests/auto/qtquick2/qquickanchors/data/margins.qml | 13 + .../auto/qtquick2/qquickanchors/qquickanchors.pro | 12 + .../qtquick2/qquickanchors/tst_qquickanchors.cpp | 692 +++ .../qtquick2/qquickanimatedimage/data/colors.gif | Bin 0 -> 505 bytes .../qtquick2/qquickanimatedimage/data/colors.qml | 5 + .../qtquick2/qquickanimatedimage/data/hearts.gif | Bin 0 -> 6524 bytes .../qtquick2/qquickanimatedimage/data/hearts.qml | 6 + .../auto/qtquick2/qquickanimatedimage/data/qmldir | 1 + .../qquickanimatedimage/data/qtbug-16520.qml | 17 + .../qtquick2/qquickanimatedimage/data/stickman.gif | Bin 0 -> 164923 bytes .../qtquick2/qquickanimatedimage/data/stickman.qml | 5 + .../qquickanimatedimage/data/stickmanerror1.qml | 6 + .../qquickanimatedimage/data/stickmanpause.qml | 7 + .../qquickanimatedimage/data/stickmanscaled.qml | 7 + .../qquickanimatedimage/data/stickmanstopped.qml | 6 + .../qquickanimatedimage/qquickanimatedimage.pro | 13 + .../tst_qquickanimatedimage.cpp | 378 ++ .../qquickborderimage/data/colors-mirror.png | Bin 0 -> 5554 bytes .../qquickborderimage/data/colors-round-quotes.sci | 7 + .../qquickborderimage/data/colors-round-remote.sci | 7 + .../qquickborderimage/data/colors-round.sci | 7 + .../qtquick2/qquickborderimage/data/colors.png | Bin 0 -> 1655 bytes .../qtquick2/qquickborderimage/data/heart200.png | Bin 0 -> 7943 bytes .../qtquick2/qquickborderimage/data/invalid.sci | 7 + .../qtquick2/qquickborderimage/data/mirror.qml | 7 + .../qquickborderimage/qquickborderimage.pro | 14 + .../qquickborderimage/tst_qquickborderimage.cpp | 376 ++ tests/auto/qtquick2/qquickcanvas/data/window.qml | 9 + tests/auto/qtquick2/qquickcanvas/qquickcanvas.pro | 8 + .../qtquick2/qquickcanvas/tst_qquickcanvas.cpp | 557 +++ .../qtquick2/qquickcanvasitem/data/anim-gr.gif | Bin 0 -> 241 bytes .../qtquick2/qquickcanvasitem/data/anim-gr.png | Bin 0 -> 460 bytes .../qquickcanvasitem/data/anim-poster-gr.png | Bin 0 -> 422 bytes .../qtquick2/qquickcanvasitem/data/background.png | Bin 0 -> 86 bytes .../auto/qtquick2/qquickcanvasitem/data/broken.png | Bin 0 -> 87 bytes .../qquickcanvasitem/data/ggrr-256x256.png | Bin 0 -> 120 bytes .../qtquick2/qquickcanvasitem/data/green-16x16.png | Bin 0 -> 92 bytes .../qtquick2/qquickcanvasitem/data/green-1x1.png | Bin 0 -> 82 bytes .../qquickcanvasitem/data/green-256x256.png | Bin 0 -> 103 bytes .../qtquick2/qquickcanvasitem/data/green-2x2.png | Bin 0 -> 118 bytes .../auto/qtquick2/qquickcanvasitem/data/green.png | Bin 0 -> 87 bytes .../qquickcanvasitem/data/grgr-256x256.png | Bin 0 -> 130 bytes .../qtquick2/qquickcanvasitem/data/red-16x16.png | Bin 0 -> 130 bytes tests/auto/qtquick2/qquickcanvasitem/data/red.png | Bin 0 -> 87 bytes .../qquickcanvasitem/data/redtransparent.png | Bin 0 -> 109 bytes .../qquickcanvasitem/data/rgrg-256x256.png | Bin 0 -> 131 bytes .../qquickcanvasitem/data/rrgg-256x256.png | Bin 0 -> 120 bytes .../qtquick2/qquickcanvasitem/data/testhelper.js | 18 + .../qtquick2/qquickcanvasitem/data/transparent.png | Bin 0 -> 100 bytes .../qquickcanvasitem/data/transparent50.png | Bin 0 -> 155 bytes .../qtquick2/qquickcanvasitem/data/tst_arc.qml | 487 ++ .../qtquick2/qquickcanvasitem/data/tst_arcto.qml | 410 ++ .../qtquick2/qquickcanvasitem/data/tst_canvas.qml | 274 ++ .../qquickcanvasitem/data/tst_composite.qml | 380 ++ .../qquickcanvasitem/data/tst_drawimage.qml | 662 +++ .../qquickcanvasitem/data/tst_fillStyle.qml | 113 + .../qquickcanvasitem/data/tst_fillrect.qml | 23 + .../qquickcanvasitem/data/tst_gradient.qml | 981 ++++ .../qtquick2/qquickcanvasitem/data/tst_line.qml | 831 ++++ .../qtquick2/qquickcanvasitem/data/tst_path.qml | 1443 ++++++ .../qtquick2/qquickcanvasitem/data/tst_pattern.qml | 34 + .../qtquick2/qquickcanvasitem/data/tst_pixel.qml | 30 + .../qtquick2/qquickcanvasitem/data/tst_shadow.qml | 59 + .../qtquick2/qquickcanvasitem/data/tst_state.qml | 390 ++ .../qquickcanvasitem/data/tst_strokeStyle.qml | 48 + .../qtquick2/qquickcanvasitem/data/tst_text.qml | 34 + .../qquickcanvasitem/data/tst_transform.qml | 487 ++ .../auto/qtquick2/qquickcanvasitem/data/yellow.png | Bin 0 -> 95 bytes .../qtquick2/qquickcanvasitem/data/yellow75.png | Bin 0 -> 150 bytes .../qtquick2/qquickcanvasitem/qquickcanvasitem.pro | 33 + .../qquickcanvasitem/tst_qquickcanvasitem.cpp | 42 + tests/auto/qtquick2/qquickdrag/qquickdrag.pro | 9 + tests/auto/qtquick2/qquickdrag/tst_qquickdrag.cpp | 827 ++++ .../qtquick2/qquickdroparea/qquickdroparea.pro | 9 + .../qtquick2/qquickdroparea/tst_qquickdroparea.cpp | 1117 +++++ .../qtquick2/qquickflickable/data/disabled.qml | 30 + .../qtquick2/qquickflickable/data/flickable01.qml | 4 + .../qtquick2/qquickflickable/data/flickable02.qml | 14 + .../qtquick2/qquickflickable/data/flickable03.qml | 14 + .../qtquick2/qquickflickable/data/flickable04.qml | 22 + .../data/flickableqgraphicswidget.qml | 7 + .../auto/qtquick2/qquickflickable/data/margins.qml | 19 + .../qquickflickable/data/nestedPressDelay.qml | 33 + .../auto/qtquick2/qquickflickable/data/resize.qml | 27 + tests/auto/qtquick2/qquickflickable/data/wheel.qml | 25 + .../qtquick2/qquickflickable/qquickflickable.pro | 12 + .../qquickflickable/tst_qquickflickable.cpp | 662 +++ tests/auto/qtquick2/qquickflipable/data/crash.qml | 9 + .../qquickflipable/data/flipable-abort.qml | 10 + .../qtquick2/qquickflipable/data/test-flipable.qml | 9 + .../qtquick2/qquickflipable/qquickflipable.pro | 13 + .../qtquick2/qquickflipable/tst_qquickflipable.cpp | 150 + .../qtquick2/qquickfocusscope/data/canvasFocus.qml | 22 + .../auto/qtquick2/qquickfocusscope/data/chain.qml | 28 + .../qquickfocusscope/data/forceActiveFocus.qml | 26 + .../qtquick2/qquickfocusscope/data/forcefocus.qml | 81 + .../qtquick2/qquickfocusscope/data/qtBug13380.qml | 24 + .../qquickfocusscope/data/signalEmission.qml | 33 + tests/auto/qtquick2/qquickfocusscope/data/test.qml | 77 + .../auto/qtquick2/qquickfocusscope/data/test2.qml | 39 + .../auto/qtquick2/qquickfocusscope/data/test3.qml | 52 + .../auto/qtquick2/qquickfocusscope/data/test4.qml | 76 + .../auto/qtquick2/qquickfocusscope/data/test5.qml | 84 + .../qtquick2/qquickfocusscope/qquickfocusscope.pro | 10 + .../qquickfocusscope/tst_qquickfocusscope.cpp | 668 +++ .../qtquick2/qquickgridview/data/ComponentView.qml | 14 + .../qtquick2/qquickgridview/data/asyncloader.qml | 36 + .../qquickgridview/data/attachedSignals.qml | 27 + .../qquickgridview/data/creationContext.qml | 5 + .../qtquick2/qquickgridview/data/displaygrid.qml | 39 + tests/auto/qtquick2/qquickgridview/data/footer.qml | 48 + .../qquickgridview/data/gridview-enforcerange.qml | 58 + .../qquickgridview/data/gridview-initCurrent.qml | 66 + .../qquickgridview/data/gridview-noCurrent.qml | 52 + .../qtquick2/qquickgridview/data/gridview1.qml | 69 + .../qtquick2/qquickgridview/data/gridview2.qml | 26 + .../qtquick2/qquickgridview/data/gridview3.qml | 6 + .../qtquick2/qquickgridview/data/gridview4.qml | 11 + tests/auto/qtquick2/qquickgridview/data/header.qml | 40 + .../qquickgridview/data/manual-highlight.qml | 48 + .../auto/qtquick2/qquickgridview/data/margins.qml | 55 + .../qtquick2/qquickgridview/data/mirroring.qml | 43 + .../qquickgridview/data/propertychangestest.qml | 69 + .../qtquick2/qquickgridview/data/resizeview.qml | 24 + .../auto/qtquick2/qquickgridview/data/setindex.qml | 29 + .../qtquick2/qquickgridview/data/snapToRow.qml | 49 + .../qtquick2/qquickgridview/data/unaligned.qml | 15 + .../qtquick2/qquickgridview/qquickgridview.pro | 13 + .../qtquick2/qquickgridview/tst_qquickgridview.cpp | 3705 +++++++++++++++ .../auto/qtquick2/qquickimage/data/aspectratio.qml | 6 + tests/auto/qtquick2/qquickimage/data/big.jpeg | Bin 0 -> 1700081 bytes tests/auto/qtquick2/qquickimage/data/big256.png | Bin 0 -> 3566 bytes tests/auto/qtquick2/qquickimage/data/colors.png | Bin 0 -> 1655 bytes tests/auto/qtquick2/qquickimage/data/colors1.png | Bin 0 -> 1655 bytes tests/auto/qtquick2/qquickimage/data/green.png | Bin 0 -> 314 bytes .../auto/qtquick2/qquickimage/data/heart-win32.png | Bin 0 -> 12621 bytes tests/auto/qtquick2/qquickimage/data/heart.png | Bin 0 -> 12577 bytes tests/auto/qtquick2/qquickimage/data/heart.svg | 55 + .../qtquick2/qquickimage/data/heart200-win32.png | Bin 0 -> 8062 bytes tests/auto/qtquick2/qquickimage/data/heart200.png | Bin 0 -> 8063 bytes tests/auto/qtquick2/qquickimage/data/htiling.qml | 11 + tests/auto/qtquick2/qquickimage/data/mirror.qml | 11 + .../auto/qtquick2/qquickimage/data/nullpixmap.qml | 6 + tests/auto/qtquick2/qquickimage/data/pattern.png | Bin 0 -> 1371 bytes .../auto/qtquick2/qquickimage/data/qtbug_16389.qml | 30 + .../auto/qtquick2/qquickimage/data/qtbug_22125.qml | 44 + tests/auto/qtquick2/qquickimage/data/rect.png | Bin 0 -> 171 bytes tests/auto/qtquick2/qquickimage/data/vtiling.qml | 11 + tests/auto/qtquick2/qquickimage/qquickimage.pro | 13 + .../auto/qtquick2/qquickimage/tst_qquickimage.cpp | 732 +++ tests/auto/qtquick2/qquickitem/data/order.1.qml | 7 + tests/auto/qtquick2/qquickitem/data/order.2.qml | 7 + tests/auto/qtquick2/qquickitem/qquickitem.pro | 12 + tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp | 1190 +++++ .../qtquick2/qquickitem2/data/childrenProperty.qml | 14 + .../qtquick2/qquickitem2/data/childrenRect.qml | 27 + .../qtquick2/qquickitem2/data/childrenRectBug.qml | 23 + .../qtquick2/qquickitem2/data/childrenRectBug2.qml | 53 + .../qtquick2/qquickitem2/data/childrenRectBug3.qml | 15 + .../qtquick2/qquickitem2/data/implicitsize.qml | 19 + .../qquickitem2/data/keynavigationtest.qml | 87 + .../data/keynavigationtest_implicit.qml | 68 + .../qtquick2/qquickitem2/data/keyspriority.qml | 9 + tests/auto/qtquick2/qquickitem2/data/keystest.qml | 24 + .../qtquick2/qquickitem2/data/layoutmirroring.qml | 54 + .../qtquick2/qquickitem2/data/mapCoordinates.qml | 84 + .../qtquick2/qquickitem2/data/propertychanges.qml | 10 + .../auto/qtquick2/qquickitem2/data/qtbug_16871.qml | 5 + .../qquickitem2/data/resourcesProperty.qml | 21 + .../qtquick2/qquickitem2/data/transformCrash.qml | 13 + tests/auto/qtquick2/qquickitem2/qquickitem2.pro | 13 + tests/auto/qtquick2/qquickitem2/tst_qquickitem.cpp | 1254 +++++ .../qtquick2/qquicklistview/data/ComponentView.qml | 16 + .../qtquick2/qquicklistview/data/asyncloader.qml | 36 + .../qquicklistview/data/attachedSignals.qml | 24 + .../qquicklistview/data/creationContext.qml | 5 + .../qtquick2/qquicklistview/data/displaylist.qml | 50 + .../data/fillModelOnComponentCompleted.qml | 36 + tests/auto/qtquick2/qquicklistview/data/footer.qml | 46 + tests/auto/qtquick2/qquicklistview/data/header.qml | 39 + .../qtquick2/qquicklistview/data/headerfooter.qml | 26 + .../auto/qtquick2/qquicklistview/data/itemlist.qml | 46 + .../data/listview-enforcerange-nohighlight.qml | 61 + .../qquicklistview/data/listview-enforcerange.qml | 55 + .../qquicklistview/data/listview-initCurrent.qml | 64 + .../qquicklistview/data/listview-noCurrent.qml | 50 + .../qquicklistview/data/listview-sections.qml | 64 + .../data/listview-sections_delegate.qml | 71 + .../qtquick2/qquicklistview/data/listviewtest.qml | 133 + .../qquicklistview/data/manual-highlight.qml | 47 + .../auto/qtquick2/qquicklistview/data/margins.qml | 47 + .../qquicklistview/data/propertychangestest.qml | 71 + .../qtquick2/qquicklistview/data/qtbug-21742.qml | 36 + .../qtquick2/qquicklistview/data/qtbug14821.qml | 31 + .../qtquick2/qquicklistview/data/qtbug16037.qml | 37 + .../qtquick2/qquicklistview/data/resizeview.qml | 22 + .../qtquick2/qquicklistview/data/rightToLeft.qml | 42 + .../qtquick2/qquicklistview/data/sizelessthan1.qml | 26 + .../qtquick2/qquicklistview/data/snapToItem.qml | 49 + .../qquicklistview/data/strictlyenforcerange.qml | 29 + .../qtquick2/qquicklistview/incrementalmodel.cpp | 89 + .../qtquick2/qquicklistview/incrementalmodel.h | 68 + .../qtquick2/qquicklistview/qquicklistview.pro | 13 + .../qtquick2/qquicklistview/tst_qquicklistview.cpp | 4379 +++++++++++++++++ .../qtquick2/qquickloader/data/ActiveComponent.qml | 11 + .../qtquick2/qquickloader/data/AnchoredLoader.qml | 14 + .../qtquick2/qquickloader/data/BigComponent.qml | 5015 ++++++++++++++++++++ tests/auto/qtquick2/qquickloader/data/BlueRect.qml | 8 + .../qquickloader/data/CreationContextLoader.qml | 15 + .../qquickloader/data/GraphicsWidget250x250.qml | 5 + .../auto/qtquick2/qquickloader/data/GreenRect.qml | 7 + .../data/InitialPropertyValuesComponent.qml | 11 + .../qquickloader/data/InvalidSourceComponent.qml | 5 + tests/auto/qtquick2/qquickloader/data/NoResize.qml | 8 + .../qquickloader/data/NoResizeGraphicsWidget.qml | 9 + .../qtquick2/qquickloader/data/QTBUG_16928.qml | 23 + .../qtquick2/qquickloader/data/QTBUG_17114.qml | 18 + .../auto/qtquick2/qquickloader/data/Rect120x60.qml | 6 + .../qquickloader/data/SetSourceComponent.qml | 9 + .../data/SizeGraphicsWidgetToLoader.qml | 7 + .../data/SizeLoaderToGraphicsWidget.qml | 5 + .../auto/qtquick2/qquickloader/data/SizeToItem.qml | 5 + .../qtquick2/qquickloader/data/SizeToLoader.qml | 6 + tests/auto/qtquick2/qquickloader/data/VmeError.qml | 7 + tests/auto/qtquick2/qquickloader/data/active.1.qml | 31 + tests/auto/qtquick2/qquickloader/data/active.2.qml | 18 + tests/auto/qtquick2/qquickloader/data/active.3.qml | 18 + tests/auto/qtquick2/qquickloader/data/active.4.qml | 26 + tests/auto/qtquick2/qquickloader/data/active.5.qml | 18 + tests/auto/qtquick2/qquickloader/data/active.6.qml | 21 + tests/auto/qtquick2/qquickloader/data/active.7.qml | 14 + tests/auto/qtquick2/qquickloader/data/active.8.qml | 13 + .../qtquick2/qquickloader/data/asynchronous.qml | 16 + tests/auto/qtquick2/qquickloader/data/crash.qml | 14 + .../qtquick2/qquickloader/data/creationContext.qml | 8 + .../qtquick2/qquickloader/data/differentorigin.qml | 3 + .../qtquick2/qquickloader/data/implicitSize.qml | 28 + .../qquickloader/data/initialPropertyValues.1.qml | 22 + .../qquickloader/data/initialPropertyValues.2.qml | 20 + .../qquickloader/data/initialPropertyValues.3.qml | 18 + .../qquickloader/data/initialPropertyValues.4.qml | 22 + .../qquickloader/data/initialPropertyValues.5.qml | 20 + .../qquickloader/data/initialPropertyValues.6.qml | 25 + .../qquickloader/data/initialPropertyValues.7.qml | 29 + .../qquickloader/data/initialPropertyValues.8.qml | 20 + .../data/initialPropertyValues.binding.qml | 21 + .../data/initialPropertyValues.error.1.qml | 14 + .../data/initialPropertyValues.error.2.qml | 14 + .../data/initialPropertyValues.error.3.qml | 14 + .../data/initialPropertyValues.error.4.qml | 15 + tests/auto/qtquick2/qquickloader/data/nonItem.qml | 5 + tests/auto/qtquick2/qquickloader/data/parented.qml | 21 + tests/auto/qtquick2/qquickloader/data/qmldir | 1 + .../qtquick2/qquickloader/data/sameorigin-load.qml | 3 + .../auto/qtquick2/qquickloader/data/sameorigin.qml | 3 + .../auto/qtquick2/qquickloader/data/vmeErrors.qml | 6 + tests/auto/qtquick2/qquickloader/qquickloader.pro | 16 + .../qtquick2/qquickloader/tst_qquickloader.cpp | 969 ++++ .../qtquick2/qquickmousearea/data/clickThrough.qml | 25 + .../qquickmousearea/data/clickThrough2.qml | 35 + .../qtquick2/qquickmousearea/data/clickandhold.qml | 13 + .../qtquick2/qquickmousearea/data/clicktwice.qml | 16 + .../qtquick2/qquickmousearea/data/doubleclick.qml | 16 + .../qtquick2/qquickmousearea/data/dragging.qml | 28 + .../qquickmousearea/data/dragproperties.qml | 28 + .../qtquick2/qquickmousearea/data/dragreset.qml | 28 + .../qquickmousearea/data/hoverPosition.qml | 17 + .../qquickmousearea/data/hoverPropagation.qml | 54 + .../qquickmousearea/data/noclickandhold.qml | 11 + .../qquickmousearea/data/pressedCanceled.qml | 18 + .../qquickmousearea/data/pressedOrdering.qml | 28 + .../qquickmousearea/data/preventstealing.qml | 24 + .../qtquick2/qquickmousearea/data/rejectEvent.qml | 28 + .../qquickmousearea/data/updateMousePosOnClick.qml | 20 + .../data/updateMousePosOnResize.qml | 43 + .../qtquick2/qquickmousearea/qquickmousearea.pro | 14 + .../qquickmousearea/tst_qquickmousearea.cpp | 824 ++++ .../qquickmultipointtoucharea/data/inFlickable.qml | 25 + .../qquickmultipointtoucharea/data/nested.qml | 27 + .../data/nonOverlapping.qml | 32 + .../qquickmultipointtoucharea/data/properties.qml | 15 + .../qquickmultipointtoucharea/data/signalTest.qml | 25 + .../qquickmultipointtoucharea.pro | 11 + .../tst_qquickmultipointtoucharea.cpp | 586 +++ .../qtquick2/qquickpathview/data/ComponentView.qml | 17 + .../qtquick2/qquickpathview/data/asyncloader.qml | 71 + .../qtquick2/qquickpathview/data/closedPath.qml | 24 + .../qquickpathview/data/creationContext.qml | 5 + .../qtquick2/qquickpathview/data/datamodel.qml | 38 + .../qtquick2/qquickpathview/data/displaypath.qml | 59 + .../auto/qtquick2/qquickpathview/data/dragpath.qml | 19 + .../qtquick2/qquickpathview/data/emptymodel.qml | 5 + .../qquickpathview/data/missingPercent.qml | 9 + .../auto/qtquick2/qquickpathview/data/openPath.qml | 10 + .../qtquick2/qquickpathview/data/pathUpdate.qml | 18 + .../data/pathUpdateOnStartChanged.qml | 38 + .../auto/qtquick2/qquickpathview/data/pathline.qml | 48 + .../auto/qtquick2/qquickpathview/data/pathtest.qml | 14 + .../qtquick2/qquickpathview/data/pathview0.qml | 85 + .../qtquick2/qquickpathview/data/pathview1.qml | 4 + .../qtquick2/qquickpathview/data/pathview2.qml | 57 + .../qtquick2/qquickpathview/data/pathview3.qml | 59 + .../qquickpathview/data/pathview_package.qml | 88 + .../qquickpathview/data/propertychanges.qml | 116 + .../qtquick2/qquickpathview/data/treemodel.qml | 19 + .../qtquick2/qquickpathview/data/undefinedpath.qml | 17 + tests/auto/qtquick2/qquickpathview/data/vdm.qml | 28 + .../qtquick2/qquickpathview/qquickpathview.pro | 12 + .../qtquick2/qquickpathview/tst_qquickpathview.cpp | 1629 +++++++ .../qquickpincharea/data/pinchproperties.qml | 50 + .../qtquick2/qquickpincharea/qquickpincharea.pro | 13 + .../qquickpincharea/tst_qquickpincharea.cpp | 395 ++ .../qquickpositioners/data/allInvisible.qml | 44 + .../data/attachedproperties-column.qml | 50 + .../data/attachedproperties-dynamic.qml | 44 + .../data/attachedproperties-flow.qml | 50 + .../data/attachedproperties-grid.qml | 50 + .../data/attachedproperties-row.qml | 50 + .../data/flow-testimplicitsize.qml | 19 + .../data/flowtest-toptobottom.qml | 44 + .../qtquick2/qquickpositioners/data/flowtest.qml | 43 + .../qquickpositioners/data/grid-animated.qml | 64 + .../data/grid-row-column-spacing.qml | 43 + .../qquickpositioners/data/grid-spacing.qml | 41 + .../qquickpositioners/data/grid-toptobottom.qml | 41 + .../qtquick2/qquickpositioners/data/gridtest.qml | 42 + .../qquickpositioners/data/gridzerocolumns.qml | 40 + .../data/horizontal-animated-disabled.qml | 40 + .../qquickpositioners/data/horizontal-animated.qml | 47 + .../qquickpositioners/data/horizontal-spacing.qml | 31 + .../qtquick2/qquickpositioners/data/horizontal.qml | 29 + .../qquickpositioners/data/propertychangestest.qml | 39 + .../qquickpositioners/data/rectangleComponent.qml | 11 + .../qquickpositioners/data/repeatertest.qml | 38 + .../qquickpositioners/data/vertical-animated.qml | 41 + .../qquickpositioners/data/vertical-spacing.qml | 28 + .../qtquick2/qquickpositioners/data/vertical.qml | 27 + .../qquickpositioners/qquickpositioners.pro | 11 + .../qquickpositioners/tst_qquickpositioners.cpp | 1473 ++++++ .../qtquick2/qquickrepeater/data/asyncloader.qml | 32 + .../qtquick2/qquickrepeater/data/initparent.qml | 12 + .../auto/qtquick2/qquickrepeater/data/intmodel.qml | 29 + .../auto/qtquick2/qquickrepeater/data/itemlist.qml | 68 + .../qtquick2/qquickrepeater/data/modelChanged.qml | 26 + .../auto/qtquick2/qquickrepeater/data/objlist.qml | 21 + .../qtquick2/qquickrepeater/data/properties.qml | 11 + .../qtquick2/qquickrepeater/data/repeater1.qml | 28 + .../qtquick2/qquickrepeater/data/repeater2.qml | 36 + .../qtquick2/qquickrepeater/qquickrepeater.pro | 12 + .../qtquick2/qquickrepeater/tst_qquickrepeater.cpp | 764 +++ .../qquickshadereffect/qquickshadereffect.pro | 8 + .../qquickshadereffect/tst_qquickshadereffect.cpp | 320 ++ .../auto/qtquick2/qquickspriteimage/data/basic.qml | 60 + .../qquickspriteimage/data/squarefacesprite.png | Bin 0 -> 496 bytes .../qquickspriteimage/qquickspriteimage.pro | 12 + .../qquickspriteimage/tst_qquickspriteimage.cpp | 81 + tests/auto/qtquick2/qquicktext/data/alignments.qml | 41 + .../qtquick2/qquicktext/data/alignments_cb.png | Bin 0 -> 496 bytes .../qtquick2/qquicktext/data/alignments_cc.png | Bin 0 -> 556 bytes .../qtquick2/qquicktext/data/alignments_ct.png | Bin 0 -> 533 bytes .../qtquick2/qquicktext/data/alignments_lb.png | Bin 0 -> 496 bytes .../qtquick2/qquicktext/data/alignments_lc.png | Bin 0 -> 535 bytes .../qtquick2/qquicktext/data/alignments_lt.png | Bin 0 -> 514 bytes .../qtquick2/qquicktext/data/alignments_rb.png | Bin 0 -> 505 bytes .../qtquick2/qquicktext/data/alignments_rc.png | Bin 0 -> 559 bytes .../qtquick2/qquicktext/data/alignments_rt.png | Bin 0 -> 539 bytes .../qquicktext/data/embeddedImagesLocal.qml | 6 + .../qquicktext/data/embeddedImagesLocalError.qml | 6 + .../qquicktext/data/embeddedImagesRemote.qml | 6 + .../qquicktext/data/embeddedImagesRemoteError.qml | 6 + .../data/horizontalAlignment_RightToLeft.qml | 23 + .../auto/qtquick2/qquicktext/data/http/exists.png | Bin 0 -> 2738 bytes tests/auto/qtquick2/qquicktext/data/lineCount.qml | 15 + tests/auto/qtquick2/qquicktext/data/lineHeight.qml | 15 + tests/auto/qtquick2/qquicktext/data/lineLayout.qml | 35 + .../qtquick2/qquicktext/data/multilineelide.qml | 10 + .../auto/qtquick2/qquicktext/data/qtbug_14734.qml | 10 + tests/auto/qtquick2/qquicktext/data/rotated.qml | 18 + tests/auto/qtquick2/qquicktext/qquicktext.pro | 17 + tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp | 1460 ++++++ .../qtquick2/qquicktextedit/data/CursorRect.qml | 8 + .../qtquick2/qquicktextedit/data/alignments.qml | 41 + .../qtquick2/qquicktextedit/data/alignments_cb.png | Bin 0 -> 496 bytes .../qtquick2/qquicktextedit/data/alignments_cc.png | Bin 0 -> 556 bytes .../qtquick2/qquicktextedit/data/alignments_ct.png | Bin 0 -> 533 bytes .../qtquick2/qquicktextedit/data/alignments_lb.png | Bin 0 -> 496 bytes .../qtquick2/qquicktextedit/data/alignments_lc.png | Bin 0 -> 535 bytes .../qtquick2/qquicktextedit/data/alignments_lt.png | Bin 0 -> 514 bytes .../qtquick2/qquicktextedit/data/alignments_rb.png | Bin 0 -> 505 bytes .../qtquick2/qquicktextedit/data/alignments_rc.png | Bin 0 -> 559 bytes .../qtquick2/qquicktextedit/data/alignments_rt.png | Bin 0 -> 539 bytes .../qtquick2/qquicktextedit/data/cursorTest.qml | 9 + .../qtquick2/qquicktextedit/data/cursorVisible.qml | 6 + .../qquicktextedit/data/geometrySignals.qml | 12 + .../data/horizontalAlignment_RightToLeft.qml | 24 + .../qtquick2/qquicktextedit/data/http/ErrItem.qml | 7 + .../qtquick2/qquicktextedit/data/http/NormItem.qml | 6 + .../qquicktextedit/data/http/cursorHttpTest.qml | 22 + .../data/http/cursorHttpTestFail1.qml | 18 + .../data/http/cursorHttpTestFail2.qml | 18 + .../data/http/cursorHttpTestPass.qml | 18 + .../auto/qtquick2/qquicktextedit/data/http/qmldir | 4 + .../qquicktextedit/data/httpfail/FailItem.qml | 5 + .../qquicktextedit/data/httpslow/WaitItem.qml | 5 + .../qtquick2/qquicktextedit/data/inputContext.qml | 7 + .../qquicktextedit/data/inputMethodEvent.qml | 5 + .../qquicktextedit/data/inputmethodhints.qml | 6 + .../qquicktextedit/data/mouseselection_default.qml | 7 + .../qquicktextedit/data/mouseselection_false.qml | 7 + .../data/mouseselection_false_words.qml | 8 + .../qquicktextedit/data/mouseselection_true.qml | 7 + .../data/mouseselection_true_words.qml | 8 + .../data/mouseselectionmode_characters.qml | 8 + .../data/mouseselectionmode_default.qml | 7 + .../data/mouseselectionmode_words.qml | 8 + .../qtquick2/qquicktextedit/data/navigation.qml | 24 + .../qquicktextedit/data/openInputPanel.qml | 7 + .../qtquick2/qquicktextedit/data/positionAt.qml | 9 + .../qtquick2/qquicktextedit/data/qtbug-22058.qml | 39 + .../auto/qtquick2/qquicktextedit/data/readOnly.qml | 12 + .../qtquick2/qquicktextedit/qquicktextedit.pro | 12 + .../qtquick2/qquicktextedit/tst_qquicktextedit.cpp | 3555 ++++++++++++++ .../qtquick2/qquicktextinput/data/cursorTest.qml | 9 + .../qquicktextinput/data/cursorVisible.qml | 6 + .../qtquick2/qquicktextinput/data/echoMode.qml | 11 + .../qquicktextinput/data/geometrySignals.qml | 12 + .../qquicktextinput/data/halign_center.png | Bin 0 -> 293 bytes .../qtquick2/qquicktextinput/data/halign_left.png | Bin 0 -> 291 bytes .../qtquick2/qquicktextinput/data/halign_right.png | Bin 0 -> 292 bytes .../qquicktextinput/data/horizontalAlignment.qml | 22 + .../data/horizontalAlignment_RightToLeft.qml | 24 + .../qtquick2/qquicktextinput/data/inputContext.qml | 8 + .../qquicktextinput/data/inputMethodEvent.qml | 6 + .../qtquick2/qquicktextinput/data/inputmethods.qml | 7 + tests/auto/qtquick2/qquicktextinput/data/masks.qml | 7 + .../qtquick2/qquicktextinput/data/maxLength.qml | 7 + .../qquicktextinput/data/mouseselection_true.qml | 7 + .../data/mouseselectionmode_characters.qml | 8 + .../data/mouseselectionmode_default.qml | 7 + .../data/mouseselectionmode_words.qml | 8 + .../qtquick2/qquicktextinput/data/navigation.qml | 24 + .../qquicktextinput/data/openInputPanel.qml | 7 + .../qtquick2/qquicktextinput/data/positionAt.qml | 8 + .../qquicktextinput/data/preeditAutoScroll.qml | 7 + .../qquicktextinput/data/qtbug-19956double.qml | 15 + .../qquicktextinput/data/qtbug-19956int.qml | 15 + .../qquicktextinput/data/qtbug-19956regexp.qml | 13 + .../qtquick2/qquicktextinput/data/readOnly.qml | 12 + .../qtquick2/qquicktextinput/data/validators.qml | 22 + .../qtquick2/qquicktextinput/qquicktextinput.pro | 11 + .../qquicktextinput/tst_qquicktextinput.cpp | 3310 +++++++++++++ tests/auto/qtquick2/qquickview/data/error1.qml | 5 + .../qtquick2/qquickview/data/resizemodeitem.qml | 5 + tests/auto/qtquick2/qquickview/qquickview.pro | 11 + tests/auto/qtquick2/qquickview/tst_qquickview.cpp | 207 + .../qtquick2/qquickvisualdatamodel/data/create.qml | 25 + .../data/datalist-package.qml | 20 + .../qquickvisualdatamodel/data/datalist.qml | 18 + .../qquickvisualdatamodel/data/groups-invalid.qml | 14 + .../qquickvisualdatamodel/data/groups-package.qml | 52 + .../qtquick2/qquickvisualdatamodel/data/groups.qml | 46 + .../data/itemsDestroyed_listView.qml | 13 + .../data/itemsDestroyed_package.qml | 42 + .../data/itemsDestroyed_pathView.qml | 18 + .../data/itemsDestroyed_repeater.qml | 15 + .../qquickvisualdatamodel/data/modelproperties.qml | 21 + .../data/modelproperties2.qml | 21 + .../qquickvisualdatamodel/data/objectlist.qml | 19 + .../qquickvisualdatamodel/data/onChanged.qml | 87 + .../qquickvisualdatamodel/data/singlerole1.qml | 10 + .../qquickvisualdatamodel/data/singlerole2.qml | 10 + .../qquickvisualdatamodel/data/visualdatamodel.qml | 12 + .../qquickvisualdatamodel.pro | 13 + .../tst_qquickvisualdatamodel.cpp | 1865 ++++++++ tests/auto/qtquick2/qtquick2.pro | 63 + tests/auto/shared/testhttpserver.cpp | 324 ++ tests/auto/shared/testhttpserver.h | 93 + tests/auto/shared/util.h | 85 + tests/benchmarks/particles/affectors/affectors.pro | 2 +- tests/benchmarks/particles/emission/emission.pro | 2 +- 1448 files changed, 65808 insertions(+), 65799 deletions(-) delete mode 100644 tests/auto/declarative/examples/data/dummytest.qml delete mode 100644 tests/auto/declarative/examples/data/webbrowser/webbrowser.qml delete mode 100644 tests/auto/declarative/examples/examples.pro delete mode 100644 tests/auto/declarative/examples/tst_examples.cpp delete mode 100644 tests/auto/declarative/geometry/geometry.pro delete mode 100644 tests/auto/declarative/geometry/tst_geometry.cpp delete mode 100644 tests/auto/declarative/nodes/nodes.pro delete mode 100644 tests/auto/declarative/nodes/tst_nodestest.cpp delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/Double.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/attached.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badproperty1.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badproperty2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badtype1.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badtype2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badtype3.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/badtype4.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/disabledTransition.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/dontStart.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/dontStart2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/dotproperty.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/mixedtype1.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/mixedtype2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/nonTransitionBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathAnimation.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathAnimation2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathAnimationNoStart.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathInterpolator.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pathTransition.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pauseBindingBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/pauseBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/properties.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/properties2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/properties3.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/properties4.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/properties5.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition3.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition4.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition5.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition6.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition7.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/rotation.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/runningTrueBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/valuesource.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/data/valuesource2.qml delete mode 100644 tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro delete mode 100644 tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp delete mode 100644 tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro delete mode 100644 tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/binding.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/color.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/cpptrigger.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/disabled.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/empty.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/explicit.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/groupProperty.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/groupProperty2.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/loop.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/nonSelecting2.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/parent.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/runningTrue.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/scripttrigger.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/simple.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/startup.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/startup2.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro delete mode 100644 tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp delete mode 100644 tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf delete mode 100644 tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf delete mode 100644 tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml delete mode 100644 tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf delete mode 100644 tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro delete mode 100644 tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp delete mode 100644 tests/auto/declarative/qdeclarativepath/data/arc.qml delete mode 100644 tests/auto/declarative/qdeclarativepath/data/curve.qml delete mode 100644 tests/auto/declarative/qdeclarativepath/data/svg.qml delete mode 100644 tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro delete mode 100644 tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/exists.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/exists1.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/exists2.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists1.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists2.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists3.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists4.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists5.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists6.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists7.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/http/exists8.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/data/massive.png delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro delete mode 100644 tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro delete mode 100644 tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp delete mode 100644 tests/auto/declarative/qdeclarativespringanimation/data/springanimation1.qml delete mode 100644 tests/auto/declarative/qdeclarativespringanimation/data/springanimation2.qml delete mode 100644 tests/auto/declarative/qdeclarativespringanimation/data/springanimation3.qml delete mode 100644 tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro delete mode 100644 tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp delete mode 100644 tests/auto/declarative/qdeclarativestates/data/ExtendedRectangle.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/Implementation/MyType.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/Implementation/images/qt-logo.png delete mode 100644 tests/auto/declarative/qdeclarativestates/data/QTBUG-14830.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges3.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges4.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChanges5.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorChangesCrash.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorRewindBug.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/attachedPropertyChanges.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/avoidFastForward.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicBinding.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicBinding2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicBinding3.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicBinding4.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicChanges.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicChanges2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicChanges3.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/basicExtension.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/deleting.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/deletingState.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/editProperties.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/explicit.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/extendsBug.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/fakeExtension.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/illegalObj.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/illegalTempState.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/image.png delete mode 100644 tests/auto/declarative/qdeclarativestates/data/legalTempState.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/nonExistantProp.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange1.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange3.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange4.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange5.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/parentChange6.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/propertyErrors.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/reset.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/restoreEntryValues.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/returnToBase.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/revertListBug.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/script.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/signalOverride.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/signalOverride2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/unnamedWhen.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/urlResolution.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml delete mode 100644 tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro delete mode 100644 tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp delete mode 100644 tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro delete mode 100644 tests/auto/declarative/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp delete mode 100644 tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro delete mode 100644 tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp delete mode 100644 tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro delete mode 100644 tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/empty.xml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/get.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/model.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/model.xml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/model2.xml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/propertychanges.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.xml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/roleErrors.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/roleKeys.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/data/unique.qml delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro delete mode 100644 tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp delete mode 100644 tests/auto/declarative/qquickanchors/data/anchors.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/centerin.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/centerinRotation.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/crash1.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/fill.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/hvCenter.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/loop1.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/loop2.qml delete mode 100644 tests/auto/declarative/qquickanchors/data/margins.qml delete mode 100644 tests/auto/declarative/qquickanchors/qquickanchors.pro delete mode 100644 tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/colors.gif delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/colors.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/hearts.gif delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/hearts.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/qmldir delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/qtbug-16520.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickman.gif delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickman.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickmanerror1.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickmanpause.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickmanscaled.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/data/stickmanstopped.qml delete mode 100644 tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro delete mode 100644 tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp delete mode 100644 tests/auto/declarative/qquickborderimage/data/colors-mirror.png delete mode 100644 tests/auto/declarative/qquickborderimage/data/colors-round-quotes.sci delete mode 100644 tests/auto/declarative/qquickborderimage/data/colors-round-remote.sci delete mode 100644 tests/auto/declarative/qquickborderimage/data/colors-round.sci delete mode 100644 tests/auto/declarative/qquickborderimage/data/colors.png delete mode 100644 tests/auto/declarative/qquickborderimage/data/heart200.png delete mode 100644 tests/auto/declarative/qquickborderimage/data/invalid.sci delete mode 100644 tests/auto/declarative/qquickborderimage/data/mirror.qml delete mode 100644 tests/auto/declarative/qquickborderimage/qquickborderimage.pro delete mode 100644 tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp delete mode 100644 tests/auto/declarative/qquickcanvas/data/window.qml delete mode 100644 tests/auto/declarative/qquickcanvas/qquickcanvas.pro delete mode 100644 tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/anim-gr.gif delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/anim-gr.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/anim-poster-gr.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/background.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/broken.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/ggrr-256x256.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/green-16x16.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/green-1x1.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/green-256x256.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/green-2x2.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/green.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/grgr-256x256.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/red-16x16.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/red.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/redtransparent.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/rgrg-256x256.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/rrgg-256x256.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/testhelper.js delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/transparent.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/transparent50.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_arc.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_arcto.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_canvas.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_composite.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_drawimage.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_fillStyle.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_fillrect.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_gradient.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_line.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_path.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_pattern.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_pixel.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_shadow.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_state.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_strokeStyle.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_text.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/tst_transform.qml delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/yellow.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/data/yellow75.png delete mode 100644 tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro delete mode 100644 tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp delete mode 100644 tests/auto/declarative/qquickdrag/qquickdrag.pro delete mode 100644 tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp delete mode 100644 tests/auto/declarative/qquickdroparea/qquickdroparea.pro delete mode 100644 tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp delete mode 100644 tests/auto/declarative/qquickflickable/data/disabled.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/flickable01.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/flickable02.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/flickable03.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/flickable04.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/flickableqgraphicswidget.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/margins.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/nestedPressDelay.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/resize.qml delete mode 100644 tests/auto/declarative/qquickflickable/data/wheel.qml delete mode 100644 tests/auto/declarative/qquickflickable/qquickflickable.pro delete mode 100644 tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp delete mode 100644 tests/auto/declarative/qquickflipable/data/crash.qml delete mode 100644 tests/auto/declarative/qquickflipable/data/flipable-abort.qml delete mode 100644 tests/auto/declarative/qquickflipable/data/test-flipable.qml delete mode 100644 tests/auto/declarative/qquickflipable/qquickflipable.pro delete mode 100644 tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp delete mode 100644 tests/auto/declarative/qquickfocusscope/data/canvasFocus.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/chain.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/forceActiveFocus.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/forcefocus.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/qtBug13380.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/signalEmission.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/test.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/test2.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/test3.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/test4.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/data/test5.qml delete mode 100644 tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro delete mode 100644 tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp delete mode 100644 tests/auto/declarative/qquickgridview/data/ComponentView.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/asyncloader.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/attachedSignals.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/creationContext.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/displaygrid.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/footer.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview-enforcerange.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview-initCurrent.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview-noCurrent.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview1.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview2.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview3.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/gridview4.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/header.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/manual-highlight.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/margins.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/mirroring.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/resizeview.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/setindex.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/snapToRow.qml delete mode 100644 tests/auto/declarative/qquickgridview/data/unaligned.qml delete mode 100644 tests/auto/declarative/qquickgridview/qquickgridview.pro delete mode 100644 tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp delete mode 100644 tests/auto/declarative/qquickimage/data/aspectratio.qml delete mode 100644 tests/auto/declarative/qquickimage/data/big.jpeg delete mode 100644 tests/auto/declarative/qquickimage/data/big256.png delete mode 100644 tests/auto/declarative/qquickimage/data/colors.png delete mode 100644 tests/auto/declarative/qquickimage/data/colors1.png delete mode 100644 tests/auto/declarative/qquickimage/data/green.png delete mode 100644 tests/auto/declarative/qquickimage/data/heart-win32.png delete mode 100644 tests/auto/declarative/qquickimage/data/heart.png delete mode 100644 tests/auto/declarative/qquickimage/data/heart.svg delete mode 100644 tests/auto/declarative/qquickimage/data/heart200-win32.png delete mode 100644 tests/auto/declarative/qquickimage/data/heart200.png delete mode 100644 tests/auto/declarative/qquickimage/data/htiling.qml delete mode 100644 tests/auto/declarative/qquickimage/data/mirror.qml delete mode 100644 tests/auto/declarative/qquickimage/data/nullpixmap.qml delete mode 100644 tests/auto/declarative/qquickimage/data/pattern.png delete mode 100644 tests/auto/declarative/qquickimage/data/qtbug_16389.qml delete mode 100644 tests/auto/declarative/qquickimage/data/qtbug_22125.qml delete mode 100644 tests/auto/declarative/qquickimage/data/rect.png delete mode 100644 tests/auto/declarative/qquickimage/data/vtiling.qml delete mode 100644 tests/auto/declarative/qquickimage/qquickimage.pro delete mode 100644 tests/auto/declarative/qquickimage/tst_qquickimage.cpp delete mode 100644 tests/auto/declarative/qquickitem/data/order.1.qml delete mode 100644 tests/auto/declarative/qquickitem/data/order.2.qml delete mode 100644 tests/auto/declarative/qquickitem/qquickitem.pro delete mode 100644 tests/auto/declarative/qquickitem/tst_qquickitem.cpp delete mode 100644 tests/auto/declarative/qquickitem2/data/childrenProperty.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/childrenRect.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/childrenRectBug.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/childrenRectBug2.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/childrenRectBug3.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/implicitsize.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/keynavigationtest.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/keynavigationtest_implicit.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/keyspriority.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/keystest.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/layoutmirroring.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/mapCoordinates.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/propertychanges.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/qtbug_16871.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/resourcesProperty.qml delete mode 100644 tests/auto/declarative/qquickitem2/data/transformCrash.qml delete mode 100644 tests/auto/declarative/qquickitem2/qquickitem2.pro delete mode 100644 tests/auto/declarative/qquickitem2/tst_qquickitem.cpp delete mode 100644 tests/auto/declarative/qquicklistview/data/ComponentView.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/asyncloader.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/attachedSignals.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/creationContext.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/displaylist.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/fillModelOnComponentCompleted.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/footer.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/header.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/headerfooter.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/itemlist.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-enforcerange-nohighlight.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-enforcerange.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-initCurrent.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-noCurrent.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-sections.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listview-sections_delegate.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/listviewtest.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/manual-highlight.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/margins.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/qtbug-21742.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/qtbug14821.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/qtbug16037.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/resizeview.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/rightToLeft.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/sizelessthan1.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/snapToItem.qml delete mode 100644 tests/auto/declarative/qquicklistview/data/strictlyenforcerange.qml delete mode 100644 tests/auto/declarative/qquicklistview/incrementalmodel.cpp delete mode 100644 tests/auto/declarative/qquicklistview/incrementalmodel.h delete mode 100644 tests/auto/declarative/qquicklistview/qquicklistview.pro delete mode 100644 tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp delete mode 100644 tests/auto/declarative/qquickloader/data/ActiveComponent.qml delete mode 100644 tests/auto/declarative/qquickloader/data/AnchoredLoader.qml delete mode 100644 tests/auto/declarative/qquickloader/data/BigComponent.qml delete mode 100644 tests/auto/declarative/qquickloader/data/BlueRect.qml delete mode 100644 tests/auto/declarative/qquickloader/data/CreationContextLoader.qml delete mode 100644 tests/auto/declarative/qquickloader/data/GraphicsWidget250x250.qml delete mode 100644 tests/auto/declarative/qquickloader/data/GreenRect.qml delete mode 100644 tests/auto/declarative/qquickloader/data/InitialPropertyValuesComponent.qml delete mode 100644 tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml delete mode 100644 tests/auto/declarative/qquickloader/data/NoResize.qml delete mode 100644 tests/auto/declarative/qquickloader/data/NoResizeGraphicsWidget.qml delete mode 100644 tests/auto/declarative/qquickloader/data/QTBUG_16928.qml delete mode 100644 tests/auto/declarative/qquickloader/data/QTBUG_17114.qml delete mode 100644 tests/auto/declarative/qquickloader/data/Rect120x60.qml delete mode 100644 tests/auto/declarative/qquickloader/data/SetSourceComponent.qml delete mode 100644 tests/auto/declarative/qquickloader/data/SizeGraphicsWidgetToLoader.qml delete mode 100644 tests/auto/declarative/qquickloader/data/SizeLoaderToGraphicsWidget.qml delete mode 100644 tests/auto/declarative/qquickloader/data/SizeToItem.qml delete mode 100644 tests/auto/declarative/qquickloader/data/SizeToLoader.qml delete mode 100644 tests/auto/declarative/qquickloader/data/VmeError.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.1.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.2.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.3.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.4.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.5.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.6.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.7.qml delete mode 100644 tests/auto/declarative/qquickloader/data/active.8.qml delete mode 100644 tests/auto/declarative/qquickloader/data/asynchronous.qml delete mode 100644 tests/auto/declarative/qquickloader/data/crash.qml delete mode 100644 tests/auto/declarative/qquickloader/data/creationContext.qml delete mode 100644 tests/auto/declarative/qquickloader/data/differentorigin.qml delete mode 100644 tests/auto/declarative/qquickloader/data/implicitSize.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.1.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.2.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.3.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.4.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.5.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.6.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.7.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.8.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.binding.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.error.1.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.error.2.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.error.3.qml delete mode 100644 tests/auto/declarative/qquickloader/data/initialPropertyValues.error.4.qml delete mode 100644 tests/auto/declarative/qquickloader/data/nonItem.qml delete mode 100644 tests/auto/declarative/qquickloader/data/parented.qml delete mode 100644 tests/auto/declarative/qquickloader/data/qmldir delete mode 100644 tests/auto/declarative/qquickloader/data/sameorigin-load.qml delete mode 100644 tests/auto/declarative/qquickloader/data/sameorigin.qml delete mode 100644 tests/auto/declarative/qquickloader/data/vmeErrors.qml delete mode 100644 tests/auto/declarative/qquickloader/qquickloader.pro delete mode 100644 tests/auto/declarative/qquickloader/tst_qquickloader.cpp delete mode 100644 tests/auto/declarative/qquickmousearea/data/clickThrough.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/clickThrough2.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/clickandhold.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/clicktwice.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/doubleclick.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/dragging.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/dragproperties.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/dragreset.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/hoverPosition.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/hoverPropagation.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/noclickandhold.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/pressedCanceled.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/pressedOrdering.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/preventstealing.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/rejectEvent.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/updateMousePosOnClick.qml delete mode 100644 tests/auto/declarative/qquickmousearea/data/updateMousePosOnResize.qml delete mode 100644 tests/auto/declarative/qquickmousearea/qquickmousearea.pro delete mode 100644 tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro delete mode 100644 tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp delete mode 100644 tests/auto/declarative/qquickpathview/data/ComponentView.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/asyncloader.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/closedPath.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/creationContext.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/datamodel.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/displaypath.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/dragpath.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/emptymodel.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/missingPercent.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/openPath.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathUpdate.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathUpdateOnStartChanged.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathline.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathtest.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathview0.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathview1.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathview2.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathview3.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/pathview_package.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/propertychanges.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/treemodel.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/undefinedpath.qml delete mode 100644 tests/auto/declarative/qquickpathview/data/vdm.qml delete mode 100644 tests/auto/declarative/qquickpathview/qquickpathview.pro delete mode 100644 tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp delete mode 100644 tests/auto/declarative/qquickpincharea/data/pinchproperties.qml delete mode 100644 tests/auto/declarative/qquickpincharea/qquickpincharea.pro delete mode 100644 tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp delete mode 100644 tests/auto/declarative/qquickpositioners/data/allInvisible.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/attachedproperties-column.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/attachedproperties-dynamic.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/attachedproperties-flow.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/attachedproperties-grid.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/attachedproperties-row.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/flow-testimplicitsize.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/flowtest-toptobottom.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/flowtest.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/grid-animated.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/grid-row-column-spacing.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/grid-spacing.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/grid-toptobottom.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/gridtest.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/gridzerocolumns.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/horizontal-animated-disabled.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/horizontal-animated.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/horizontal-spacing.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/horizontal.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/propertychangestest.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/rectangleComponent.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/repeatertest.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/vertical-animated.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/vertical-spacing.qml delete mode 100644 tests/auto/declarative/qquickpositioners/data/vertical.qml delete mode 100644 tests/auto/declarative/qquickpositioners/qquickpositioners.pro delete mode 100644 tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp delete mode 100644 tests/auto/declarative/qquickrepeater/data/asyncloader.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/initparent.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/intmodel.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/itemlist.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/modelChanged.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/objlist.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/properties.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/repeater1.qml delete mode 100644 tests/auto/declarative/qquickrepeater/data/repeater2.qml delete mode 100644 tests/auto/declarative/qquickrepeater/qquickrepeater.pro delete mode 100644 tests/auto/declarative/qquickrepeater/tst_qquickrepeater.cpp delete mode 100644 tests/auto/declarative/qquickshadereffect/qquickshadereffect.pro delete mode 100644 tests/auto/declarative/qquickshadereffect/tst_qquickshadereffect.cpp delete mode 100644 tests/auto/declarative/qquickspriteimage/data/basic.qml delete mode 100644 tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png delete mode 100644 tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro delete mode 100644 tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp delete mode 100644 tests/auto/declarative/qquicktext/data/alignments.qml delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_cb.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_cc.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_ct.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_lb.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_lc.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_lt.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_rb.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_rc.png delete mode 100644 tests/auto/declarative/qquicktext/data/alignments_rt.png delete mode 100644 tests/auto/declarative/qquicktext/data/embeddedImagesLocal.qml delete mode 100644 tests/auto/declarative/qquicktext/data/embeddedImagesLocalError.qml delete mode 100644 tests/auto/declarative/qquicktext/data/embeddedImagesRemote.qml delete mode 100644 tests/auto/declarative/qquicktext/data/embeddedImagesRemoteError.qml delete mode 100644 tests/auto/declarative/qquicktext/data/horizontalAlignment_RightToLeft.qml delete mode 100644 tests/auto/declarative/qquicktext/data/http/exists.png delete mode 100644 tests/auto/declarative/qquicktext/data/lineCount.qml delete mode 100644 tests/auto/declarative/qquicktext/data/lineHeight.qml delete mode 100644 tests/auto/declarative/qquicktext/data/lineLayout.qml delete mode 100644 tests/auto/declarative/qquicktext/data/multilineelide.qml delete mode 100644 tests/auto/declarative/qquicktext/data/qtbug_14734.qml delete mode 100644 tests/auto/declarative/qquicktext/data/rotated.qml delete mode 100644 tests/auto/declarative/qquicktext/qquicktext.pro delete mode 100644 tests/auto/declarative/qquicktext/tst_qquicktext.cpp delete mode 100644 tests/auto/declarative/qquicktextedit/data/CursorRect.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_cb.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_cc.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_ct.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_lb.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_lc.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_lt.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_rb.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_rc.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/alignments_rt.png delete mode 100644 tests/auto/declarative/qquicktextedit/data/cursorTest.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/cursorVisible.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/geometrySignals.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/horizontalAlignment_RightToLeft.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/ErrItem.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/NormItem.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/cursorHttpTest.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail1.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail2.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestPass.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/http/qmldir delete mode 100644 tests/auto/declarative/qquicktextedit/data/httpfail/FailItem.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/httpslow/WaitItem.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/inputContext.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/inputMethodEvent.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/inputmethodhints.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselection_default.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselection_false.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselection_false_words.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselection_true.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselection_true_words.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselectionmode_characters.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselectionmode_default.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/mouseselectionmode_words.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/navigation.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/openInputPanel.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/positionAt.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/qtbug-22058.qml delete mode 100644 tests/auto/declarative/qquicktextedit/data/readOnly.qml delete mode 100644 tests/auto/declarative/qquicktextedit/qquicktextedit.pro delete mode 100644 tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp delete mode 100644 tests/auto/declarative/qquicktextinput/data/cursorTest.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/cursorVisible.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/echoMode.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/geometrySignals.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/halign_center.png delete mode 100644 tests/auto/declarative/qquicktextinput/data/halign_left.png delete mode 100644 tests/auto/declarative/qquicktextinput/data/halign_right.png delete mode 100644 tests/auto/declarative/qquicktextinput/data/horizontalAlignment.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/horizontalAlignment_RightToLeft.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/inputContext.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/inputMethodEvent.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/inputmethods.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/masks.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/maxLength.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/mouseselection_true.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/mouseselectionmode_characters.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/mouseselectionmode_default.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/mouseselectionmode_words.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/navigation.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/openInputPanel.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/positionAt.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/preeditAutoScroll.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/qtbug-19956double.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/qtbug-19956int.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/qtbug-19956regexp.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/readOnly.qml delete mode 100644 tests/auto/declarative/qquicktextinput/data/validators.qml delete mode 100644 tests/auto/declarative/qquicktextinput/qquicktextinput.pro delete mode 100644 tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp delete mode 100644 tests/auto/declarative/qquickview/data/error1.qml delete mode 100644 tests/auto/declarative/qquickview/data/resizemodeitem.qml delete mode 100644 tests/auto/declarative/qquickview/qquickview.pro delete mode 100644 tests/auto/declarative/qquickview/tst_qquickview.cpp delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/create.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/datalist.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/groups.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/modelproperties.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/modelproperties2.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/objectlist.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/singlerole1.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/singlerole2.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/data/visualdatamodel.qml delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro delete mode 100644 tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp delete mode 100644 tests/auto/declarative/shared/testhttpserver.cpp delete mode 100644 tests/auto/declarative/shared/testhttpserver.h delete mode 100644 tests/auto/declarative/shared/util.h create mode 100644 tests/auto/qtquick2/examples/data/dummytest.qml create mode 100644 tests/auto/qtquick2/examples/data/webbrowser/webbrowser.qml create mode 100644 tests/auto/qtquick2/examples/examples.pro create mode 100644 tests/auto/qtquick2/examples/tst_examples.cpp create mode 100644 tests/auto/qtquick2/geometry/geometry.pro create mode 100644 tests/auto/qtquick2/geometry/tst_geometry.cpp create mode 100644 tests/auto/qtquick2/nodes/nodes.pro create mode 100644 tests/auto/qtquick2/nodes/tst_nodestest.cpp create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/Double.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/attached.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badproperty1.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badproperty2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badtype1.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badtype2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badtype3.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/badtype4.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/disabledTransition.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/dontAutoStart.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/dontStart.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/dontStart2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/dotproperty.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/doubleRegistrationBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype1.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/nonTransitionBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimationNoStart.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolator.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolatorBack.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pathTransition.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pauseBindingBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/pauseBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/properties.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/properties2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/properties3.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/properties4.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/properties5.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition3.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition4.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition5.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition6.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition7.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/registrationBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/rotation.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/runningTrueBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/transitionAssignmentBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/valuesource.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/data/valuesource2.qml create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/qdeclarativeanimations.pro create mode 100644 tests/auto/qtquick2/qdeclarativeanimations/tst_qdeclarativeanimations.cpp create mode 100644 tests/auto/qtquick2/qdeclarativeapplication/qdeclarativeapplication.pro create mode 100644 tests/auto/qtquick2/qdeclarativeapplication/tst_qdeclarativeapplication.cpp create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/binding.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/color.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/cpptrigger.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/delayedRegistration.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/disabled.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/dontStart.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/empty.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/explicit.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty2.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/groupedPropertyCrash.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/loop.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/nonSelecting2.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/parent.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/qtbug12295.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/reassignedAnimation.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/runningTrue.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/scripttrigger.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/simple.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/startOnCompleted.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/startup.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/startup2.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/data/valueType.qml create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/qdeclarativebehaviors.pro create mode 100644 tests/auto/qtquick2/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/data/daniel.ttf create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/data/dummy.ttf create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/data/qtbug-20268.qml create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/data/tarzeau_ocr_a.ttf create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/qdeclarativefontloader.pro create mode 100644 tests/auto/qtquick2/qdeclarativefontloader/tst_qdeclarativefontloader.cpp create mode 100644 tests/auto/qtquick2/qdeclarativepath/data/arc.qml create mode 100644 tests/auto/qtquick2/qdeclarativepath/data/curve.qml create mode 100644 tests/auto/qtquick2/qdeclarativepath/data/svg.qml create mode 100644 tests/auto/qtquick2/qdeclarativepath/qdeclarativepath.pro create mode 100644 tests/auto/qtquick2/qdeclarativepath/tst_qdeclarativepath.cpp create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/exists.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/exists1.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/exists2.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists1.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists2.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists3.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists4.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists5.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists6.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists7.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists8.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/data/massive.png create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/qdeclarativepixmapcache.pro create mode 100644 tests/auto/qtquick2/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation1.qml create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation2.qml create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation3.qml create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro create mode 100644 tests/auto/qtquick2/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp create mode 100644 tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation1.qml create mode 100644 tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation2.qml create mode 100644 tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation3.qml create mode 100644 tests/auto/qtquick2/qdeclarativespringanimation/qdeclarativespringanimation.pro create mode 100644 tests/auto/qtquick2/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/ExtendedRectangle.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/Implementation/MyType.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/Implementation/images/qt-logo.png create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/QTBUG-14830.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChanges1.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChanges2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChanges3.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChanges4.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChanges5.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorChangesCrash.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/attachedPropertyChanges.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/avoidFastForward.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicBinding.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicBinding2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicBinding3.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicBinding4.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicChanges.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicChanges2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicChanges3.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicChanges4.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/basicExtension.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/deleting.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/deletingState.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/editProperties.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/explicit.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/extendsBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/fakeExtension.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/illegalObj.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/illegalTempState.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/image.png create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/legalTempState.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/nonExistantProp.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange1.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange3.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange4.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange5.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/parentChange6.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/propertyErrors.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/reset.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/restoreEntryValues.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/returnToBase.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/revertListBug.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/script.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/signalOverride.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/signalOverride2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash2.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash3.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/unnamedWhen.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/urlResolution.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/data/whenOrdering.qml create mode 100644 tests/auto/qtquick2/qdeclarativestates/qdeclarativestates.pro create mode 100644 tests/auto/qtquick2/qdeclarativestates/tst_qdeclarativestates.cpp create mode 100644 tests/auto/qtquick2/qdeclarativestyledtext/qdeclarativestyledtext.pro create mode 100644 tests/auto/qtquick2/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp create mode 100644 tests/auto/qtquick2/qdeclarativesystempalette/qdeclarativesystempalette.pro create mode 100644 tests/auto/qtquick2/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp create mode 100644 tests/auto/qtquick2/qdeclarativetimer/qdeclarativetimer.pro create mode 100644 tests/auto/qtquick2/qdeclarativetimer/tst_qdeclarativetimer.cpp create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/empty.xml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/get.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.xml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/model2.xml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/propertychanges.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.xml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleCrash.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleErrors.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleKeys.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/testtypes.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/data/unique.qml create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro create mode 100644 tests/auto/qtquick2/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp create mode 100644 tests/auto/qtquick2/qquickanchors/data/anchors.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/centerin.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/centerinRotation.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/crash1.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/fill.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/hvCenter.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/loop1.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/loop2.qml create mode 100644 tests/auto/qtquick2/qquickanchors/data/margins.qml create mode 100644 tests/auto/qtquick2/qquickanchors/qquickanchors.pro create mode 100644 tests/auto/qtquick2/qquickanchors/tst_qquickanchors.cpp create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/colors.gif create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/colors.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/hearts.gif create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/hearts.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/qmldir create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/qtbug-16520.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickman.gif create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickman.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickmanerror1.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickmanpause.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickmanscaled.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/data/stickmanstopped.qml create mode 100644 tests/auto/qtquick2/qquickanimatedimage/qquickanimatedimage.pro create mode 100644 tests/auto/qtquick2/qquickanimatedimage/tst_qquickanimatedimage.cpp create mode 100644 tests/auto/qtquick2/qquickborderimage/data/colors-mirror.png create mode 100644 tests/auto/qtquick2/qquickborderimage/data/colors-round-quotes.sci create mode 100644 tests/auto/qtquick2/qquickborderimage/data/colors-round-remote.sci create mode 100644 tests/auto/qtquick2/qquickborderimage/data/colors-round.sci create mode 100644 tests/auto/qtquick2/qquickborderimage/data/colors.png create mode 100644 tests/auto/qtquick2/qquickborderimage/data/heart200.png create mode 100644 tests/auto/qtquick2/qquickborderimage/data/invalid.sci create mode 100644 tests/auto/qtquick2/qquickborderimage/data/mirror.qml create mode 100644 tests/auto/qtquick2/qquickborderimage/qquickborderimage.pro create mode 100644 tests/auto/qtquick2/qquickborderimage/tst_qquickborderimage.cpp create mode 100644 tests/auto/qtquick2/qquickcanvas/data/window.qml create mode 100644 tests/auto/qtquick2/qquickcanvas/qquickcanvas.pro create mode 100644 tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.gif create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/anim-poster-gr.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/background.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/broken.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/ggrr-256x256.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/green-16x16.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/green-1x1.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/green-256x256.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/green-2x2.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/green.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/grgr-256x256.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/red-16x16.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/red.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/redtransparent.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/rgrg-256x256.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/rrgg-256x256.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/testhelper.js create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/transparent.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/transparent50.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_arc.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_arcto.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_canvas.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_composite.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_drawimage.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_fillStyle.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_fillrect.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_gradient.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_line.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_path.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_pattern.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_pixel.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_shadow.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_state.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_strokeStyle.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_text.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/tst_transform.qml create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/yellow.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/data/yellow75.png create mode 100644 tests/auto/qtquick2/qquickcanvasitem/qquickcanvasitem.pro create mode 100644 tests/auto/qtquick2/qquickcanvasitem/tst_qquickcanvasitem.cpp create mode 100644 tests/auto/qtquick2/qquickdrag/qquickdrag.pro create mode 100644 tests/auto/qtquick2/qquickdrag/tst_qquickdrag.cpp create mode 100644 tests/auto/qtquick2/qquickdroparea/qquickdroparea.pro create mode 100644 tests/auto/qtquick2/qquickdroparea/tst_qquickdroparea.cpp create mode 100644 tests/auto/qtquick2/qquickflickable/data/disabled.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/flickable01.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/flickable02.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/flickable03.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/flickable04.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/flickableqgraphicswidget.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/margins.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/nestedPressDelay.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/resize.qml create mode 100644 tests/auto/qtquick2/qquickflickable/data/wheel.qml create mode 100644 tests/auto/qtquick2/qquickflickable/qquickflickable.pro create mode 100644 tests/auto/qtquick2/qquickflickable/tst_qquickflickable.cpp create mode 100644 tests/auto/qtquick2/qquickflipable/data/crash.qml create mode 100644 tests/auto/qtquick2/qquickflipable/data/flipable-abort.qml create mode 100644 tests/auto/qtquick2/qquickflipable/data/test-flipable.qml create mode 100644 tests/auto/qtquick2/qquickflipable/qquickflipable.pro create mode 100644 tests/auto/qtquick2/qquickflipable/tst_qquickflipable.cpp create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/canvasFocus.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/chain.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/forceActiveFocus.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/forcefocus.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/qtBug13380.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/signalEmission.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/test.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/test2.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/test3.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/test4.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/data/test5.qml create mode 100644 tests/auto/qtquick2/qquickfocusscope/qquickfocusscope.pro create mode 100644 tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp create mode 100644 tests/auto/qtquick2/qquickgridview/data/ComponentView.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/asyncloader.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/attachedSignals.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/creationContext.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/displaygrid.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/footer.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview-enforcerange.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview-initCurrent.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview-noCurrent.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview1.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview2.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview3.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/gridview4.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/header.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/manual-highlight.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/margins.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/mirroring.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/propertychangestest.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/resizeview.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/setindex.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/snapToRow.qml create mode 100644 tests/auto/qtquick2/qquickgridview/data/unaligned.qml create mode 100644 tests/auto/qtquick2/qquickgridview/qquickgridview.pro create mode 100644 tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp create mode 100644 tests/auto/qtquick2/qquickimage/data/aspectratio.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/big.jpeg create mode 100644 tests/auto/qtquick2/qquickimage/data/big256.png create mode 100644 tests/auto/qtquick2/qquickimage/data/colors.png create mode 100644 tests/auto/qtquick2/qquickimage/data/colors1.png create mode 100644 tests/auto/qtquick2/qquickimage/data/green.png create mode 100644 tests/auto/qtquick2/qquickimage/data/heart-win32.png create mode 100644 tests/auto/qtquick2/qquickimage/data/heart.png create mode 100644 tests/auto/qtquick2/qquickimage/data/heart.svg create mode 100644 tests/auto/qtquick2/qquickimage/data/heart200-win32.png create mode 100644 tests/auto/qtquick2/qquickimage/data/heart200.png create mode 100644 tests/auto/qtquick2/qquickimage/data/htiling.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/mirror.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/nullpixmap.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/pattern.png create mode 100644 tests/auto/qtquick2/qquickimage/data/qtbug_16389.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/qtbug_22125.qml create mode 100644 tests/auto/qtquick2/qquickimage/data/rect.png create mode 100644 tests/auto/qtquick2/qquickimage/data/vtiling.qml create mode 100644 tests/auto/qtquick2/qquickimage/qquickimage.pro create mode 100644 tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp create mode 100644 tests/auto/qtquick2/qquickitem/data/order.1.qml create mode 100644 tests/auto/qtquick2/qquickitem/data/order.2.qml create mode 100644 tests/auto/qtquick2/qquickitem/qquickitem.pro create mode 100644 tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp create mode 100644 tests/auto/qtquick2/qquickitem2/data/childrenProperty.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/childrenRect.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/childrenRectBug.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/childrenRectBug2.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/childrenRectBug3.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/implicitsize.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/keynavigationtest.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/keynavigationtest_implicit.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/keyspriority.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/keystest.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/layoutmirroring.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/mapCoordinates.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/propertychanges.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/qtbug_16871.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/resourcesProperty.qml create mode 100644 tests/auto/qtquick2/qquickitem2/data/transformCrash.qml create mode 100644 tests/auto/qtquick2/qquickitem2/qquickitem2.pro create mode 100644 tests/auto/qtquick2/qquickitem2/tst_qquickitem.cpp create mode 100644 tests/auto/qtquick2/qquicklistview/data/ComponentView.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/asyncloader.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/attachedSignals.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/creationContext.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/displaylist.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/fillModelOnComponentCompleted.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/footer.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/header.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/headerfooter.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/itemlist.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-enforcerange-nohighlight.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-enforcerange.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-initCurrent.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-noCurrent.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-sections.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listview-sections_delegate.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/listviewtest.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/manual-highlight.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/margins.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/propertychangestest.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/qtbug-21742.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/qtbug14821.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/qtbug16037.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/resizeview.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/rightToLeft.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/sizelessthan1.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/snapToItem.qml create mode 100644 tests/auto/qtquick2/qquicklistview/data/strictlyenforcerange.qml create mode 100644 tests/auto/qtquick2/qquicklistview/incrementalmodel.cpp create mode 100644 tests/auto/qtquick2/qquicklistview/incrementalmodel.h create mode 100644 tests/auto/qtquick2/qquicklistview/qquicklistview.pro create mode 100644 tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp create mode 100644 tests/auto/qtquick2/qquickloader/data/ActiveComponent.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/AnchoredLoader.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/BigComponent.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/BlueRect.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/CreationContextLoader.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/GraphicsWidget250x250.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/GreenRect.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/InitialPropertyValuesComponent.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/InvalidSourceComponent.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/NoResize.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/NoResizeGraphicsWidget.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/QTBUG_16928.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/QTBUG_17114.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/Rect120x60.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/SetSourceComponent.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/SizeGraphicsWidgetToLoader.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/SizeLoaderToGraphicsWidget.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/SizeToItem.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/SizeToLoader.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/VmeError.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.1.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.2.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.3.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.4.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.5.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.6.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.7.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/active.8.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/asynchronous.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/crash.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/creationContext.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/differentorigin.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/implicitSize.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.1.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.2.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.3.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.4.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.5.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.6.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.7.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.8.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.binding.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.1.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.2.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.3.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.4.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/nonItem.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/parented.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/qmldir create mode 100644 tests/auto/qtquick2/qquickloader/data/sameorigin-load.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/sameorigin.qml create mode 100644 tests/auto/qtquick2/qquickloader/data/vmeErrors.qml create mode 100644 tests/auto/qtquick2/qquickloader/qquickloader.pro create mode 100644 tests/auto/qtquick2/qquickloader/tst_qquickloader.cpp create mode 100644 tests/auto/qtquick2/qquickmousearea/data/clickThrough.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/clickThrough2.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/clickandhold.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/clicktwice.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/doubleclick.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/dragging.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/dragproperties.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/dragreset.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/hoverPosition.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/hoverPropagation.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/noclickandhold.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/pressedCanceled.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/pressedOrdering.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/preventstealing.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/rejectEvent.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnClick.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnResize.qml create mode 100644 tests/auto/qtquick2/qquickmousearea/qquickmousearea.pro create mode 100644 tests/auto/qtquick2/qquickmousearea/tst_qquickmousearea.cpp create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/data/inFlickable.qml create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/data/nested.qml create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/data/nonOverlapping.qml create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/data/properties.qml create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/data/signalTest.qml create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/qquickmultipointtoucharea.pro create mode 100644 tests/auto/qtquick2/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp create mode 100644 tests/auto/qtquick2/qquickpathview/data/ComponentView.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/asyncloader.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/closedPath.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/creationContext.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/datamodel.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/displaypath.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/dragpath.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/emptymodel.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/missingPercent.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/openPath.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathUpdate.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathUpdateOnStartChanged.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathline.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathtest.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathview0.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathview1.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathview2.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathview3.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/pathview_package.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/propertychanges.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/treemodel.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/undefinedpath.qml create mode 100644 tests/auto/qtquick2/qquickpathview/data/vdm.qml create mode 100644 tests/auto/qtquick2/qquickpathview/qquickpathview.pro create mode 100644 tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp create mode 100644 tests/auto/qtquick2/qquickpincharea/data/pinchproperties.qml create mode 100644 tests/auto/qtquick2/qquickpincharea/qquickpincharea.pro create mode 100644 tests/auto/qtquick2/qquickpincharea/tst_qquickpincharea.cpp create mode 100644 tests/auto/qtquick2/qquickpositioners/data/allInvisible.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/attachedproperties-column.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/attachedproperties-dynamic.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/attachedproperties-flow.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/attachedproperties-grid.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/attachedproperties-row.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/flow-testimplicitsize.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/flowtest-toptobottom.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/flowtest.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/grid-animated.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/grid-row-column-spacing.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/grid-spacing.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/grid-toptobottom.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/gridtest.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/gridzerocolumns.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/horizontal-animated-disabled.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/horizontal-animated.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/horizontal-spacing.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/horizontal.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/propertychangestest.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/rectangleComponent.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/repeatertest.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/vertical-animated.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/vertical-spacing.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/data/vertical.qml create mode 100644 tests/auto/qtquick2/qquickpositioners/qquickpositioners.pro create mode 100644 tests/auto/qtquick2/qquickpositioners/tst_qquickpositioners.cpp create mode 100644 tests/auto/qtquick2/qquickrepeater/data/asyncloader.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/initparent.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/intmodel.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/itemlist.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/modelChanged.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/objlist.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/properties.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/repeater1.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/data/repeater2.qml create mode 100644 tests/auto/qtquick2/qquickrepeater/qquickrepeater.pro create mode 100644 tests/auto/qtquick2/qquickrepeater/tst_qquickrepeater.cpp create mode 100644 tests/auto/qtquick2/qquickshadereffect/qquickshadereffect.pro create mode 100644 tests/auto/qtquick2/qquickshadereffect/tst_qquickshadereffect.cpp create mode 100644 tests/auto/qtquick2/qquickspriteimage/data/basic.qml create mode 100644 tests/auto/qtquick2/qquickspriteimage/data/squarefacesprite.png create mode 100644 tests/auto/qtquick2/qquickspriteimage/qquickspriteimage.pro create mode 100644 tests/auto/qtquick2/qquickspriteimage/tst_qquickspriteimage.cpp create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_cb.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_cc.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_ct.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_lb.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_lc.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_lt.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_rb.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_rc.png create mode 100644 tests/auto/qtquick2/qquicktext/data/alignments_rt.png create mode 100644 tests/auto/qtquick2/qquicktext/data/embeddedImagesLocal.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/embeddedImagesLocalError.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/embeddedImagesRemote.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/embeddedImagesRemoteError.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/horizontalAlignment_RightToLeft.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/http/exists.png create mode 100644 tests/auto/qtquick2/qquicktext/data/lineCount.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/lineHeight.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/lineLayout.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/multilineelide.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/qtbug_14734.qml create mode 100644 tests/auto/qtquick2/qquicktext/data/rotated.qml create mode 100644 tests/auto/qtquick2/qquicktext/qquicktext.pro create mode 100644 tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp create mode 100644 tests/auto/qtquick2/qquicktextedit/data/CursorRect.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_cb.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_cc.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_ct.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_lb.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_lc.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_lt.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_rb.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_rc.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/alignments_rt.png create mode 100644 tests/auto/qtquick2/qquicktextedit/data/cursorTest.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/cursorVisible.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/geometrySignals.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/horizontalAlignment_RightToLeft.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/ErrItem.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/NormItem.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTest.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail1.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail2.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestPass.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/http/qmldir create mode 100644 tests/auto/qtquick2/qquicktextedit/data/httpfail/FailItem.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/httpslow/WaitItem.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/inputContext.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/inputMethodEvent.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/inputmethodhints.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselection_default.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselection_false.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselection_false_words.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselection_true.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselection_true_words.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_characters.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_default.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_words.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/navigation.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/openInputPanel.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/positionAt.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/qtbug-22058.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/data/readOnly.qml create mode 100644 tests/auto/qtquick2/qquicktextedit/qquicktextedit.pro create mode 100644 tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp create mode 100644 tests/auto/qtquick2/qquicktextinput/data/cursorTest.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/cursorVisible.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/echoMode.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/geometrySignals.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/halign_center.png create mode 100644 tests/auto/qtquick2/qquicktextinput/data/halign_left.png create mode 100644 tests/auto/qtquick2/qquicktextinput/data/halign_right.png create mode 100644 tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment_RightToLeft.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/inputContext.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/inputMethodEvent.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/inputmethods.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/masks.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/maxLength.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/mouseselection_true.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_characters.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_default.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_words.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/navigation.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/openInputPanel.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/positionAt.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/preeditAutoScroll.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/qtbug-19956double.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/qtbug-19956int.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/qtbug-19956regexp.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/readOnly.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/data/validators.qml create mode 100644 tests/auto/qtquick2/qquicktextinput/qquicktextinput.pro create mode 100644 tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp create mode 100644 tests/auto/qtquick2/qquickview/data/error1.qml create mode 100644 tests/auto/qtquick2/qquickview/data/resizemodeitem.qml create mode 100644 tests/auto/qtquick2/qquickview/qquickview.pro create mode 100644 tests/auto/qtquick2/qquickview/tst_qquickview.cpp create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/create.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/datalist-package.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/datalist.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/groups-invalid.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/groups-package.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/groups.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_listView.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_package.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties2.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/objectlist.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/onChanged.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole1.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole2.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/data/visualdatamodel.qml create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/qquickvisualdatamodel.pro create mode 100644 tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp create mode 100644 tests/auto/qtquick2/qtquick2.pro create mode 100644 tests/auto/shared/testhttpserver.cpp create mode 100644 tests/auto/shared/testhttpserver.h create mode 100644 tests/auto/shared/util.h (limited to 'tests') diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index c3ec7231cc..c4ed5aeee8 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,6 +1,7 @@ TEMPLATE=subdirs SUBDIRS=\ declarative \ + qtquick2 \ particles # ### refactor: port properly diff --git a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp index 105700eedc..8967b844df 100644 --- a/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp +++ b/tests/auto/declarative/debugger/qdeclarativedebugjs/tst_qdeclarativedebugjs.cpp @@ -51,7 +51,7 @@ //QDeclarativeDebugTest #include "../shared/debugutil_p.h" -#include "../../shared/util.h" +#include "../../../shared/util.h" const char *SEQ = "seq"; const char *TYPE = "type"; diff --git a/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp index 21aeca9040..6754503de9 100644 --- a/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp +++ b/tests/auto/declarative/debugger/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp @@ -50,7 +50,7 @@ #include #include -#include "../../shared/util.h" +#include "../../../shared/util.h" #include "../shared/debugutil_p.h" #define PORT 13769 diff --git a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp index fc2f0d6626..3b5311e617 100644 --- a/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp +++ b/tests/auto/declarative/debugger/qdeclarativedebugtrace/tst_qdeclarativedebugtrace.cpp @@ -44,7 +44,7 @@ #include "QtDeclarative/private/qdeclarativedebugtrace_p.h" #include "../shared/debugutil_p.h" -#include "../../shared/util.h" +#include "../../../shared/util.h" #define PORT 13773 #define STR_PORT "13773" diff --git a/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro b/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro index 4805f37e55..6b414d3c32 100644 --- a/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro +++ b/tests/auto/declarative/debugger/qdeclarativeenginedebug/qdeclarativeenginedebug.pro @@ -8,4 +8,4 @@ SOURCES += tst_qdeclarativeenginedebug.cpp \ CONFIG += parallel_test declarative_debug -QT += core-private declarative-private v8-private testlib +QT += core-private declarative-private quick-private v8-private testlib diff --git a/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp b/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp index f48b281d3a..d5e4696936 100644 --- a/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp +++ b/tests/auto/declarative/debugger/qdeclarativeenginedebug/tst_qdeclarativeenginedebug.cpp @@ -50,7 +50,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro b/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro index 7b6783b112..90595df881 100644 --- a/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/app.pro @@ -1,5 +1,5 @@ TARGET = app -QT += declarative widgets qtquick1 +QT += declarative quick widgets qtquick1 CONFIG += declarative_debug macx:CONFIG -= app_bundle diff --git a/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp b/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp index c851222461..67d0a4499e 100644 --- a/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp +++ b/tests/auto/declarative/debugger/qdeclarativeinspector/app/main.cpp @@ -41,7 +41,7 @@ #include #include -#include +#include #include #include diff --git a/tests/auto/declarative/debugger/qv8profilerservice/tst_qv8profilerservice.cpp b/tests/auto/declarative/debugger/qv8profilerservice/tst_qv8profilerservice.cpp index 00ed1317a0..0739c746b9 100644 --- a/tests/auto/declarative/debugger/qv8profilerservice/tst_qv8profilerservice.cpp +++ b/tests/auto/declarative/debugger/qv8profilerservice/tst_qv8profilerservice.cpp @@ -44,7 +44,7 @@ #include "QtDeclarative/private/qv8profilerservice_p.h" #include "../shared/debugutil_p.h" -#include "../../shared/util.h" +#include "../../../shared/util.h" #define PORT 13774 #define STR_PORT "13774" diff --git a/tests/auto/declarative/declarative.pro b/tests/auto/declarative/declarative.pro index 708127289b..8e52392941 100644 --- a/tests/auto/declarative/declarative.pro +++ b/tests/auto/declarative/declarative.pro @@ -4,9 +4,6 @@ METATYPETESTS += \ qdeclarativemetatype PUBLICTESTS += \ - examples \ - geometry \ - nodes \ parserstress \ qdeclarativecomponent \ qdeclarativeconsole \ @@ -19,7 +16,6 @@ PUBLICTESTS += \ qdeclarativelistreference \ qdeclarativelocale \ qdeclarativemoduleplugin \ - qdeclarativepixmapcache \ qdeclarativeqt \ qdeclarativetranslation \ qdeclarativexmlhttprequest \ @@ -30,76 +26,28 @@ PUBLICTESTS += \ qmlplugindump PRIVATETESTS += \ - qdeclarativeanimations \ - qdeclarativeapplication \ - qdeclarativebehaviors \ qdeclarativebinding \ qdeclarativechangeset \ qdeclarativeconnection \ qdeclarativecpputils \ qdeclarativeecmascript \ qdeclarativeexpression \ - qdeclarativefontloader \ qdeclarativeimageprovider \ qdeclarativeinstruction \ qdeclarativelanguage \ qdeclarativelistcompositor \ qdeclarativelistmodel \ - qdeclarativepath \ qdeclarativeproperty \ qdeclarativepropertymap \ - qdeclarativesmoothedanimation \ - qdeclarativespringanimation \ qdeclarativesqldatabase \ - qdeclarativestates \ - qdeclarativestyledtext \ - qdeclarativesystempalette \ - qdeclarativetimer \ qdeclarativevaluetypes \ qdeclarativeworkerscript \ - qdeclarativexmllistmodel \ v4 -# This test requires the xmlpatterns module -!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qdeclarativexmllistmodel - -QUICKTESTS = \ - qquickanchors \ - qquickanimatedimage \ - qquickborderimage \ - qquickcanvas \ - qquickcanvasitem \ - qquickdrag \ - qquickdroparea \ - qquickflickable \ - qquickflipable \ - qquickfocusscope \ - qquickgridview \ - qquickimage \ - qquickitem \ - qquickitem2 \ - qquicklistview \ - qquickloader \ - qquickmousearea \ - qquickmultipointtoucharea \ - qquickpathview \ - qquickpincharea \ - qquickpositioners \ - qquickrepeater \ - qquickshadereffect \ - qquickspriteimage \ - qquicktext \ - qquicktextedit \ - qquicktextinput \ - qquickview \ - qquickvisualdatamodel \ - - SUBDIRS += $$PUBLICTESTS SUBDIRS += $$METATYPETESTS SUBDIRS += debugger contains(QT_CONFIG, private_tests) { SUBDIRS += $$PRIVATETESTS - SUBDIRS += $$QUICKTESTS } diff --git a/tests/auto/declarative/examples/data/dummytest.qml b/tests/auto/declarative/examples/data/dummytest.qml deleted file mode 100644 index b20e907f27..0000000000 --- a/tests/auto/declarative/examples/data/dummytest.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { msec: 0 } - Frame { msec: 10 } -} diff --git a/tests/auto/declarative/examples/data/webbrowser/webbrowser.qml b/tests/auto/declarative/examples/data/webbrowser/webbrowser.qml deleted file mode 100644 index d31787b939..0000000000 --- a/tests/auto/declarative/examples/data/webbrowser/webbrowser.qml +++ /dev/null @@ -1,6 +0,0 @@ -import Qt.VisualTest 4.6 - -VisualTest { - Frame { msec: 0 } - Frame { msec: 2000 } -} diff --git a/tests/auto/declarative/examples/examples.pro b/tests/auto/declarative/examples/examples.pro deleted file mode 100644 index d70040d6ec..0000000000 --- a/tests/auto/declarative/examples/examples.pro +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG += testcase -TARGET = tst_examples -macx:CONFIG -= app_bundle - -SOURCES += tst_examples.cpp -DEFINES += SRCDIR=\\\"$$PWD\\\" - -CONFIG += parallel_test -#temporary -QT += core-private gui-private declarative-private qtquick1-private widgets-private v8-private testlib diff --git a/tests/auto/declarative/examples/tst_examples.cpp b/tests/auto/declarative/examples/tst_examples.cpp deleted file mode 100644 index bacd25d0da..0000000000 --- a/tests/auto/declarative/examples/tst_examples.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class tst_examples : public QObject -{ - Q_OBJECT -public: - tst_examples(); - -private slots: - void sgexamples_data(); - void sgexamples(); - - void namingConvention(); -private: - QStringList excludedDirs; - QStringList excludedFiles; - - void namingConvention(const QDir &); - QStringList findQmlFiles(const QDir &); - - QDeclarativeEngine engine; -}; - -tst_examples::tst_examples() -{ - // Add files to exclude here - excludedFiles << "doc/src/snippets/declarative/listmodel.qml"; //Just a ListModel, no root QQuickItem - - // Add directories you want excluded here - excludedDirs << "examples/declarative/text/fonts"; // QTBUG-21415 - - // Not run in QQuickView - excludedDirs << "examples/declarative/qtquick1"; - - // These snippets are not expected to run on their own. - excludedDirs << "doc/src/snippets/declarative/visualdatamodel_rootindex"; - excludedDirs << "doc/src/snippets/declarative/qtbinding"; - excludedDirs << "doc/src/snippets/declarative/imports"; - excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex"; - excludedDirs << "doc/src/snippets/qtquick1/qtbinding"; - excludedDirs << "doc/src/snippets/qtquick1/imports"; - -#ifdef QT_NO_WEBKIT - excludedDirs << "examples/declarative/modelviews/webview"; - excludedDirs << "examples/declarative/webbrowser"; - excludedDirs << "doc/src/snippets/declarative/webview"; - excludedDirs << "doc/src/snippets/qtquick1/webview"; -#endif - -#ifdef QT_NO_XMLPATTERNS - excludedDirs << "examples/declarative/xml/xmldata"; - excludedDirs << "examples/declarative/twitter"; - excludedDirs << "examples/declarative/flickr"; - excludedDirs << "examples/declarative/photoviewer"; -#endif -} - -/* -This tests that the examples follow the naming convention required -to have them tested by the examples() test. -*/ -void tst_examples::namingConvention(const QDir &d) -{ - for (int ii = 0; ii < excludedDirs.count(); ++ii) { - QString s = excludedDirs.at(ii); - if (d.absolutePath().endsWith(s)) - return; - } - - QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"), - QDir::Files); - - bool seenQml = !files.isEmpty(); - bool seenLowercase = false; - - foreach (const QString &file, files) { - if (file.at(0).isLower()) - seenLowercase = true; - } - - if (!seenQml) { - QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | - QDir::NoSymLinks); - foreach (const QString &dir, dirs) { - QDir sub = d; - sub.cd(dir); - namingConvention(sub); - } - } else if(!seenLowercase) { - QFAIL(qPrintable(QString( - "Directory %1 violates naming convention; expected at least one qml file " - "starting with lower case, got: %2" - ).arg(d.absolutePath()).arg(files.join(",")))); - } -} - -void tst_examples::namingConvention() -{ - QString examples = QLibraryInfo::location(QLibraryInfo::ExamplesPath); - - namingConvention(QDir(examples)); -} - -QStringList tst_examples::findQmlFiles(const QDir &d) -{ - for (int ii = 0; ii < excludedDirs.count(); ++ii) { - QString s = excludedDirs.at(ii); - if (d.absolutePath().endsWith(s)) - return QStringList(); - } - - QStringList rv; - - QStringList cppfiles = d.entryList(QStringList() << QLatin1String("*.cpp"), QDir::Files); - if (cppfiles.isEmpty()) { - QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"), - QDir::Files); - foreach (const QString &file, files) { - if (file.at(0).isLower()) { - bool superContinue = false; - for (int ii = 0; ii < excludedFiles.count(); ++ii) { - QString e = excludedFiles.at(ii); - if (d.absoluteFilePath(file).endsWith(e)) { - superContinue = true; - break; - } - } - if (superContinue) - continue; - rv << d.absoluteFilePath(file); - } - } - } - - - QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | - QDir::NoSymLinks); - foreach (const QString &dir, dirs) { - QDir sub = d; - sub.cd(dir); - rv << findQmlFiles(sub); - } - - return rv; -} - -/* -This test runs all the examples in the declarative UI source tree and ensures -that they start and exit cleanly. - -Examples are any .qml files under the examples/ directory that start -with a lower case letter. -*/ -static void silentErrorsMsgHandler(QtMsgType, const char *) -{ -} - - -void tst_examples::sgexamples_data() -{ - QTest::addColumn("file"); - - QString examples = QLatin1String(SRCDIR) + "/../../../../examples/declarative/"; - QString snippets = QLatin1String(SRCDIR) + "/../../../../doc/src/snippets/declarative"; - - QStringList files; - files << findQmlFiles(QDir(examples)); - files << findQmlFiles(QDir(snippets)); - - foreach (const QString &file, files) - QTest::newRow(qPrintable(file)) << file; -} - -void tst_examples::sgexamples() -{ - QFETCH(QString, file); - - QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler); - qInstallMsgHandler(old); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(file)); - if (component.status() == QDeclarativeComponent::Error) - qWarning() << component.errors(); - QCOMPARE(component.status(), QDeclarativeComponent::Ready); - - QScopedPointer object(component.beginCreate(engine.rootContext())); - QQuickItem *root = qobject_cast(object.data()); - if (!root) - component.completeCreate(); - QVERIFY(root); - - QQuickCanvas canvas; - root->setParentItem(canvas.rootItem()); - component.completeCreate(); - canvas.show(); - - QTest::qWaitForWindowShown(&canvas); - -} - -QTEST_MAIN(tst_examples) - -#include "tst_examples.moc" diff --git a/tests/auto/declarative/geometry/geometry.pro b/tests/auto/declarative/geometry/geometry.pro deleted file mode 100644 index a66399a6e0..0000000000 --- a/tests/auto/declarative/geometry/geometry.pro +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG += testcase -TARGET = tst_geometry -macx:CONFIG -= app_bundle - -SOURCES += tst_geometry.cpp - -CONFIG+=parallel_test - -QT += core-private gui-private declarative-private opengl testlib diff --git a/tests/auto/declarative/geometry/tst_geometry.cpp b/tests/auto/declarative/geometry/tst_geometry.cpp deleted file mode 100644 index 2915902fa4..0000000000 --- a/tests/auto/declarative/geometry/tst_geometry.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt scene graph research project. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include - -class GeometryTest : public QObject -{ - Q_OBJECT - -public: - -private Q_SLOTS: - void testPoint2D(); - void testTexturedPoint2D(); - void testCustomGeometry(); - -private: -}; - -void GeometryTest::testPoint2D() -{ - QSGGeometry geometry(QSGGeometry::defaultAttributes_Point2D(), 4, 0); - - QCOMPARE(geometry.attributeCount(), 1); - QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 2); - QCOMPARE(geometry.vertexCount(), 4); - QCOMPARE(geometry.indexCount(), 0); - QVERIFY(geometry.indexData() == 0); - - QSGGeometry::updateRectGeometry(&geometry, QRectF(1, 2, 3, 4)); - - QSGGeometry::Point2D *pts = geometry.vertexDataAsPoint2D(); - QVERIFY(pts != 0); - - QCOMPARE(pts[0].x, (float) 1); - QCOMPARE(pts[0].y, (float) 2); - QCOMPARE(pts[3].x, (float) 4); - QCOMPARE(pts[3].y, (float) 6); - - // Verify that resize gives me enough allocated data without crashing... - geometry.allocate(100, 100); - pts = geometry.vertexDataAsPoint2D(); - quint16 *is = geometry.indexDataAsUShort(); - for (int i=0; i<100; ++i) { - pts[i].x = i; - pts[i].y = i + 100; - is[i] = i; - } - QVERIFY(true); -} - - -void GeometryTest::testTexturedPoint2D() -{ - QSGGeometry geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4, 0); - - QCOMPARE(geometry.attributeCount(), 2); - QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 4); - QCOMPARE(geometry.vertexCount(), 4); - QCOMPARE(geometry.indexCount(), 0); - QVERIFY(geometry.indexData() == 0); - - QSGGeometry::updateTexturedRectGeometry(&geometry, QRectF(1, 2, 3, 4), QRectF(5, 6, 7, 8)); - - QSGGeometry::TexturedPoint2D *pts = geometry.vertexDataAsTexturedPoint2D(); - QVERIFY(pts != 0); - - QCOMPARE(pts[0].x, (float) 1); - QCOMPARE(pts[0].y, (float) 2); - QCOMPARE(pts[0].tx, (float) 5); - QCOMPARE(pts[0].ty, (float) 6); - - QCOMPARE(pts[3].x, (float) 4); - QCOMPARE(pts[3].y, (float) 6); - QCOMPARE(pts[3].tx, (float) 12); - QCOMPARE(pts[3].ty, (float) 14); - - // Verify that resize gives me enough allocated data without crashing... - geometry.allocate(100, 100); - pts = geometry.vertexDataAsTexturedPoint2D(); - quint16 *is = geometry.indexDataAsUShort(); - for (int i=0; i<100; ++i) { - pts[i].x = i; - pts[i].y = i + 100; - pts[i].tx = i + 200; - pts[i].ty = i + 300; - is[i] = i; - } - QVERIFY(true); -} - -void GeometryTest::testCustomGeometry() -{ - struct V { - float x, y; - unsigned char r, g, b, a; - float v1, v2, v3, v4; - }; - - static QSGGeometry::Attribute attributes[] = { - { 0, 2, GL_FLOAT }, - { 1, 4, GL_UNSIGNED_BYTE }, - { 2, 4, GL_FLOAT }, - }; - static QSGGeometry::AttributeSet set = { 4, 6 * sizeof(float) + 4 * sizeof(unsigned char), attributes }; - - QSGGeometry geometry(set, 1000, 4000); - - // Verify that space has been allocated. - quint16 *ii = geometry.indexDataAsUShort(); - for (int i=0; i -#include - -#include -#include -#include - -#include -#include -class NodesTest : public QObject -{ - Q_OBJECT - -public: - NodesTest(); - -private Q_SLOTS: - void initTestCase(); - void cleanupTestCase() { - delete widget; - } - - // Root nodes - void propegate(); - void propegateWithMultipleRoots(); - void simulatedEffect_data(); - void simulatedEffect(); - - // Opacity nodes - void basicOpacityNode(); - void opacityPropegation(); - - // QSGNodeUpdater - void isBlockedCheck(); - -private: - QGLWidget *widget; - - QSGNodeUpdater updater; -}; - -void NodesTest::initTestCase() -{ - widget = new QGLWidget(); - widget->resize(100, 30); - widget->show(); -} - -class DummyRenderer : public QSGRenderer -{ -public: - DummyRenderer(QSGRootNode *root) - : QSGRenderer(QSGContext::createDefaultContext()) - , changedNode(0) - , changedFlags(0) - , renderCount(0) - { - setRootNode(root); - } - - void render() { - ++renderCount; - renderingOrder = ++globalRendereringOrder; - } - - void nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags) { - changedNode = node; - changedFlags = flags; - QSGRenderer::nodeChanged(node, flags); - } - - QSGNode *changedNode; - QSGNode::DirtyFlags changedFlags; - - int renderCount; - int renderingOrder; - static int globalRendereringOrder; -}; - -int DummyRenderer::globalRendereringOrder; - -NodesTest::NodesTest() -{ -} - - -void NodesTest::propegate() -{ - QSGRootNode root; - QSGNode child; child.setFlag(QSGNode::OwnedByParent, false); - root.appendChildNode(&child); - - DummyRenderer renderer(&root); - - child.markDirty(QSGNode::DirtyGeometry); - - QCOMPARE(&child, renderer.changedNode); - QCOMPARE((int) renderer.changedFlags, (int) QSGNode::DirtyGeometry); -} - - -void NodesTest::propegateWithMultipleRoots() -{ - QSGRootNode root1; - QSGNode child2; child2.setFlag(QSGNode::OwnedByParent, false); - QSGRootNode root3; root3.setFlag(QSGNode::OwnedByParent, false); - QSGNode child4; child4.setFlag(QSGNode::OwnedByParent, false); - - root1.appendChildNode(&child2); - child2.appendChildNode(&root3); - root3.appendChildNode(&child4); - - DummyRenderer ren1(&root1); - DummyRenderer ren2(&root3); - - child4.markDirty(QSGNode::DirtyGeometry); - - QCOMPARE(ren1.changedNode, &child4); - QCOMPARE(ren2.changedNode, &child4); - - QCOMPARE((int) ren1.changedFlags, (int) QSGNode::DirtyGeometry); - QCOMPARE((int) ren2.changedFlags, (int) QSGNode::DirtyGeometry); -} - - - -class SimulatedEffectRenderer : public DummyRenderer -{ -public: - SimulatedEffectRenderer(QSGRootNode *root, QSGBasicGeometryNode *c) - : DummyRenderer(root) - { - child = c; - } - - void render() { - matrix = child->matrix() ? *child->matrix() : QMatrix4x4(); - DummyRenderer::render(); - } - - QSGBasicGeometryNode *child; - QMatrix4x4 matrix; -}; - - -class PseudoEffectNode : public QSGNode { -public: - PseudoEffectNode(QSGRenderer *r) - : renderer(r) - { - setFlag(UsePreprocess); - } - - void preprocess() { - - if (renderer->rootNode()->parent()) { - // Mark the root dirty to build a clean state from the root and down - renderer->rootNode()->markDirty(QSGNode::DirtyForceUpdate); - } - - renderer->renderScene(); - - if (renderer->rootNode()->parent()) { - // Mark the parent of the root dirty to force the root and down to be updated. - renderer->rootNode()->parent()->markDirty(QSGNode::DirtyForceUpdate); - } - } - - QSGRenderer *renderer; -}; - -void NodesTest::simulatedEffect_data() -{ - QTest::addColumn("connected"); - - QTest::newRow("connected") << true; - QTest::newRow("disconnected") << false; -} - -void NodesTest::simulatedEffect() -{ - QFETCH(bool, connected); - - QSGRootNode root; - QSGRootNode source; - QSGTransformNode xform; - QSGSimpleRectNode geometry; - geometry.setRect(QRectF(0, 0, 1, 1)); - geometry.setColor(Qt::red); - - root.setFlag(QSGNode::OwnedByParent, false); - source.setFlag(QSGNode::OwnedByParent, false); - xform.setFlag(QSGNode::OwnedByParent, false); - geometry.setFlag(QSGNode::OwnedByParent, false); - - SimulatedEffectRenderer rootRenderer(&root, &geometry); - SimulatedEffectRenderer sourceRenderer(&source, &geometry); - - PseudoEffectNode effect(&sourceRenderer); - - /* - root Source is redirected into effect using the SimulatedEffectRenderer - / \ - xform effect - | - source - | - geometry - */ - - root.appendChildNode(&xform); - root.appendChildNode(&effect); - if (connected) - xform.appendChildNode(&source); - source.appendChildNode(&geometry); - QMatrix4x4 m; m.translate(1, 2, 3); - xform.setMatrix(m); - - // Clear all dirty states... - updater.updateStates(&root); - - rootRenderer.renderScene(); - - // compare that we got one render call to each - QCOMPARE(rootRenderer.renderCount, 1); - QCOMPARE(sourceRenderer.renderCount, 1); - QVERIFY(sourceRenderer.renderingOrder < rootRenderer.renderingOrder); - if (connected) // geometry is not rendered in this case, so skip it... - QCOMPARE(rootRenderer.matrix, xform.matrix()); - QCOMPARE(sourceRenderer.matrix, QMatrix4x4()); -} - -void NodesTest::basicOpacityNode() -{ - QSGOpacityNode n; - QCOMPARE(n.opacity(), 1.); - - n.setOpacity(0.5); - QCOMPARE(n.opacity(), 0.5); - - n.setOpacity(-1); - QCOMPARE(n.opacity(), 0.); - - n.setOpacity(2); - QCOMPARE(n.opacity(), 1.); -} - -void NodesTest::opacityPropegation() -{ - QSGRootNode root; - QSGOpacityNode *a = new QSGOpacityNode; - QSGOpacityNode *b = new QSGOpacityNode; - QSGOpacityNode *c = new QSGOpacityNode; - - QSGSimpleRectNode *geometry = new QSGSimpleRectNode; - geometry->setRect(0, 0, 100, 100); - - root.appendChildNode(a); - a->appendChildNode(b); - b->appendChildNode(c); - c->appendChildNode(geometry); - - a->setOpacity(0.9); - b->setOpacity(0.8); - c->setOpacity(0.7); - - updater.updateStates(&root); - - QCOMPARE(a->combinedOpacity(), 0.9); - QCOMPARE(b->combinedOpacity(), 0.9 * 0.8); - QCOMPARE(c->combinedOpacity(), 0.9 * 0.8 * 0.7); - QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.8 * 0.7); - - b->setOpacity(0.1); - updater.updateStates(&root); - - QCOMPARE(a->combinedOpacity(), 0.9); - QCOMPARE(b->combinedOpacity(), 0.9 * 0.1); - QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); - QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); - - b->setOpacity(0); - updater.updateStates(&root); - - QVERIFY(b->isSubtreeBlocked()); - - // Verify that geometry did not get updated as it is in a blocked - // subtree - QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); - QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); -} - -void NodesTest::isBlockedCheck() -{ - QSGRootNode root; - QSGOpacityNode *opacity = new QSGOpacityNode(); - QSGNode *node = new QSGNode(); - - root.appendChildNode(opacity); - opacity->appendChildNode(node); - - QSGNodeUpdater updater; - - opacity->setOpacity(0); - QVERIFY(updater.isNodeBlocked(node, &root)); - - opacity->setOpacity(1); - QVERIFY(!updater.isNodeBlocked(node, &root)); -} - -QTEST_MAIN(NodesTest); - -#include "tst_nodestest.moc" diff --git a/tests/auto/declarative/qdeclarativeanimations/data/Double.qml b/tests/auto/declarative/qdeclarativeanimations/data/Double.qml deleted file mode 100644 index 99ffca1d62..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/Double.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - property bool on: false - border.color: "#ffffff" - color: "green" - width: 50 - height: 50 - NumberAnimation on x { - objectName: "animation" - running: container.on; from: 0; to: 600; loops: Animation.Infinite; duration: 2000 - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/attached.qml b/tests/auto/declarative/qdeclarativeanimations/data/attached.qml deleted file mode 100644 index 9dcfcd8752..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/attached.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 180; height: 200; - - Component { - id: delegate - Rectangle { - id: wrapper - width: 180; height: 200 - color: "blue" - - states: State { - name: "otherState" - PropertyChanges { target: wrapper; color: "green" } - } - - transitions: Transition { - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } - ScriptAction { script: console.log(wrapper.ListView.delayRemove ? "on" : "off") } - } - - Component.onCompleted: { - console.log(ListView.delayRemove ? "on" : "off"); - wrapper.state = "otherState" - } - } - } - - ListView { - model: 1 - delegate: delegate - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badproperty1.qml b/tests/auto/declarative/qdeclarativeanimations/data/badproperty1.qml deleted file mode 100644 index 9634c2c169..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badproperty1.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - states: State { - name: "state1" - PropertyChanges { target: myRect; border.color: "blue" } - } - transitions: Transition { - ColorAnimation { target: myRect; to: "red"; property: "border.colr"; duration: 1000 } - } - Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badproperty2.qml b/tests/auto/declarative/qdeclarativeanimations/data/badproperty2.qml deleted file mode 100644 index c121172a99..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badproperty2.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - states: State { - name: "state1" - PropertyChanges { target: myRect; border.color: "blue" } - } - transitions: Transition { - ColorAnimation { target: myRect; to: "red"; property: "border"; duration: 1000 } - } - Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badtype1.qml b/tests/auto/declarative/qdeclarativeanimations/data/badtype1.qml deleted file mode 100644 index 43e1ec8572..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badtype1.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - Rectangle { - color: "red" - width: 50; height: 50 - x: 100; y: 100 - PropertyAnimation on x { from: "blue"; to: "green"; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badtype2.qml b/tests/auto/declarative/qdeclarativeanimations/data/badtype2.qml deleted file mode 100644 index 5341cb3d1c..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badtype2.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - Rectangle { - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { from: "blue"; to: "green"; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badtype3.qml b/tests/auto/declarative/qdeclarativeanimations/data/badtype3.qml deleted file mode 100644 index 182efa0840..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badtype3.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - Rectangle { - color: "red" - ColorAnimation on color { from: 10; to: 15; } - width: 50; height: 50 - x: 100; y: 100 - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/badtype4.qml b/tests/auto/declarative/qdeclarativeanimations/data/badtype4.qml deleted file mode 100644 index f091e2430f..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/badtype4.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - objectName: "MyRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - MouseArea { - anchors.fill: parent - onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; - } - } - states: State { - name: "state1" - PropertyChanges { target: myRect; x: 200; color: "blue" } - } - transitions: Transition { - //comment out each in turn to make sure each only animates the relevant property - ColorAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color - NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/disabledTransition.qml b/tests/auto/declarative/qdeclarativeanimations/data/disabledTransition.qml deleted file mode 100644 index 0fbafead8b..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/disabledTransition.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - enabled: false - NumberAnimation { targets: theRect; properties: "x" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml b/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml deleted file mode 100644 index c0c0c65e3f..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/dontAutoStart.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 600 - height: 400 - - Rectangle { - id: redRect - width: 100; height: 100 - color: Qt.rgba(1,0,0) - Behavior on x { - NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Animation.Infinite} - } - - } - -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dontStart.qml b/tests/auto/declarative/qdeclarativeanimations/data/dontStart.qml deleted file mode 100644 index 3eee0cfd35..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/dontStart.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 600 - height: 400 - - Rectangle { - id: redRect - width: 100; height: 100 - color: Qt.rgba(1,0,0) - SequentialAnimation on x { - running: false - NumberAnimation { objectName: "MyAnim"; running: true } - } - - } - -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dontStart2.qml b/tests/auto/declarative/qdeclarativeanimations/data/dontStart2.qml deleted file mode 100644 index e7b4164e4e..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/dontStart2.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 600 - height: 400 - - Rectangle { - id: redRect - width: 100; height: 100 - color: Qt.rgba(1,0,0) - - transitions: Transition { - SequentialAnimation { - NumberAnimation { id: myAnim; objectName: "MyAnim"; running: true } - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/dotproperty.qml b/tests/auto/declarative/qdeclarativeanimations/data/dotproperty.qml deleted file mode 100644 index e0e46dcef5..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/dotproperty.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - color: "red" - width: 50; height: 50 - x: 100; y: 100 - MouseArea { - anchors.fill: parent - onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; - } - } - states: State { - name: "state1" - PropertyChanges { target: myRect; border.color: "blue" } - } - transitions: Transition { - ColorAnimation { properties: "border.color"; duration: 1000 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml deleted file mode 100644 index 9ef3da20c0..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/doubleRegistrationBug.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - - Double { id: dub; on: parent.width < 800 } - Component.onCompleted: dub.on = false -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/mixedtype1.qml b/tests/auto/declarative/qdeclarativeanimations/data/mixedtype1.qml deleted file mode 100644 index 76129dd15e..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/mixedtype1.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - objectName: "MyRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - MouseArea { - anchors.fill: parent - onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; - } - } - states: State { - name: "state1" - PropertyChanges { target: myRect; x: 200; border.width: 10 } - } - transitions: Transition { - PropertyAnimation { properties: "x,border.width"; duration: 1000 } //x is real, border.width is int - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/mixedtype2.qml b/tests/auto/declarative/qdeclarativeanimations/data/mixedtype2.qml deleted file mode 100644 index 1a7166e3f3..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/mixedtype2.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 240 - height: 320 - Rectangle { - id: myRect - objectName: "MyRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - MouseArea { - anchors.fill: parent - onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; - } - } - states: State { - name: "state1" - PropertyChanges { target: myRect; x: 200; color: "blue" } - } - transitions: Transition { - PropertyAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/nonTransitionBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/nonTransitionBug.qml deleted file mode 100644 index 909c533e7b..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/nonTransitionBug.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 200 - height: 200 - - Rectangle { - id: mover - objectName: "mover" - } - - states: [ - State { - name: "free" - }, - State { - name: "left" - PropertyChanges { - restoreEntryValues: false - target: mover - x: 0 - } - } - ] - - transitions: Transition { - PropertyAnimation { properties: "x"; duration: 50 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation.qml deleted file mode 100644 index d2006a1c6a..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - Rectangle { - id: redRect - color: "red" - width: 100; height: 100 - x: 50; y: 50 - } - - PathAnimation { - target: redRect - duration: 100; - path: Path { - startX: 50; startY: 50 - PathCubic { - x: 300; y: 300 - - control1X: 300; control1Y: 50 - control2X: 50; control2Y: 300 - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation2.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation2.qml deleted file mode 100644 index 951c5b2e57..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimation2.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - Rectangle { - id: redRect - color: "red" - width: 100; height: 100 - x: 50; y: 50 - } - - PathAnimation { - target: redRect - duration: 100; - endRotation: 0 - orientationEntryInterval: .1 - orientationExitInterval: .1 - orientation: PathAnimation.RightFirst - path: Path { - startX: 50; startY: 50 - PathLine { x: 300; y: 300 } - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimationNoStart.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathAnimationNoStart.qml deleted file mode 100644 index be3501fabb..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathAnimationNoStart.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - Rectangle { - id: redRect - color: "red" - width: 100; height: 100 - x: 50; y: 50 - } - - PathAnimation { - target: redRect - duration: 100; - path: Path { - //no startX/Y defined (should automatically start from redRects pos) - PathCubic { - x: 300; y: 300 - - control1X: 300; control1Y: 50 - control2X: 50; control2Y: 300 - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolator.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolator.qml deleted file mode 100644 index 0104412d7c..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolator.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -PathInterpolator { - path: Path { - startX: 50; startY: 50 - PathCubic { - x: 300; y: 300 - - control1X: 300; control1Y: 50 - control2X: 50; control2Y: 300 - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml deleted file mode 100644 index 41366ef798..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathInterpolatorBack.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -PathInterpolator { - path: Path { - startX: 50; startY: 50 - PathLine { x: 50; y: 100 } - PathLine { x: 100; y: 100 } - PathLine { x: 100; y: 50 } - PathLine { x: 200; y: 50 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pathTransition.qml b/tests/auto/declarative/qdeclarativeanimations/data/pathTransition.qml deleted file mode 100644 index 55ffc33f95..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pathTransition.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 800 - height: 800 - - Rectangle { - id: redRect; objectName: "redRect" - color: "red" - width: 50; height: 50 - x: 500; y: 50 - } - - states: State { - name: "moved" - PropertyChanges { - target: redRect - x: 100; y: 700 - } - } - - transitions: Transition { - to: "moved"; reversible: true - PathAnimation { - id: pathAnim - target: redRect - duration: 300 - path: Path { - PathCurve { x: 100; y: 100 } - PathCurve { x: 200; y: 350 } - PathCurve { x: 600; y: 500 } - PathCurve {} - } - } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = parent.state == "moved" ? "" : "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pauseBindingBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/pauseBindingBug.qml deleted file mode 100644 index 359cda166f..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pauseBindingBug.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: rect - width: 200 - height: 200 - - property bool animating: false - property int value: 0 - - NumberAnimation on value { - objectName: "animation" - paused: !rect.animating - to: 100 - duration: 50 - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/pauseBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/pauseBug.qml deleted file mode 100644 index fa2c4be4ba..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/pauseBug.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -SequentialAnimation { - id: animation - running: true - ScriptAction { script: animation.paused = true } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/properties.qml b/tests/auto/declarative/qdeclarativeanimations/data/properties.qml deleted file mode 100644 index f0f730967c..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/properties.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { to: 200 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/properties2.qml b/tests/auto/declarative/qdeclarativeanimations/data/properties2.qml deleted file mode 100644 index 6b7f026e0b..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/properties2.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { targets: theRect; properties: "x"; to: 200; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/properties3.qml b/tests/auto/declarative/qdeclarativeanimations/data/properties3.qml deleted file mode 100644 index 5eb65496d4..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/properties3.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { target: theRect; property: "x"; to: 300; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/properties4.qml b/tests/auto/declarative/qdeclarativeanimations/data/properties4.qml deleted file mode 100644 index dfe8ad17e7..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/properties4.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { target: theRect; property: "y"; to: 200; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/properties5.qml b/tests/auto/declarative/qdeclarativeanimations/data/properties5.qml deleted file mode 100644 index 075fc9bc5a..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/properties5.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { targets: theRect; properties: "y"; to: 200; } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition.qml deleted file mode 100644 index 968c5f6285..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { targets: theRect; properties: "x" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition2.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition2.qml deleted file mode 100644 index f06165604a..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition2.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { target: theRect; property: "y"; to: 200 } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition3.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition3.qml deleted file mode 100644 index 7d3b3b9c6d..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition3.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { targets: theRect; properties: "y" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition4.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition4.qml deleted file mode 100644 index 1c31a79634..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition4.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { target: theRect; properties: "x" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition5.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition5.qml deleted file mode 100644 index a2ff746900..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition5.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { targets: theRect; property: "x" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition6.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition6.qml deleted file mode 100644 index d3db01efb0..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition6.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - NumberAnimation { targets: theItem; properties: "x" } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition7.qml b/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition7.qml deleted file mode 100644 index 98898de8ef..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/propertiesTransition7.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: theRect - objectName: "TheRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - } - - states: State { - name: "moved" - PropertyChanges { - target: theRect - x: 200 - } - } - transitions: Transition { - SpringAnimation { targets: theRect; properties: "x"; velocity: 10000 } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "moved" - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml deleted file mode 100644 index 633da4e17f..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/registrationBug.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: rect - width: 200 - height: 200 - - property bool animating: true - property int value: 0 - - NumberAnimation { - target: rect - property: "value" - running: rect.animating - to: 100 - duration: 50 - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/rotation.qml b/tests/auto/declarative/qdeclarativeanimations/data/rotation.qml deleted file mode 100644 index 4dc42a1bd2..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/rotation.qml +++ /dev/null @@ -1,48 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 600; height: 200 - - Row { - spacing: 5 - Rectangle { - id: rr - objectName: "rr" - color: "red" - width: 100; height: 100 - } - Rectangle { - id: rr2 - objectName: "rr2" - color: "red" - width: 100; height: 100 - } - Rectangle { - id: rr3 - objectName: "rr3" - color: "red" - width: 100; height: 100 - } - Rectangle { - id: rr4 - objectName: "rr4" - color: "red" - width: 100; height: 100 - } - } - - states: State { - name: "state1" - PropertyChanges { target: rr; rotation: 370 } - PropertyChanges { target: rr2; rotation: 370 } - PropertyChanges { target: rr3; rotation: 370 } - PropertyChanges { target: rr4; rotation: 370 } - } - - transitions: Transition { - RotationAnimation { target: rr; direction: RotationAnimation.Numerical; duration: 1000 } - RotationAnimation { target: rr2; direction: RotationAnimation.Clockwise; duration: 1000 } - RotationAnimation { target: rr3; direction: RotationAnimation.Counterclockwise; duration: 1000 } - RotationAnimation { target: rr4; direction: RotationAnimation.Shortest; duration: 1000 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/runningTrueBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/runningTrueBug.qml deleted file mode 100644 index bec6fab368..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/runningTrueBug.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 -Rectangle { - color: "skyblue" - width: 500 - height: 200 - Rectangle { - objectName: "cloud" - color: "white" - y: 50 - width: 100 - height: 100 - - SequentialAnimation on x { - loops: Animation.Infinite - running: true - NumberAnimation { - id: firstAnimation - from: 0 - to: 500 - duration: 5000 - } - NumberAnimation { - id: secondAnimation - from: -100 - to: 0 - duration: 1000 - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml b/tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml deleted file mode 100644 index 508693e0fc..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/transitionAssignmentBug.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - property bool nullObject - Component.onCompleted: nullObject = transitions.length > 0 && transitions[0] === null - - property list myTransitions: [Transition {}, Transition {}] - transitions: myTransitions -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/valuesource.qml b/tests/auto/declarative/qdeclarativeanimations/data/valuesource.qml deleted file mode 100644 index 7a636b4003..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/valuesource.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { id: anim; objectName: "MyAnim"; to: 200 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/data/valuesource2.qml b/tests/auto/declarative/qdeclarativeanimations/data/valuesource2.qml deleted file mode 100644 index 9788761ee8..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/data/valuesource2.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - color: "red" - width: 50; height: 50 - x: 100; y: 100 - NumberAnimation on x { id: anim; objectName: "MyAnim"; running: false; to: 200 } - } -} diff --git a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro deleted file mode 100644 index 5870d74ab2..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/qdeclarativeanimations.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativeanimations -SOURCES += tst_qdeclarativeanimations.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp deleted file mode 100644 index 515c8fa918..0000000000 --- a/tests/auto/declarative/qdeclarativeanimations/tst_qdeclarativeanimations.cpp +++ /dev/null @@ -1,1106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "../shared/util.h" - -class tst_qdeclarativeanimations : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativeanimations() {} - -private slots: - void initTestCase() { QDeclarativeEngine engine; } // ensure types are registered - - void simpleProperty(); - void simpleNumber(); - void simpleColor(); - void simpleRotation(); - void simplePath(); - void pathInterpolator(); - void pathInterpolatorBackwardJump(); - void pathWithNoStart(); - void alwaysRunToEnd(); - void complete(); - void resume(); - void dotProperty(); - void badTypes(); - void badProperties(); - void mixedTypes(); - void properties(); - void propertiesTransition(); - void pathTransition(); - void disabledTransition(); - void invalidDuration(); - void attached(); - void propertyValueSourceDefaultStart(); - void dontStart(); - void easingProperties(); - void rotation(); - void runningTrueBug(); - void nonTransitionBug(); - void registrationBug(); - void doubleRegistrationBug(); - void alwaysRunToEndRestartBug(); - void transitionAssignmentBug(); - void pauseBindingBug(); - void pauseBug(); -}; - -#define QTIMED_COMPARE(lhs, rhs) do { \ - for (int ii = 0; ii < 5; ++ii) { \ - if (lhs == rhs) \ - break; \ - QTest::qWait(50); \ - } \ - QCOMPARE(lhs, rhs); \ -} while (false) - -void tst_qdeclarativeanimations::simpleProperty() -{ - QQuickRectangle rect; - QDeclarativePropertyAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setTo(200); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "x"); - QVERIFY(animation.to().toReal() == 200.0); - animation.start(); - QVERIFY(animation.isRunning()); - QTest::qWait(animation.duration()); - QTIMED_COMPARE(rect.x(), 200.0); - - rect.setPos(QPointF(0,0)); - animation.start(); - animation.pause(); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.x(),100.0); -} - -void tst_qdeclarativeanimations::simpleNumber() -{ - QQuickRectangle rect; - QDeclarativeNumberAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setTo(200); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "x"); - QVERIFY(animation.to() == 200); - animation.start(); - QVERIFY(animation.isRunning()); - QTest::qWait(animation.duration()); - QTIMED_COMPARE(rect.x(), qreal(200)); - - rect.setX(0); - animation.start(); - animation.pause(); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.x(), qreal(100)); -} - -void tst_qdeclarativeanimations::simpleColor() -{ - QQuickRectangle rect; - QDeclarativeColorAnimation animation; - animation.setTarget(&rect); - animation.setProperty("color"); - animation.setTo(QColor("red")); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "color"); - QVERIFY(animation.to() == QColor("red")); - animation.start(); - QVERIFY(animation.isRunning()); - QTest::qWait(animation.duration()); - QTIMED_COMPARE(rect.color(), QColor("red")); - - rect.setColor(QColor("blue")); - animation.start(); - animation.pause(); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); - - rect.setColor(QColor("green")); - animation.setFrom(QColor("blue")); - QVERIFY(animation.from() == QColor("blue")); - animation.restart(); - QCOMPARE(rect.color(), QColor("blue")); - QVERIFY(animation.isRunning()); - animation.setCurrentTime(125); - QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); -} - -void tst_qdeclarativeanimations::simpleRotation() -{ - QQuickRectangle rect; - QDeclarativeRotationAnimation animation; - animation.setTarget(&rect); - animation.setProperty("rotation"); - animation.setTo(270); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "rotation"); - QVERIFY(animation.to() == 270); - QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical); - animation.start(); - QVERIFY(animation.isRunning()); - QTest::qWait(animation.duration()); - QTIMED_COMPARE(rect.rotation(), qreal(270)); - - rect.setRotation(0); - animation.start(); - animation.pause(); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.rotation(), qreal(135)); -} - -void tst_qdeclarativeanimations::simplePath() -{ - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *redRect = rect->findChild(); - QVERIFY(redRect); - QQuickPathAnimation *pathAnim = rect->findChild(); - QVERIFY(pathAnim); - - pathAnim->start(); - pathAnim->pause(); - - pathAnim->setCurrentTime(30); - QCOMPARE(redRect->x(), qreal(167)); - QCOMPARE(redRect->y(), qreal(104)); - - pathAnim->setCurrentTime(100); - QCOMPARE(redRect->x(), qreal(300)); - QCOMPARE(redRect->y(), qreal(300)); - - //verify animation runs to end - pathAnim->start(); - QCOMPARE(redRect->x(), qreal(50)); - QCOMPARE(redRect->y(), qreal(50)); - QTRY_COMPARE(redRect->x(), qreal(300)); - QCOMPARE(redRect->y(), qreal(300)); - - pathAnim->setOrientation(QQuickPathAnimation::RightFirst); - QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); - pathAnim->start(); - QTRY_VERIFY(redRect->rotation() != 0); - pathAnim->stop(); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *redRect = rect->findChild(); - QVERIFY(redRect); - QQuickPathAnimation *pathAnim = rect->findChild(); - QVERIFY(pathAnim); - - QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); - - pathAnim->start(); - pathAnim->pause(); - QCOMPARE(redRect->x(), qreal(50)); - QCOMPARE(redRect->y(), qreal(50)); - QCOMPARE(redRect->rotation(), qreal(-360)); - - pathAnim->setCurrentTime(50); - QCOMPARE(redRect->x(), qreal(175)); - QCOMPARE(redRect->y(), qreal(175)); - QCOMPARE(redRect->rotation(), qreal(-315)); - - pathAnim->setCurrentTime(100); - QCOMPARE(redRect->x(), qreal(300)); - QCOMPARE(redRect->y(), qreal(300)); - QCOMPARE(redRect->rotation(), qreal(0)); - } -} - -void tst_qdeclarativeanimations::pathInterpolator() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolator.qml"))); - QDeclarativePathInterpolator *interpolator = qobject_cast(c.create()); - QVERIFY(interpolator); - - QCOMPARE(interpolator->progress(), qreal(0)); - QCOMPARE(interpolator->x(), qreal(50)); - QCOMPARE(interpolator->y(), qreal(50)); - QCOMPARE(interpolator->angle(), qreal(0)); - - interpolator->setProgress(.5); - QCOMPARE(interpolator->progress(), qreal(.5)); - QCOMPARE(interpolator->x(), qreal(175)); - QCOMPARE(interpolator->y(), qreal(175)); - QCOMPARE(interpolator->angle(), qreal(270)); - - interpolator->setProgress(1); - QCOMPARE(interpolator->progress(), qreal(1)); - QCOMPARE(interpolator->x(), qreal(300)); - QCOMPARE(interpolator->y(), qreal(300)); - QCOMPARE(interpolator->angle(), qreal(0)); -} - -void tst_qdeclarativeanimations::pathInterpolatorBackwardJump() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolatorBack.qml"))); - QDeclarativePathInterpolator *interpolator = qobject_cast(c.create()); - QVERIFY(interpolator); - - QCOMPARE(interpolator->progress(), qreal(0)); - QCOMPARE(interpolator->x(), qreal(50)); - QCOMPARE(interpolator->y(), qreal(50)); - QCOMPARE(interpolator->angle(), qreal(270)); - - interpolator->setProgress(.5); - QCOMPARE(interpolator->progress(), qreal(.5)); - QCOMPARE(interpolator->x(), qreal(100)); - QCOMPARE(interpolator->y(), qreal(75)); - QCOMPARE(interpolator->angle(), qreal(90)); - - interpolator->setProgress(1); - QCOMPARE(interpolator->progress(), qreal(1)); - QCOMPARE(interpolator->x(), qreal(200)); - QCOMPARE(interpolator->y(), qreal(50)); - QCOMPARE(interpolator->angle(), qreal(0)); - - //make sure we don't get caught in infinite loop here - interpolator->setProgress(0); - QCOMPARE(interpolator->progress(), qreal(0)); - QCOMPARE(interpolator->x(), qreal(50)); - QCOMPARE(interpolator->y(), qreal(50)); - QCOMPARE(interpolator->angle(), qreal(270)); -} - -void tst_qdeclarativeanimations::pathWithNoStart() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimationNoStart.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *redRect = rect->findChild(); - QVERIFY(redRect); - QQuickPathAnimation *pathAnim = rect->findChild(); - QVERIFY(pathAnim); - - pathAnim->start(); - pathAnim->pause(); - QCOMPARE(redRect->x(), qreal(50)); - QCOMPARE(redRect->y(), qreal(50)); - - pathAnim->setCurrentTime(50); - QCOMPARE(redRect->x(), qreal(175)); - QCOMPARE(redRect->y(), qreal(175)); - - pathAnim->setCurrentTime(100); - QCOMPARE(redRect->x(), qreal(300)); - QCOMPARE(redRect->y(), qreal(300)); - - redRect->setX(100); - redRect->setY(100); - pathAnim->start(); - QCOMPARE(redRect->x(), qreal(100)); - QCOMPARE(redRect->y(), qreal(100)); - QTRY_COMPARE(redRect->x(), qreal(300)); - QCOMPARE(redRect->y(), qreal(300)); -} - -void tst_qdeclarativeanimations::alwaysRunToEnd() -{ - QQuickRectangle rect; - QDeclarativePropertyAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setTo(200); - animation.setDuration(1000); - animation.setLoops(-1); - animation.setAlwaysRunToEnd(true); - QVERIFY(animation.loops() == -1); - QVERIFY(animation.alwaysRunToEnd() == true); - animation.start(); - QTest::qWait(1500); - animation.stop(); - QVERIFY(rect.x() != qreal(200)); - QTest::qWait(500); - QTIMED_COMPARE(rect.x(), qreal(200)); -} - -void tst_qdeclarativeanimations::complete() -{ - QQuickRectangle rect; - QDeclarativePropertyAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setFrom(1); - animation.setTo(200); - animation.setDuration(500); - QVERIFY(animation.from() == 1); - animation.start(); - QTest::qWait(50); - animation.stop(); - QVERIFY(rect.x() != qreal(200)); - animation.start(); - QTest::qWait(50); - QVERIFY(animation.isRunning()); - animation.complete(); - QCOMPARE(rect.x(), qreal(200)); -} - -void tst_qdeclarativeanimations::resume() -{ - QQuickRectangle rect; - QDeclarativePropertyAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setFrom(10); - animation.setTo(200); - animation.setDuration(1000); - QVERIFY(animation.from() == 10); - - animation.start(); - QTest::qWait(400); - animation.pause(); - qreal x = rect.x(); - QVERIFY(x != qreal(200) && x != qreal(10)); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - - animation.resume(); - QVERIFY(animation.isRunning()); - QVERIFY(!animation.isPaused()); - QTest::qWait(400); - animation.stop(); - QVERIFY(rect.x() > x); -} - -void tst_qdeclarativeanimations::dotProperty() -{ - QQuickRectangle rect; - QDeclarativeNumberAnimation animation; - animation.setTarget(&rect); - animation.setProperty("border.width"); - animation.setTo(10); - animation.start(); - QTest::qWait(animation.duration()+50); - QTIMED_COMPARE(rect.border()->width(), 10.0); - - rect.border()->setWidth(0); - animation.start(); - animation.pause(); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.border()->width(), 5.0); -} - -void tst_qdeclarativeanimations::badTypes() -{ - //don't crash - { - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("badtype1.qml"))); - - qApp->processEvents(); - - delete view; - } - - //make sure we get a compiler error - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype2.qml"))); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); - c.create(); - - QVERIFY(c.errors().count() == 1); - QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected")); - } - - //make sure we get a compiler error - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype3.qml"))); - QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); - c.create(); - - QVERIFY(c.errors().count() == 1); - QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected")); - } - - //don't crash - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype4.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("state1"); - QTest::qWait(1000 + 50); - QQuickRectangle *myRect = rect->findChild("MyRect"); - QVERIFY(myRect); - QCOMPARE(myRect->x(),qreal(200)); - } -} - -void tst_qdeclarativeanimations::badProperties() -{ - //make sure we get a runtime error - { - QDeclarativeEngine engine; - - QDeclarativeComponent c1(&engine, QUrl::fromLocalFile(TESTDATA("badproperty1.qml"))); - QByteArray message = QUrl::fromLocalFile(TESTDATA("badproperty1.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\""; - QTest::ignoreMessage(QtWarningMsg, message); - QQuickRectangle *rect = qobject_cast(c1.create()); - QVERIFY(rect); - - QDeclarativeComponent c2(&engine, QUrl::fromLocalFile(TESTDATA("badproperty2.qml"))); - message = QUrl::fromLocalFile(TESTDATA("badproperty2.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\""; - QTest::ignoreMessage(QtWarningMsg, message); - rect = qobject_cast(c2.create()); - QVERIFY(rect); - - //### should we warn here are well? - //rect->setState("state1"); - } -} - -//test animating mixed types with property animation in a transition -//for example, int + real; color + real; etc -void tst_qdeclarativeanimations::mixedTypes() -{ - //assumes border.width stays a real -- not real robust - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype1.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("state1"); - QTest::qWait(500); - QQuickRectangle *myRect = rect->findChild("MyRect"); - QVERIFY(myRect); - - //rather inexact -- is there a better way? - QVERIFY(myRect->x() > 100 && myRect->x() < 200); - QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("state1"); - QTest::qWait(500); - QQuickRectangle *myRect = rect->findChild("MyRect"); - QVERIFY(myRect); - - //rather inexact -- is there a better way? - QVERIFY(myRect->x() > 100 && myRect->x() < 200); - QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue")); - } -} - -void tst_qdeclarativeanimations::properties() -{ - const int waitDuration = 300; - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties3.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(300)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties4.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->y(),qreal(200)); - QTIMED_COMPARE(myRect->x(),qreal(100)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties5.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(100)); - QTIMED_COMPARE(myRect->y(),qreal(200)); - } -} - -void tst_qdeclarativeanimations::propertiesTransition() -{ - const int waitDuration = 300; - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(200)); - QCOMPARE(myRect->y(),qreal(100)); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->y(),qreal(200)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition3.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(200)); - QCOMPARE(myRect->y(),qreal(100)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition4.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(100)); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition5.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(100)); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - - /*{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition6.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(100)); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(100)); - }*/ - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition7.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - QTest::qWait(waitDuration); - QTIMED_COMPARE(myRect->x(),qreal(200)); - } - -} - -void tst_qdeclarativeanimations::pathTransition() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathTransition.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("redRect"); - QVERIFY(myRect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started - QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700))); - QTest::qWait(100); - - QQuickItemPrivate::get(rect)->setState(""); - QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started - QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50))); -} - -void tst_qdeclarativeanimations::disabledTransition() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabledTransition.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *myRect = rect->findChild("TheRect"); - QVERIFY(myRect); - - QDeclarativeTransition *trans = rect->findChild(); - QVERIFY(trans); - - QCOMPARE(trans->enabled(), false); - - QQuickItemPrivate::get(rect)->setState("moved"); - QCOMPARE(myRect->x(),qreal(200)); - - trans->setEnabled(true); - - QQuickItemPrivate::get(rect)->setState(""); - QCOMPARE(myRect->x(),qreal(200)); - QTest::qWait(300); - QTIMED_COMPARE(myRect->x(),qreal(100)); -} - -void tst_qdeclarativeanimations::invalidDuration() -{ - QDeclarativePropertyAnimation *animation = new QDeclarativePropertyAnimation; - QTest::ignoreMessage(QtWarningMsg, ": QML PropertyAnimation: Cannot set a duration of < 0"); - animation->setDuration(-1); - QCOMPARE(animation->duration(), 250); - - QDeclarativePauseAnimation *pauseAnimation = new QDeclarativePauseAnimation; - QTest::ignoreMessage(QtWarningMsg, ": QML PauseAnimation: Cannot set a duration of < 0"); - pauseAnimation->setDuration(-1); - QCOMPARE(pauseAnimation->duration(), 250); -} - -void tst_qdeclarativeanimations::attached() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml"))); - QTest::ignoreMessage(QtDebugMsg, "off"); - QTest::ignoreMessage(QtDebugMsg, "on"); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); -} - -void tst_qdeclarativeanimations::propertyValueSourceDefaultStart() -{ - { - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource.qml"))); - - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim); - QVERIFY(myAnim->isRunning()); - } - - { - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource2.qml"))); - - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim); - QVERIFY(myAnim->isRunning() == false); - } - - { - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontAutoStart.qml"))); - - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim && myAnim->qtAnimation()); - QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); - } -} - - -void tst_qdeclarativeanimations::dontStart() -{ - { - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml"))); - - QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim && myAnim->qtAnimation()); - QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); - } - - { - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart2.qml"))); - - QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim && myAnim->qtAnimation()); - QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); - } -} - -void tst_qdeclarativeanimations::easingProperties() -{ - { - QDeclarativeEngine engine; - QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }"; - QDeclarativeComponent animationComponent(&engine); - animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); - - QVERIFY(animObject != 0); - QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad); - } - - { - QDeclarativeEngine engine; - QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }"; - QDeclarativeComponent animationComponent(&engine); - animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); - - QVERIFY(animObject != 0); - QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce); - QCOMPARE(animObject->easing().amplitude(), 5.0); - } - - { - QDeclarativeEngine engine; - QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}"; - QDeclarativeComponent animationComponent(&engine); - animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); - - QVERIFY(animObject != 0); - QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic); - QCOMPARE(animObject->easing().amplitude(), 5.0); - QCOMPARE(animObject->easing().period(), 3.0); - } - - { - QDeclarativeEngine engine; - QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }"; - QDeclarativeComponent animationComponent(&engine); - animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); - - QVERIFY(animObject != 0); - QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack); - QCOMPARE(animObject->easing().overshoot(), 2.0); - } -} - -void tst_qdeclarativeanimations::rotation() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("rotation.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *rr = rect->findChild("rr"); - QQuickRectangle *rr2 = rect->findChild("rr2"); - QQuickRectangle *rr3 = rect->findChild("rr3"); - QQuickRectangle *rr4 = rect->findChild("rr4"); - - QQuickItemPrivate::get(rect)->setState("state1"); - QTest::qWait(800); - qreal r1 = rr->rotation(); - qreal r2 = rr2->rotation(); - qreal r3 = rr3->rotation(); - qreal r4 = rr4->rotation(); - - QVERIFY(r1 > qreal(0) && r1 < qreal(370)); - QVERIFY(r2 > qreal(0) && r2 < qreal(370)); - QVERIFY(r3 < qreal(0) && r3 > qreal(-350)); - QVERIFY(r4 > qreal(0) && r4 < qreal(10)); - QCOMPARE(r1,r2); - QVERIFY(r4 < r2); - - QTest::qWait(800); - QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4)); -} - -void tst_qdeclarativeanimations::runningTrueBug() -{ - //ensure we start correctly when "running: true" is explicitly set - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrueBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *cloud = rect->findChild("cloud"); - QVERIFY(cloud); - QTest::qWait(1000); - QVERIFY(cloud->x() > qreal(0)); -} - -//QTBUG-12805 -void tst_qdeclarativeanimations::nonTransitionBug() -{ - //tests that the animation values from the previous transition are properly cleared - //in the case where an animation in the transition doesn't match anything (but previously did) - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonTransitionBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QQuickRectangle *mover = rect->findChild("mover"); - - mover->setX(100); - QCOMPARE(mover->x(), qreal(100)); - - rectPrivate->setState("left"); - QTRY_COMPARE(mover->x(), qreal(0)); - - mover->setX(100); - QCOMPARE(mover->x(), qreal(100)); - - //make sure we don't try to animate back to 0 - rectPrivate->setState("free"); - QTest::qWait(300); - QCOMPARE(mover->x(), qreal(100)); -} - -//QTBUG-14042 -void tst_qdeclarativeanimations::registrationBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("registrationBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QTRY_COMPARE(rect->property("value"), QVariant(int(100))); -} - -void tst_qdeclarativeanimations::doubleRegistrationBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("doubleRegistrationBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QDeclarativeAbstractAnimation *anim = rect->findChild("animation"); - QVERIFY(anim != 0); - QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped); -} - -//QTBUG-16736 -void tst_qdeclarativeanimations::alwaysRunToEndRestartBug() -{ - QQuickRectangle rect; - QDeclarativePropertyAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setTo(200); - animation.setDuration(1000); - animation.setLoops(-1); - animation.setAlwaysRunToEnd(true); - QVERIFY(animation.loops() == -1); - QVERIFY(animation.alwaysRunToEnd() == true); - animation.start(); - animation.stop(); - animation.start(); - animation.stop(); - QTest::qWait(500); - QVERIFY(rect.x() != qreal(200)); - QTest::qWait(800); - QTIMED_COMPARE(rect.x(), qreal(200)); - QCOMPARE(static_cast(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped); -} - -//QTBUG-20227 -void tst_qdeclarativeanimations::transitionAssignmentBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("transitionAssignmentBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QCOMPARE(rect->property("nullObject").toBool(), false); -} - -//QTBUG-19080 -void tst_qdeclarativeanimations::pauseBindingBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBindingBug.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QDeclarativeAbstractAnimation *anim = rect->findChild("animation"); - QVERIFY(anim->qtAnimation()->state() == QAbstractAnimation::Paused); - - delete rect; -} - -//QTBUG-13598 -void tst_qdeclarativeanimations::pauseBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBug.qml"))); - QDeclarativeAbstractAnimation *anim = qobject_cast(c.create()); - QVERIFY(anim != 0); - QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Paused); - QCOMPARE(anim->isPaused(), true); - QCOMPARE(anim->isRunning(), true); - - delete anim; -} - -QTEST_MAIN(tst_qdeclarativeanimations) - -#include "tst_qdeclarativeanimations.moc" diff --git a/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro b/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro deleted file mode 100644 index 3b01fcf9e3..0000000000 --- a/tests/auto/declarative/qdeclarativeapplication/qdeclarativeapplication.pro +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativeapplication -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativeapplication.cpp -QT += core-private gui-private declarative-private testlib - diff --git a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp deleted file mode 100644 index 72313ab054..0000000000 --- a/tests/auto/declarative/qdeclarativeapplication/tst_qdeclarativeapplication.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -class tst_qdeclarativeapplication : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativeapplication(); - -private slots: - void active(); - void layoutDirection(); - void inputPanel(); - -private: - QDeclarativeEngine engine; -}; - -tst_qdeclarativeapplication::tst_qdeclarativeapplication() -{ -} - -void tst_qdeclarativeapplication::active() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - QQuickView view; - item->setParentItem(view.rootObject()); - - // not active - QVERIFY(!item->property("active").toBool()); - QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); - - // active - view.show(); - view.requestActivateWindow(); - QTest::qWait(50); - QEXPECT_FAIL("", "QTBUG-21573", Abort); - QTRY_COMPARE(view.status(), QQuickView::Ready); - QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); - -#if 0 - // QGuiApplication has no equivalent of setActiveWindow(0). QTBUG-21573 - // Is this different to clearing the active state of the window or can it be removed? - // On Mac, setActiveWindow(0) on mac does not deactivate the current application, - // must switch to a different app or hide the current app to trigger this - // on mac, setActiveWindow(0) on mac does not deactivate the current application - // (you have to switch to a different app or hide the current app to trigger this) - - // not active again - QGuiApplication::setActiveWindow(0); - QVERIFY(!item->property("active").toBool()); - QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); -#endif - -} - -void tst_qdeclarativeapplication::layoutDirection() -{ - - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - QQuickView view; - item->setParentItem(view.rootObject()); - - // not mirrored - QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); - - // mirrored - QGuiApplication::setLayoutDirection(Qt::RightToLeft); - QEXPECT_FAIL("", "QTBUG-21573", Abort); - QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft); - - // not mirrored again - QGuiApplication::setLayoutDirection(Qt::LeftToRight); - QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); -} - -void tst_qdeclarativeapplication::inputPanel() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Item { property variant inputPanel: Qt.application.inputPanel }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - QQuickView view; - item->setParentItem(view.rootObject()); - - // check that the inputPanel property maches with application's input panel - QCOMPARE(qvariant_cast(item->property("inputPanel")), qApp->inputPanel()); -} - -QTEST_MAIN(tst_qdeclarativeapplication) - -#include "tst_qdeclarativeapplication.moc" diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/binding.qml b/tests/auto/declarative/qdeclarativebehaviors/data/binding.qml deleted file mode 100644 index 5aceefa743..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/binding.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - property real basex : 0 - property real movedx: 200 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - x: basex - Behavior on x { NumberAnimation { duration: 800; } } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: movedx - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/color.qml b/tests/auto/declarative/qdeclarativebehaviors/data/color.qml deleted file mode 100644 index a318578a9b..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/color.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; - color: "green" - Behavior on color { ColorAnimation { duration: 500; } } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "red" - when: clicker.pressed - PropertyChanges { - target: rect - color: "red" - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/cpptrigger.qml b/tests/auto/declarative/qdeclarativebehaviors/data/cpptrigger.qml deleted file mode 100644 index f033ec5aeb..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/cpptrigger.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { NumberAnimation { duration: 500; } } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml b/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml deleted file mode 100644 index ed35a308f7..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/delayedRegistration.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - - width: 400; height: 400; - property Item myItem - - function doCreate() { - myItem = myComponent.createObject(container) - myItem.x = 100 - } - - Component { - id: myComponent - Rectangle { - width: 100 - height: 100 - color: "green" - Behavior on x { NumberAnimation { duration: 500 } } - } - } - - Component.onCompleted: doCreate() -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/disabled.qml b/tests/auto/declarative/qdeclarativebehaviors/data/disabled.qml deleted file mode 100644 index 20860d8dde..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/disabled.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { - objectName: "MyBehavior"; - enabled: false - NumberAnimation { duration: 200; } - } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml b/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml deleted file mode 100644 index 38e1ea9d9e..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/dontStart.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: wrapper - width: 600 - height: 400 - - Rectangle { - id: redRect - width: 100; height: 100 - color: Qt.rgba(1,0,0) - Behavior on x { - NumberAnimation {id: myAnim; objectName: "MyAnim"; running: true } - } - - } - -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/empty.qml b/tests/auto/declarative/qdeclarativebehaviors/data/empty.qml deleted file mode 100644 index d8f115390a..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/empty.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x {} - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/explicit.qml b/tests/auto/declarative/qdeclarativebehaviors/data/explicit.qml deleted file mode 100644 index 20875c30e3..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/explicit.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { - objectName: "MyBehavior"; - NumberAnimation { target: rect; property: "x"; duration: 500; } - } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty.qml b/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty.qml deleted file mode 100644 index a05ab7d54b..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on pos { PropertyAnimation { duration: 500; } } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - pos: Qt.point(200,0); - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty2.qml b/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty2.qml deleted file mode 100644 index 2f3de5131c..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/groupProperty2.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on border.width { NumberAnimation { duration: 500; } } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - border.width: 4; - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml b/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml deleted file mode 100644 index 6835902bc5..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/groupedPropertyCrash.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 200 - Text { - Behavior on anchors.verticalCenterOffset { NumberAnimation { duration: 300; } } - text: "Hello World" - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/loop.qml b/tests/auto/declarative/qdeclarativebehaviors/data/loop.qml deleted file mode 100644 index 3e8d88734d..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/loop.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { NumberAnimation { duration: 200; } } - onXChanged: x = 100; - } - states: State { - name: "moved" - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/nonSelecting2.qml b/tests/auto/declarative/qdeclarativebehaviors/data/nonSelecting2.qml deleted file mode 100644 index 6357094cfe..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/nonSelecting2.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { - objectName: "MyBehavior"; - NumberAnimation { targets: rect; properties: "y"; duration: 200; } - } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/parent.qml b/tests/auto/declarative/qdeclarativebehaviors/data/parent.qml deleted file mode 100644 index f8c2731d86..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/parent.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on parent { - SequentialAnimation { - PauseAnimation { duration: 500 } - PropertyAction {} - } - } - } - Item { - id: newParent - objectName: "NewParent" - x: 100 - } - states: State { - name: "reparented" - PropertyChanges { - target: rect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml b/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml deleted file mode 100644 index c6bef581a4..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/qtbug12295.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 200 - color: "blue" - - Rectangle { - id: myRect - objectName: "myRect" - width: 100 - height: 100 - Behavior on x { - NumberAnimation { duration: 500 } - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml b/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml deleted file mode 100644 index 5731cb3efd..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/reassignedAnimation.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { - id: myBehavior - objectName: "MyBehavior" - NumberAnimation {id: na1; duration: 200 } - } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } - - NumberAnimation {id: na2; duration: 1000 } - Component.onCompleted: { - myBehavior.animation = na2; - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/runningTrue.qml b/tests/auto/declarative/qdeclarativebehaviors/data/runningTrue.qml deleted file mode 100644 index 4fd1136f3a..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/runningTrue.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width:200; height:200 - - property real myValue: 0 - - Rectangle { - anchors.centerIn: parent - width: 100 - height: 100 - color: "green" - smooth: true - rotation: myValue - Behavior on rotation { - RotationAnimation { id: rotAnim; objectName: "rotAnim"; direction: RotationAnimation.Shortest } - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/scripttrigger.qml b/tests/auto/declarative/qdeclarativebehaviors/data/scripttrigger.qml deleted file mode 100644 index ff71f2b1b0..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/scripttrigger.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - - onColorChanged: { - rect.x = 200 - } - - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { NumberAnimation { duration: 800; } } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml b/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml deleted file mode 100644 index c64a6e1928..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/simple.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - Rectangle { - id: rect - objectName: "MyRect" - width: 100; height: 100; color: "green" - Behavior on x { - objectName: "MyBehavior"; - NumberAnimation {id: na; duration: 500; } - } - } - MouseArea { - id: clicker - anchors.fill: parent - } - states: State { - name: "moved" - when: clicker.pressed - PropertyChanges { - target: rect - x: 200 - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml b/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml deleted file mode 100644 index fdc3779a5c..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/startOnCompleted.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - Rectangle { - id: innerRect - width: 100; height: 100 - color: "green" - Behavior on x { NumberAnimation {} } - } - - Component.onCompleted: innerRect.x = 100 -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/startup.qml b/tests/auto/declarative/qdeclarativebehaviors/data/startup.qml deleted file mode 100644 index 9fa74ca39e..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/startup.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - Rectangle { - objectName: "innerRect" - height: 100; width: 100; color: "green" - property real targetX: 100 - - x: targetX - Behavior on x { - NumberAnimation {} - } - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/startup2.qml b/tests/auto/declarative/qdeclarativebehaviors/data/startup2.qml deleted file mode 100644 index 0654ef3644..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/startup2.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 800; - height: 480; - - Text { id:theText; text: "hello world" } - - Rectangle { - objectName: "innerRect" - color: "red" - x: theText.width - Behavior on x { NumberAnimation {} } - width: 100; height: 100 - } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml b/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml deleted file mode 100644 index 7bc8297dc7..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/data/valueType.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - - color.r: 1 - color.g: 0 - color.b: 1 - - Behavior on color.r { NumberAnimation { duration: 500; } } - - function changeR() { color.r = 0 } -} diff --git a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro deleted file mode 100644 index 0e7c73ab90..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/qdeclarativebehaviors.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativebehaviors -SOURCES += tst_qdeclarativebehaviors.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp deleted file mode 100644 index d1c1ca7d9c..0000000000 --- a/tests/auto/declarative/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp +++ /dev/null @@ -1,474 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qdeclarativebehaviors : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativebehaviors() {} - -private slots: - void init() { qApp->processEvents(); } //work around animation timer bug (QTBUG-22865) - void simpleBehavior(); - void scriptTriggered(); - void cppTriggered(); - void loop(); - void colorBehavior(); - void parentBehavior(); - void replaceBinding(); - //void transitionOverrides(); - void group(); - void valueType(); - void emptyBehavior(); - void explicitSelection(); - void nonSelectingBehavior(); - void reassignedAnimation(); - void disabled(); - void dontStart(); - void startup(); - void groupedPropertyCrash(); - void runningTrue(); - void sameValue(); - void delayedRegistration(); - void startOnCompleted(); -}; - -void tst_qdeclarativebehaviors::simpleBehavior() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("simple.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - QTRY_VERIFY(qobject_cast(rect->findChild("MyBehavior"))->animation()); - - QQuickItemPrivate::get(rect)->setState("moved"); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); - //i.e. the behavior has been triggered - - delete rect; -} - -void tst_qdeclarativebehaviors::scriptTriggered() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("scripttrigger.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - rect->setColor(QColor("red")); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); - //i.e. the behavior has been triggered - - delete rect; -} - -void tst_qdeclarativebehaviors::cppTriggered() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("cpptrigger.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QTRY_VERIFY(innerRect); - - innerRect->setProperty("x", 200); - QTRY_VERIFY(innerRect->x() > 0); - QTRY_VERIFY(innerRect->x() < 200); //i.e. the behavior has been triggered - - delete rect; -} - -void tst_qdeclarativebehaviors::loop() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("loop.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - //don't crash - QQuickItemPrivate::get(rect)->setState("moved"); - - delete rect; -} - -void tst_qdeclarativebehaviors::colorBehavior() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("color.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("red"); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->color() != QColor("red")); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->color() != QColor("green")); - //i.e. the behavior has been triggered - - delete rect; -} - -void tst_qdeclarativebehaviors::parentBehavior() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("parent.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("reparented"); - QTRY_VERIFY(rect->findChild("MyRect")->parentItem() != rect->findChild("NewParent")); - QTRY_VERIFY(rect->findChild("MyRect")->parentItem() == rect->findChild("NewParent")); - - delete rect; -} - -void tst_qdeclarativebehaviors::replaceBinding() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("binding.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QTRY_VERIFY(innerRect); - QTRY_VERIFY(innerRect->x() > 0); - QTRY_VERIFY(innerRect->x() < 200); - //i.e. the behavior has been triggered - QTRY_COMPARE(innerRect->x(), (qreal)200); - rect->setProperty("basex", 10); - QTRY_COMPARE(innerRect->x(), (qreal)200); - rect->setProperty("movedx", 210); - QTRY_COMPARE(innerRect->x(), (qreal)210); - - QQuickItemPrivate::get(rect)->setState(""); - QTRY_VERIFY(innerRect->x() > 10); - QTRY_VERIFY(innerRect->x() < 210); //i.e. the behavior has been triggered - QTRY_COMPARE(innerRect->x(), (qreal)10); - rect->setProperty("movedx", 200); - QTRY_COMPARE(innerRect->x(), (qreal)10); - rect->setProperty("basex", 20); - QTRY_COMPARE(innerRect->x(), (qreal)20); - - delete rect; -} - -void tst_qdeclarativebehaviors::group() -{ - /* XXX TODO Create a test element for this case. - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - qDebug() << c.errorString(); - QTRY_VERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - //QTest::qWait(200); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); - //i.e. the behavior has been triggered - - delete rect; - } - */ - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QTRY_VERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->border()->width() > 0); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->border()->width() < 4); - //i.e. the behavior has been triggered - - delete rect; - } -} - -void tst_qdeclarativebehaviors::valueType() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valueType.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - //QTBUG-20827 - QCOMPARE(rect->color(), QColor::fromRgb(255,0,255)); - - delete rect; -} - -void tst_qdeclarativebehaviors::emptyBehavior() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("empty.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - qreal x = qobject_cast(rect->findChild("MyRect"))->x(); - QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; -} - -void tst_qdeclarativebehaviors::explicitSelection() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("explicit.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); - QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); - //i.e. the behavior has been triggered - - delete rect; -} - -void tst_qdeclarativebehaviors::nonSelectingBehavior() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonSelecting2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickItemPrivate::get(rect)->setState("moved"); - qreal x = qobject_cast(rect->findChild("MyRect"))->x(); - QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; -} - -void tst_qdeclarativebehaviors::reassignedAnimation() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml"))); - QString warning = QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml")).toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior."; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - QCOMPARE(qobject_cast( - rect->findChild("MyBehavior")->animation())->duration(), 200); - - delete rect; -} - -void tst_qdeclarativebehaviors::disabled() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabled.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - QCOMPARE(rect->findChild("MyBehavior")->enabled(), false); - - QQuickItemPrivate::get(rect)->setState("moved"); - qreal x = qobject_cast(rect->findChild("MyRect"))->x(); - QCOMPARE(x, qreal(200)); //should change immediately - - delete rect; -} - -void tst_qdeclarativebehaviors::dontStart() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml"))); - - QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); - QVERIFY(myAnim && myAnim->qtAnimation()); - QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); - - delete rect; -} - -void tst_qdeclarativebehaviors::startup() -{ - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *innerRect = rect->findChild("innerRect"); - QVERIFY(innerRect); - - QCOMPARE(innerRect->x(), qreal(100)); //should be set immediately - - delete rect; - } - - { - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup2.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *innerRect = rect->findChild("innerRect"); - QVERIFY(innerRect); - - QQuickText *text = rect->findChild(); - QVERIFY(text); - - QCOMPARE(innerRect->x(), text->width()); //should be set immediately - - delete rect; - } -} - -//QTBUG-10799 -void tst_qdeclarativebehaviors::groupedPropertyCrash() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupedPropertyCrash.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); //don't crash - - delete rect; -} - -//QTBUG-5491 -void tst_qdeclarativebehaviors::runningTrue() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrue.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QDeclarativeAbstractAnimation *animation = rect->findChild("rotAnim"); - QVERIFY(animation); - - QSignalSpy runningSpy(animation, SIGNAL(runningChanged(bool))); - rect->setProperty("myValue", 180); - QTRY_VERIFY(runningSpy.count() > 0); - - delete rect; -} - -//QTBUG-12295 -void tst_qdeclarativebehaviors::sameValue() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("qtbug12295.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *target = rect->findChild("myRect"); - QVERIFY(target); - - target->setX(100); - QCOMPARE(target->x(), qreal(100)); - - target->setProperty("x", 0); - QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); - QTRY_VERIFY(target->x() == qreal(0)); //make sure Behavior has finished. - - target->setX(100); - QCOMPARE(target->x(), qreal(100)); - - //this is the main point of the test -- the behavior needs to be triggered again - //even though we set 0 twice in a row. - target->setProperty("x", 0); - QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); - - delete rect; -} - -//QTBUG-18362 -void tst_qdeclarativebehaviors::delayedRegistration() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("delayedRegistration.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickItem *innerRect = rect->property("myItem").value(); - QVERIFY(innerRect != 0); - - QCOMPARE(innerRect->property("x").toInt(), int(0)); - - QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); -} - -//QTBUG-22555 -void tst_qdeclarativebehaviors::startOnCompleted() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startOnCompleted.qml"))); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickItem *innerRect = rect->findChild(); - QVERIFY(innerRect != 0); - - QCOMPARE(innerRect->property("x").toInt(), int(0)); - - QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); - - delete rect; -} - -QTEST_MAIN(tst_qdeclarativebehaviors) - -#include "tst_qdeclarativebehaviors.moc" diff --git a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro index d0bbfe6faa..5f8ee634f4 100644 --- a/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro +++ b/tests/auto/declarative/qdeclarativebinding/qdeclarativebinding.pro @@ -10,4 +10,4 @@ DEPLOYMENT += testDataFiles CONFIG += parallel_test -QT += core-private gui-private declarative-private testlib +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp index 091a87b5a8..80ed10cd25 100644 --- a/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp +++ b/tests/auto/declarative/qdeclarativebinding/tst_qdeclarativebinding.cpp @@ -42,8 +42,8 @@ #include #include #include -#include -#include "../shared/util.h" +#include +#include "../../shared/util.h" class tst_qdeclarativebinding : public QObject { diff --git a/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro index b2f88b630b..7c52ef5dfd 100644 --- a/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro +++ b/tests/auto/declarative/qdeclarativechangeset/qdeclarativechangeset.pro @@ -6,4 +6,4 @@ SOURCES += tst_qdeclarativechangeset.cpp CONFIG += parallel_test -QT += core-private gui-private declarative-private testlib +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp index 1dcaaa1b06..da15458d27 100644 --- a/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp +++ b/tests/auto/declarative/qdeclarativecomponent/tst_qdeclarativecomponent.cpp @@ -43,11 +43,10 @@ #include #include -#include #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class MyIC : public QObject, public QDeclarativeIncubationController { diff --git a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro index ef3ef536f0..702f3fc542 100644 --- a/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro +++ b/tests/auto/declarative/qdeclarativeconnection/qdeclarativeconnection.pro @@ -10,4 +10,4 @@ DEPLOYMENT += testDataFiles CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp index 450f16c036..cd8f7b7b0c 100644 --- a/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp +++ b/tests/auto/declarative/qdeclarativeconnection/tst_qdeclarativeconnection.cpp @@ -43,7 +43,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" #include class tst_qdeclarativeconnection : public QObject diff --git a/tests/auto/declarative/qdeclarativeconsole/tst_qdeclarativeconsole.cpp b/tests/auto/declarative/qdeclarativeconsole/tst_qdeclarativeconsole.cpp index 24095e3c35..0025798854 100644 --- a/tests/auto/declarative/qdeclarativeconsole/tst_qdeclarativeconsole.cpp +++ b/tests/auto/declarative/qdeclarativeconsole/tst_qdeclarativeconsole.cpp @@ -42,7 +42,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativeconsole : public QObject { diff --git a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp index ba9db4f875..c57cbeceba 100644 --- a/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp +++ b/tests/auto/declarative/qdeclarativecontext/tst_qdeclarativecontext.cpp @@ -46,7 +46,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" inline QUrl TEST_FILE(const QString &filename) { diff --git a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro index d6d17c5869..1908e6bae1 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro +++ b/tests/auto/declarative/qdeclarativeecmascript/qdeclarativeecmascript.pro @@ -4,10 +4,10 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativeecmascript.cpp \ testtypes.cpp \ - ../shared/testhttpserver.cpp + ../../shared/testhttpserver.cpp HEADERS += testtypes.h \ - ../shared/testhttpserver.h -INCLUDEPATH += ../shared + ../../shared/testhttpserver.h +INCLUDEPATH += ../../shared # QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage # LIBS += -lgcov diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 4891e5088e..3d50d6ee3d 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -54,7 +54,7 @@ #include #include "testtypes.h" #include "testhttpserver.h" -#include "../shared/util.h" +#include "../../shared/util.h" /* This test covers evaluation of ECMAScript expressions and bindings from within diff --git a/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp b/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp index ab97d04d4c..8fab5e5e50 100644 --- a/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp +++ b/tests/auto/declarative/qdeclarativeerror/tst_qdeclarativeerror.cpp @@ -42,7 +42,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativeerror : public QObject { diff --git a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp index a65045b48f..f7699e2bac 100644 --- a/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp +++ b/tests/auto/declarative/qdeclarativeexpression/tst_qdeclarativeexpression.cpp @@ -44,7 +44,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativeexpression : public QObject { diff --git a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp index f8c91e6000..f85a6f14b6 100644 --- a/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp +++ b/tests/auto/declarative/qdeclarativefolderlistmodel/tst_qdeclarativefolderlistmodel.cpp @@ -46,7 +46,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" // From qdeclarastivefolderlistmodel.h const int FileNameRole = Qt::UserRole+1; diff --git a/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf b/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf deleted file mode 100644 index aae50d5035..0000000000 Binary files a/tests/auto/declarative/qdeclarativefontloader/data/daniel.ttf and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf b/tests/auto/declarative/qdeclarativefontloader/data/dummy.ttf deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml b/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml deleted file mode 100644 index 0eafdfa17b..0000000000 --- a/tests/auto/declarative/qdeclarativefontloader/data/qtbug-20268.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: test - property variant fontloader: fontloaderelement - height: 100; width: 100 - property bool usename: false - property int statenum: 1 - property alias name: fontloaderelement.name - property alias source: fontloaderelement.source - property alias status: fontloaderelement.status - - FontLoader { - id: fontloaderelement - } - - states: [ - State { name: "start"; when: !usename - PropertyChanges { target: fontloaderelement; source: "tarzeau_ocr_a.ttf" } - }, - State { name: "changefont"; when: usename - PropertyChanges { target: fontloaderelement; name: "Tahoma" } - } - ] - - Text { id: textelement; text: fontloaderelement.name; color: "black" } -} diff --git a/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf b/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf deleted file mode 100644 index cf93f9651f..0000000000 Binary files a/tests/auto/declarative/qdeclarativefontloader/data/tarzeau_ocr_a.ttf and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro deleted file mode 100644 index 3efde621b2..0000000000 --- a/tests/auto/declarative/qdeclarativefontloader/qdeclarativefontloader.pro +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativefontloader -macx:CONFIG -= app_bundle - -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativefontloader.cpp ../../declarative/shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp deleted file mode 100644 index 6e81befad8..0000000000 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include "../../declarative/shared/testhttpserver.h" -#include -#include - -#define SERVER_PORT 14448 - -class tst_qdeclarativefontloader : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativefontloader(); - -private slots: - void init(); - void noFont(); - void namedFont(); - void localFont(); - void failLocalFont(); - void webFont(); - void redirWebFont(); - void failWebFont(); - void changeFont(); - void changeFontSourceViaState(); - -private: - QDeclarativeEngine engine; - TestHTTPServer server; -}; - -tst_qdeclarativefontloader::tst_qdeclarativefontloader() : - server(SERVER_PORT) -{ - server.serveDirectory(TESTDATA("")); -} - -void tst_qdeclarativefontloader::init() -{ - QVERIFY(server.isValid()); -} - -void tst_qdeclarativefontloader::noFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QCOMPARE(fontObject->name(), QString("")); - QCOMPARE(fontObject->source(), QUrl("")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Null); - - delete fontObject; -} - -void tst_qdeclarativefontloader::namedFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { name: \"Helvetica\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QCOMPARE(fontObject->source(), QUrl("")); - QCOMPARE(fontObject->name(), QString("Helvetica")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); -} - -void tst_qdeclarativefontloader::localFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + TESTDATA("tarzeau_ocr_a.ttf") + "\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); -} - -void tst_qdeclarativefontloader::failLocalFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\" }"; - QTest::ignoreMessage(QtWarningMsg, QString("file::2:1: QML FontLoader: Cannot load font: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\"").toUtf8().constData()); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error); -} - -void tst_qdeclarativefontloader::webFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/tarzeau_ocr_a.ttf\" }"; - QDeclarativeComponent component(&engine); - - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); -} - -void tst_qdeclarativefontloader::redirWebFont() -{ - server.addRedirect("olddir/oldname.ttf","../tarzeau_ocr_a.ttf"); - - QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/olddir/oldname.ttf\" }"; - QDeclarativeComponent component(&engine); - - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); -} - -void tst_qdeclarativefontloader::failWebFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/nonexist.ttf\" }"; - QTest::ignoreMessage(QtWarningMsg, "file::2:1: QML FontLoader: Cannot load font: \"http://localhost:14448/nonexist.ttf\""); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("")); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error); -} - -void tst_qdeclarativefontloader::changeFont() -{ - QString componentStr = "import QtQuick 2.0\nFontLoader { source: font }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); - - QVERIFY(fontObject != 0); - - QSignalSpy nameSpy(fontObject, SIGNAL(nameChanged())); - QSignalSpy statusSpy(fontObject, SIGNAL(statusChanged())); - - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QCOMPARE(nameSpy.count(), 0); - QCOMPARE(statusSpy.count(), 0); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - - ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf"); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Loading); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QCOMPARE(nameSpy.count(), 1); - QCOMPARE(statusSpy.count(), 2); - QTRY_COMPARE(fontObject->name(), QString("Daniel")); - - ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf"))); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QCOMPARE(nameSpy.count(), 2); - QCOMPARE(statusSpy.count(), 2); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - - ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf"); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QCOMPARE(nameSpy.count(), 3); - QCOMPARE(statusSpy.count(), 2); - QTRY_COMPARE(fontObject->name(), QString("Daniel")); -} - -void tst_qdeclarativefontloader::changeFontSourceViaState() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-20268.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QDeclarativeFontLoader *fontObject = qobject_cast(qvariant_cast(canvas.rootObject()->property("fontloader"))); - QVERIFY(fontObject != 0); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QVERIFY(fontObject->source() != QUrl("")); - QTRY_COMPARE(fontObject->name(), QString("OCRA")); - - canvas.rootObject()->setProperty("usename", true); - - // This warning should probably not be printed once QTBUG-20268 is fixed - QString warning = QString(QUrl::fromLocalFile(TESTDATA("qtbug-20268.qml")).toString()) + - QLatin1String(":13:5: QML FontLoader: Cannot load font: \"\""); - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - - QEXPECT_FAIL("", "QTBUG-20268", Abort); - QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); - QCOMPARE(canvas.rootObject()->property("name").toString(), QString("Tahoma")); -} - -QTEST_MAIN(tst_qdeclarativefontloader) - -#include "tst_qdeclarativefontloader.moc" diff --git a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro index dda2595956..70b9a406b3 100644 --- a/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro +++ b/tests/auto/declarative/qdeclarativeimageprovider/qdeclarativeimageprovider.pro @@ -6,4 +6,4 @@ SOURCES += tst_qdeclarativeimageprovider.cpp CONFIG += parallel_test -QT += core-private gui-private declarative-private network testlib +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp index fe618b87e8..599b5d21b1 100644 --- a/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp +++ b/tests/auto/declarative/qdeclarativeincubator/tst_qdeclarativeincubator.cpp @@ -51,7 +51,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" inline QUrl TEST_FILE(const QString &filename) { diff --git a/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp b/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp index ec04a83102..d4e3df2ffb 100644 --- a/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp +++ b/tests/auto/declarative/qdeclarativeinfo/tst_qdeclarativeinfo.cpp @@ -45,7 +45,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativeinfo : public QObject { diff --git a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro index 105e2b44d6..f79d1c99c9 100644 --- a/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro +++ b/tests/auto/declarative/qdeclarativelanguage/qdeclarativelanguage.pro @@ -6,9 +6,9 @@ SOURCES += tst_qdeclarativelanguage.cpp \ testtypes.cpp HEADERS += testtypes.h -INCLUDEPATH += ../shared/ -HEADERS += ../shared/testhttpserver.h -SOURCES += ../shared/testhttpserver.cpp +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h +SOURCES += ../../shared/testhttpserver.cpp importFiles.files = data importFiles.path = . diff --git a/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro b/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro index e8dd7dd83a..3936f4beff 100644 --- a/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro +++ b/tests/auto/declarative/qdeclarativelistcompositor/qdeclarativelistcompositor.pro @@ -6,4 +6,4 @@ SOURCES += tst_qdeclarativelistcompositor.cpp CONFIG += parallel_test -QT += core-private gui-private declarative-private testlib +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro index fc8a3178ae..ae3aa9d287 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro +++ b/tests/auto/declarative/qdeclarativelistmodel/qdeclarativelistmodel.pro @@ -10,4 +10,4 @@ DEPLOYMENT += testDataFiles CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 661b086fd1..1de2a2868e 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -39,8 +39,8 @@ ** ****************************************************************************/ #include -#include -#include +#include +#include #include #include #include @@ -51,7 +51,7 @@ #include #include -#include "../shared/util.h" +#include "../../shared/util.h" Q_DECLARE_METATYPE(QList) Q_DECLARE_METATYPE(QList) diff --git a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp index a86e66de45..e09db2c9c7 100644 --- a/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp +++ b/tests/auto/declarative/qdeclarativelistreference/tst_qdeclarativelistreference.cpp @@ -49,7 +49,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" inline QUrl TEST_FILE(const QString &filename) { diff --git a/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp b/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp index 54139a2671..b2f35fd8b3 100644 --- a/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp +++ b/tests/auto/declarative/qdeclarativelocale/tst_qdeclarativelocale.cpp @@ -43,10 +43,9 @@ #include #include -#include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativelocale : public QObject { diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp index d8b7cf4e5b..1530eb9d36 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.cpp @@ -44,8 +44,8 @@ #include #include -#include "../shared/testhttpserver.h" -#include "../shared/util.h" +#include "../../shared/testhttpserver.h" +#include "../../shared/util.h" #define SERVER_ADDR "http://127.0.0.1:14450" #define SERVER_PORT 14450 diff --git a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro index 94c0f9dde1..bec727f05f 100644 --- a/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro +++ b/tests/auto/declarative/qdeclarativemoduleplugin/tst_qdeclarativemoduleplugin.pro @@ -1,9 +1,9 @@ CONFIG += testcase TARGET = tst_qdeclarativemoduleplugin -HEADERS = ../shared/testhttpserver.h +HEADERS = ../../shared/testhttpserver.h SOURCES = tst_qdeclarativemoduleplugin.cpp \ - ../shared/testhttpserver.cpp + ../../shared/testhttpserver.cpp CONFIG -= app_bundle testDataFiles.files = data diff --git a/tests/auto/declarative/qdeclarativepath/data/arc.qml b/tests/auto/declarative/qdeclarativepath/data/arc.qml deleted file mode 100644 index 000221c784..0000000000 --- a/tests/auto/declarative/qdeclarativepath/data/arc.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Path { - startX: 0; startY: 0 - - PathArc { - x: 100; y: 100 - radiusX: 100; radiusY: 100 - direction: PathArc.Clockwise - } -} diff --git a/tests/auto/declarative/qdeclarativepath/data/curve.qml b/tests/auto/declarative/qdeclarativepath/data/curve.qml deleted file mode 100644 index c571186496..0000000000 --- a/tests/auto/declarative/qdeclarativepath/data/curve.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Path { - startX: 0; startY: 0 - - PathCurve { x: 100; y: 50 } - PathCurve { x: 50; y: 100 } - PathCurve { x: 100; y: 150 } -} diff --git a/tests/auto/declarative/qdeclarativepath/data/svg.qml b/tests/auto/declarative/qdeclarativepath/data/svg.qml deleted file mode 100644 index cec0f75061..0000000000 --- a/tests/auto/declarative/qdeclarativepath/data/svg.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Path { - PathSvg { path: "M200,300 Q400,50 600,300 T1000,300" } -} diff --git a/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro b/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro deleted file mode 100644 index 212117165d..0000000000 --- a/tests/auto/declarative/qdeclarativepath/qdeclarativepath.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativepath -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativepath.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private testlib diff --git a/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp b/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp deleted file mode 100644 index 91513fc8a5..0000000000 --- a/tests/auto/declarative/qdeclarativepath/tst_qdeclarativepath.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include - -#include "../shared/util.h" - -class tst_QDeclarativePath : public QObject -{ - Q_OBJECT -public: - tst_QDeclarativePath() {} - -private slots: - void arc(); - void catmullromCurve(); - void svg(); -}; - -void tst_QDeclarativePath::arc() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("arc.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->startX(), 0.); - QCOMPARE(obj->startY(), 0.); - - QDeclarativeListReference list(obj, "pathElements"); - QCOMPARE(list.count(), 1); - - QDeclarativePathArc* arc = qobject_cast(list.at(0)); - QVERIFY(arc != 0); - QCOMPARE(arc->x(), 100.); - QCOMPARE(arc->y(), 100.); - QCOMPARE(arc->radiusX(), 100.); - QCOMPARE(arc->radiusY(), 100.); - QCOMPARE(arc->useLargeArc(), false); - QCOMPARE(arc->direction(), QDeclarativePathArc::Clockwise); - - QPainterPath path = obj->path(); - QVERIFY(path != QPainterPath()); - - QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(0,0)); - pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(39,8)); //fuzzy compare - pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(92,61)); //fuzzy compare - pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(100,100)); -} - -void tst_QDeclarativePath::catmullromCurve() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("curve.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->startX(), 0.); - QCOMPARE(obj->startY(), 0.); - - QDeclarativeListReference list(obj, "pathElements"); - QCOMPARE(list.count(), 3); - - QDeclarativePathCatmullRomCurve* arc = qobject_cast(list.at(0)); -// QVERIFY(arc != 0); -// QCOMPARE(arc->x(), 100.); -// QCOMPARE(arc->y(), 100.); -// QCOMPARE(arc->radiusX(), 100.); -// QCOMPARE(arc->radiusY(), 100.); -// QCOMPARE(arc->useLargeArc(), false); -// QCOMPARE(arc->direction(), QDeclarativePathArc::Clockwise); - - QPainterPath path = obj->path(); - QVERIFY(path != QPainterPath()); - - QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(0,0)); - pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(63,26)); //fuzzy compare - pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(51,105)); //fuzzy compare - pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(100,150)); -} - -void tst_QDeclarativePath::svg() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("svg.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->startX(), 0.); - QCOMPARE(obj->startY(), 0.); - - QDeclarativeListReference list(obj, "pathElements"); - QCOMPARE(list.count(), 1); - - QDeclarativePathSvg* svg = qobject_cast(list.at(0)); - QVERIFY(svg != 0); - QCOMPARE(svg->path(), QLatin1String("M200,300 Q400,50 600,300 T1000,300")); - - QPainterPath path = obj->path(); - QVERIFY(path != QPainterPath()); - - QPointF pos = obj->pointAt(0); - QCOMPARE(pos, QPointF(200,300)); - pos = obj->pointAt(.25); - QCOMPARE(pos.toPoint(), QPoint(400,175)); //fuzzy compare - pos = obj->pointAt(.75); - QCOMPARE(pos.toPoint(), QPoint(800,425)); //fuzzy compare - pos = obj->pointAt(1); - QCOMPARE(pos, QPointF(1000,300)); -} - - -QTEST_MAIN(tst_QDeclarativePath) - -#include "tst_qdeclarativepath.moc" diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/exists.png b/tests/auto/declarative/qdeclarativepixmapcache/data/exists.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/exists.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/exists1.png b/tests/auto/declarative/qdeclarativepixmapcache/data/exists1.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/exists1.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/exists2.png b/tests/auto/declarative/qdeclarativepixmapcache/data/exists2.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/exists2.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists1.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists1.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists1.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists2.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists2.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists2.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists3.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists3.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists3.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists4.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists4.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists4.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists5.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists5.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists5.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists6.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists6.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists6.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists7.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists7.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists7.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists8.png b/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists8.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/http/exists8.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png b/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png deleted file mode 100644 index bc6cc9e6ca..0000000000 Binary files a/tests/auto/declarative/qdeclarativepixmapcache/data/massive.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro b/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro deleted file mode 100644 index 79d411c62c..0000000000 --- a/tests/auto/declarative/qdeclarativepixmapcache/qdeclarativepixmapcache.pro +++ /dev/null @@ -1,20 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativepixmapcache -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativepixmapcache.cpp - -INCLUDEPATH += ../shared/ -HEADERS += ../shared/testhttpserver.h -SOURCES += ../shared/testhttpserver.cpp - -importFiles.files = data -importFiles.path = . -DEPLOYMENT += importFiles - -# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage -# LIBS += -lgcov - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp deleted file mode 100644 index 7a1c9e6bfd..0000000000 --- a/tests/auto/declarative/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp +++ /dev/null @@ -1,458 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include "testhttpserver.h" - -#ifndef QT_NO_CONCURRENT -#include -#include -#endif - -inline QUrl TEST_FILE(const QString &filename) -{ - return QUrl::fromLocalFile(TESTDATA(filename)); -} - -class tst_qdeclarativepixmapcache : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativepixmapcache() : - server(14452) - { - server.serveDirectory(TESTDATA("http")); - } - -private slots: - void single(); - void single_data(); - void parallel(); - void parallel_data(); - void massive(); - void cancelcrash(); - void shrinkcache(); -#ifndef QT_NO_CONCURRENT - void networkCrash(); -#endif - void lockingCrash(); - void dataLeak(); -private: - QDeclarativeEngine engine; - TestHTTPServer server; -}; - -static int slotters=0; - -class Slotter : public QObject -{ - Q_OBJECT -public: - Slotter() - { - gotslot = false; - slotters++; - } - bool gotslot; - -public slots: - void got() - { - gotslot = true; - --slotters; - if (slotters==0) - QTestEventLoop::instance().exitLoop(); - } -}; - -#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML -static const bool localfile_optimized = true; -#else -static const bool localfile_optimized = false; -#endif - -void tst_qdeclarativepixmapcache::single_data() -{ - // Note, since QDeclarativePixmapCache is shared, tests affect each other! - // so use different files fore all test functions. - - QTest::addColumn("target"); - QTest::addColumn("incache"); - QTest::addColumn("exists"); - QTest::addColumn("neterror"); - - // File URLs are optimized - QTest::newRow("local") << TEST_FILE("exists.png") << localfile_optimized << true << false; - QTest::newRow("local") << TEST_FILE("notexists.png") << localfile_optimized << false << false; - QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/exists.png") << false << true << false; - QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/notexists.png") << false << false << true; -} - -void tst_qdeclarativepixmapcache::single() -{ - QFETCH(QUrl, target); - QFETCH(bool, incache); - QFETCH(bool, exists); - QFETCH(bool, neterror); - - QString expectedError; - if (neterror) { - expectedError = "Error downloading " + target.toString() + " - server replied: Not found"; - } else if (!exists) { - expectedError = "Cannot open: " + target.toString(); - } - - QDeclarativePixmap pixmap; - QVERIFY(pixmap.width() <= 0); // Check Qt assumption - - pixmap.load(&engine, target); - - if (incache) { - QCOMPARE(pixmap.error(), expectedError); - if (exists) { - QVERIFY(pixmap.status() == QDeclarativePixmap::Ready); - QVERIFY(pixmap.width() > 0); - } else { - QVERIFY(pixmap.status() == QDeclarativePixmap::Error); - QVERIFY(pixmap.width() <= 0); - } - } else { - QVERIFY(pixmap.width() <= 0); - - Slotter getter; - pixmap.connectFinished(&getter, SLOT(got())); - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - QVERIFY(getter.gotslot); - if (exists) { - QVERIFY(pixmap.status() == QDeclarativePixmap::Ready); - QVERIFY(pixmap.width() > 0); - } else { - QVERIFY(pixmap.status() == QDeclarativePixmap::Error); - QVERIFY(pixmap.width() <= 0); - } - QCOMPARE(pixmap.error(), expectedError); - } -} - -void tst_qdeclarativepixmapcache::parallel_data() -{ - // Note, since QDeclarativePixmapCache is shared, tests affect each other! - // so use different files fore all test functions. - - QTest::addColumn("target1"); - QTest::addColumn("target2"); - QTest::addColumn("incache"); - QTest::addColumn("cancel"); // which one to cancel - - QTest::newRow("local") - << TEST_FILE("exists1.png") - << TEST_FILE("exists2.png") - << (localfile_optimized ? 2 : 0) - << -1; - - QTest::newRow("remote") - << QUrl("http://127.0.0.1:14452/exists2.png") - << QUrl("http://127.0.0.1:14452/exists3.png") - << 0 - << -1; - - QTest::newRow("remoteagain") - << QUrl("http://127.0.0.1:14452/exists2.png") - << QUrl("http://127.0.0.1:14452/exists3.png") - << 2 - << -1; - - QTest::newRow("remotecopy") - << QUrl("http://127.0.0.1:14452/exists4.png") - << QUrl("http://127.0.0.1:14452/exists4.png") - << 0 - << -1; - - QTest::newRow("remotecopycancel") - << QUrl("http://127.0.0.1:14452/exists5.png") - << QUrl("http://127.0.0.1:14452/exists5.png") - << 0 - << 0; -} - -void tst_qdeclarativepixmapcache::parallel() -{ - QFETCH(QUrl, target1); - QFETCH(QUrl, target2); - QFETCH(int, incache); - QFETCH(int, cancel); - - QList targets; - targets << target1 << target2; - - QList pixmaps; - QList pending; - QList getters; - - for (int i=0; iload(&engine, target); - - QVERIFY(pixmap->status() != QDeclarativePixmap::Error); - pixmaps.append(pixmap); - if (pixmap->isReady()) { - QVERIFY(pixmap->width() > 0); - getters.append(0); - pending.append(false); - } else { - QVERIFY(pixmap->width() <= 0); - getters.append(new Slotter); - pixmap->connectFinished(getters[i], SLOT(got())); - pending.append(true); - } - } - - QCOMPARE(incache+slotters, targets.count()); - - if (cancel >= 0) { - pixmaps.at(cancel)->clear(getters[cancel]); - slotters--; - } - - if (slotters) { - QTestEventLoop::instance().enterLoop(10); - QVERIFY(!QTestEventLoop::instance().timeout()); - } - - for (int i=0; igotslot); - } else { - if (pending[i]) - QVERIFY(getters[i]->gotslot); - - QVERIFY(pixmap->isReady()); - QVERIFY(pixmap->width() > 0); - delete getters[i]; - } - } - - qDeleteAll(pixmaps); -} - -void tst_qdeclarativepixmapcache::massive() -{ - QDeclarativeEngine engine; - QUrl url = TEST_FILE("massive.png"); - - // Confirm that massive images remain in the cache while they are - // in use by the application. - { - qint64 cachekey = 0; - QDeclarativePixmap p(&engine, url); - QVERIFY(p.isReady()); - QVERIFY(p.image().size() == QSize(10000, 1000)); - cachekey = p.image().cacheKey(); - - QDeclarativePixmap p2(&engine, url); - QVERIFY(p2.isReady()); - QVERIFY(p2.image().size() == QSize(10000, 1000)); - - QVERIFY(p2.image().cacheKey() == cachekey); - } - - // Confirm that massive images are removed from the cache when - // they become unused - { - qint64 cachekey = 0; - { - QDeclarativePixmap p(&engine, url); - QVERIFY(p.isReady()); - QVERIFY(p.image().size() == QSize(10000, 1000)); - cachekey = p.image().cacheKey(); - } - - QDeclarativePixmap p2(&engine, url); - QVERIFY(p2.isReady()); - QVERIFY(p2.image().size() == QSize(10000, 1000)); - - QVERIFY(p2.image().cacheKey() != cachekey); - } -} - -// QTBUG-12729 -void tst_qdeclarativepixmapcache::cancelcrash() -{ - QUrl url("http://127.0.0.1:14452/cancelcrash_notexist.png"); - for (int ii = 0; ii < 1000; ++ii) { - QDeclarativePixmap pix(&engine, url); - } -} - -class MyPixmapProvider : public QDeclarativeImageProvider -{ -public: - MyPixmapProvider() - : QDeclarativeImageProvider(Pixmap) {} - - virtual QPixmap requestPixmap(const QString &d, QSize *, const QSize &) { - Q_UNUSED(d) - QPixmap pix(800, 600); - pix.fill(Qt::red); - return pix; - } -}; - -// QTBUG-13345 -void tst_qdeclarativepixmapcache::shrinkcache() -{ - QDeclarativeEngine engine; - engine.addImageProvider(QLatin1String("mypixmaps"), new MyPixmapProvider); - - for (int ii = 0; ii < 4000; ++ii) { - QUrl url("image://mypixmaps/" + QString::number(ii)); - QDeclarativePixmap p(&engine, url); - } -} - -#ifndef QT_NO_CONCURRENT - -void createNetworkServer() -{ - QEventLoop eventLoop; - TestHTTPServer server(14453); - server.serveDirectory(TESTDATA("http")); - QTimer::singleShot(100, &eventLoop, SLOT(quit())); - eventLoop.exec(); -} - -#ifndef QT_NO_CONCURRENT -// QT-3957 -void tst_qdeclarativepixmapcache::networkCrash() -{ - QFuture future = QtConcurrent::run(createNetworkServer); - QDeclarativeEngine engine; - for (int ii = 0; ii < 100 ; ++ii) { - QDeclarativePixmap* pixmap = new QDeclarativePixmap; - pixmap->load(&engine, QUrl(QString("http://127.0.0.1:14453/exists.png"))); - QTest::qSleep(1); - pixmap->clear(); - delete pixmap; - } - future.cancel(); -} -#endif - -#endif - -// QTBUG-22125 -void tst_qdeclarativepixmapcache::lockingCrash() -{ - TestHTTPServer server(14453); - server.serveDirectory(TESTDATA("http"), TestHTTPServer::Delay); - - { - QDeclarativePixmap* p = new QDeclarativePixmap; - { - QDeclarativeEngine e; - p->load(&e, QUrl(QString("http://127.0.0.1:14453/exists6.png"))); - } - p->clear(); - QVERIFY(p->isNull()); - delete p; - } -} - -#include -class DataLeakView : public QQuickView -{ - Q_OBJECT - -public: - explicit DataLeakView() : QQuickView() - { - setSource(TEST_FILE("dataLeak.qml")); - } - - void showFor2Seconds() - { - showFullScreen(); - QTimer::singleShot(2000, this, SIGNAL(ready())); - } - -signals: - void ready(); -}; - -// QTBUG-22742 -Q_GLOBAL_STATIC(QDeclarativePixmap, dataLeakPixmap) -void tst_qdeclarativepixmapcache::dataLeak() -{ - // Should not leak cached QDeclarativePixmapData. - // Unfortunately, since the QDeclarativePixmapStore - // is a global static, and it releases the cache - // entries on dtor (application exit), we must use - // valgrind to determine whether it leaks or not. - QDeclarativePixmap *p1 = new QDeclarativePixmap; - QDeclarativePixmap *p2 = new QDeclarativePixmap; - { - QScopedPointer test(new DataLeakView); - test->showFor2Seconds(); - dataLeakPixmap()->load(test->engine(), TEST_FILE("exists.png")); - p1->load(test->engine(), TEST_FILE("exists.png")); - p2->load(test->engine(), TEST_FILE("exists2.png")); - QTest::qWait(2005); // 2 seconds + a few more millis. - } - - // When the (global static) dataLeakPixmap is deleted, it - // shouldn't attempt to dereference a QDeclarativePixmapData - // which has been deleted by the QDeclarativePixmapStore - // destructor. -} - -QTEST_MAIN(tst_qdeclarativepixmapcache) - -#include "tst_qdeclarativepixmapcache.moc" diff --git a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp index 411eeeacc7..b1aad3a34b 100644 --- a/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp +++ b/tests/auto/declarative/qdeclarativeproperty/tst_qdeclarativeproperty.cpp @@ -47,7 +47,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" inline QUrl TEST_FILE(const QString &filename) { diff --git a/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro b/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro index a6332161a0..f94405c770 100644 --- a/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro +++ b/tests/auto/declarative/qdeclarativepropertymap/qdeclarativepropertymap.pro @@ -6,4 +6,4 @@ SOURCES += tst_qdeclarativepropertymap.cpp CONFIG += parallel_test -QT += core-private gui-private declarative-private testlib +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp index cb2db47800..59a7fe7931 100644 --- a/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp +++ b/tests/auto/declarative/qdeclarativepropertymap/tst_qdeclarativepropertymap.cpp @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include class tst_QDeclarativePropertyMap : public QObject diff --git a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro index 18fb8b2027..9428746dc1 100644 --- a/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro +++ b/tests/auto/declarative/qdeclarativeqt/qdeclarativeqt.pro @@ -9,4 +9,4 @@ DEPLOYMENT += testDataFiles CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private testlib +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp index 293fcd382f..5b3ea5e169 100644 --- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp +++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp @@ -50,9 +50,9 @@ #include #include #include -#include +#include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativeqt : public QObject { diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml deleted file mode 100644 index 3631f971f0..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation1.qml +++ /dev/null @@ -1,3 +0,0 @@ -import QtQuick 2.0 - -SmoothedAnimation {} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml deleted file mode 100644 index b07120234a..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation2.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -SmoothedAnimation { - to: 10; duration: 300; reversingMode: SmoothedAnimation.Immediate -} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml deleted file mode 100644 index 8d5dc4a92b..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimation3.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -SmoothedAnimation { - to: 10; velocity: 250; reversingMode: SmoothedAnimation.Sync - maximumEasingTime: 150 -} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml deleted file mode 100644 index 81d36bf015..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400; color: "blue" - - Rectangle { - id: rect1 - color: "red" - width: 60; height: 60; - x: 100; y: 100; - SmoothedAnimation on x { to: 200; velocity: 500 } - SmoothedAnimation on y { to: 200; velocity: 500 } - } - - Rectangle { - objectName: "theRect" - color: "green" - width: 60; height: 60; - x: rect1.x; y: rect1.y; - // id are needed for SmoothedAnimation in order to avoid deferred creation - Behavior on x { SmoothedAnimation { id: anim1; objectName: "easeX"; velocity: 400 } } - Behavior on y { SmoothedAnimation { id: anim2; objectName: "easeY"; velocity: 400 } } - } - } diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml b/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml deleted file mode 100644 index e136df84f6..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 300; height: 300; - Rectangle { - objectName: "theRect" - color: "red" - width: 60; height: 60; - x: 100; y: 100; - SmoothedAnimation on x { objectName: "easeX"; to: 200; velocity: 500 } - SmoothedAnimation on y { objectName: "easeY"; to: 200; duration: 250; velocity: 500 } - } -} diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro deleted file mode 100644 index 05d31be39d..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativesmoothedanimation -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativesmoothedanimation.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private testlib diff --git a/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp b/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp deleted file mode 100644 index 735af520fe..0000000000 --- a/tests/auto/declarative/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qdeclarativesmoothedanimation : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativesmoothedanimation(); - -private slots: - void defaultValues(); - void values(); - void disabled(); - void simpleAnimation(); - void valueSource(); - void behavior(); - -private: - QDeclarativeEngine engine; -}; - -tst_qdeclarativesmoothedanimation::tst_qdeclarativesmoothedanimation() -{ -} - -void tst_qdeclarativesmoothedanimation::defaultValues() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation1.qml"))); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 0.); - QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->duration(), -1); - QCOMPARE(obj->maximumEasingTime(), -1); - QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Eased); - - delete obj; -} - -void tst_qdeclarativesmoothedanimation::values() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation2.qml"))); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 10.); - QCOMPARE(obj->velocity(), 200.); - QCOMPARE(obj->duration(), 300); - QCOMPARE(obj->maximumEasingTime(), -1); - QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Immediate); - - delete obj; -} - -void tst_qdeclarativesmoothedanimation::disabled() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation3.qml"))); - QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 10.); - QCOMPARE(obj->velocity(), 250.); - QCOMPARE(obj->maximumEasingTime(), 150); - QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Sync); - - delete obj; -} - -void tst_qdeclarativesmoothedanimation::simpleAnimation() -{ - QQuickRectangle rect; - QDeclarativeSmoothedAnimation animation; - animation.setTarget(&rect); - animation.setProperty("x"); - animation.setTo(200); - animation.setDuration(250); - QVERIFY(animation.target() == &rect); - QVERIFY(animation.property() == "x"); - QVERIFY(animation.to() == 200); - animation.start(); - QVERIFY(animation.isRunning()); - QTest::qWait(animation.duration()); - QTRY_COMPARE(rect.x(), qreal(200)); - - rect.setX(0); - animation.start(); - animation.pause(); - QVERIFY(animation.isRunning()); - QVERIFY(animation.isPaused()); - animation.setCurrentTime(125); - QVERIFY(animation.currentTime() == 125); - QCOMPARE(rect.x(), qreal(100)); -} - -void tst_qdeclarativesmoothedanimation::valueSource() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationValueSource.qml"))); - - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *theRect = rect->findChild("theRect"); - QVERIFY(theRect); - - QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); - QVERIFY(easeX); - QVERIFY(easeX->isRunning()); - - QDeclarativeSmoothedAnimation *easeY = rect->findChild("easeY"); - QVERIFY(easeY); - QVERIFY(easeY->isRunning()); - - // XXX get the proper duration - QTest::qWait(100); - - QTRY_VERIFY(!easeX->isRunning()); - QTRY_VERIFY(!easeY->isRunning()); - - QTRY_COMPARE(theRect->x(), qreal(200)); - QTRY_COMPARE(theRect->y(), qreal(200)); - - delete rect; -} - -void tst_qdeclarativesmoothedanimation::behavior() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationBehavior.qml"))); - - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect); - - QQuickRectangle *theRect = rect->findChild("theRect"); - QVERIFY(theRect); - - QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); - QVERIFY(easeX); - - QDeclarativeSmoothedAnimation *easeY = rect->findChild("easeY"); - QVERIFY(easeY); - - // XXX get the proper duration - QTest::qWait(400); - - QTRY_VERIFY(!easeX->isRunning()); - QTRY_VERIFY(!easeY->isRunning()); - - QTRY_COMPARE(theRect->x(), qreal(200)); - QTRY_COMPARE(theRect->y(), qreal(200)); - - delete rect; -} - -QTEST_MAIN(tst_qdeclarativesmoothedanimation) - -#include "tst_qdeclarativesmoothedanimation.moc" diff --git a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation1.qml b/tests/auto/declarative/qdeclarativespringanimation/data/springanimation1.qml deleted file mode 100644 index 9f52aa56c1..0000000000 --- a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation1.qml +++ /dev/null @@ -1,4 +0,0 @@ -import QtQuick 2.0 - -SpringAnimation { -} diff --git a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation2.qml b/tests/auto/declarative/qdeclarativespringanimation/data/springanimation2.qml deleted file mode 100644 index 172cc57ca8..0000000000 --- a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation2.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -SpringAnimation { - to: 1.44; velocity: 0.9 - spring: 1.0; damping: 0.5 - epsilon: 0.25; modulus: 360.0 - mass: 2.0; - running: true; -} diff --git a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation3.qml b/tests/auto/declarative/qdeclarativespringanimation/data/springanimation3.qml deleted file mode 100644 index f4dc121eb8..0000000000 --- a/tests/auto/declarative/qdeclarativespringanimation/data/springanimation3.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -SpringAnimation { - to: 1.44; velocity: 0.9 - spring: 1.0; damping: 0.5 - epsilon: 0.25; modulus: 360.0 - mass: 2.0; running: false -} diff --git a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro deleted file mode 100644 index 7153327829..0000000000 --- a/tests/auto/declarative/qdeclarativespringanimation/qdeclarativespringanimation.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativespringanimation -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativespringanimation.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private testlib diff --git a/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp b/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp deleted file mode 100644 index d7edcee386..0000000000 --- a/tests/auto/declarative/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qdeclarativespringanimation : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativespringanimation(); - -private slots: - void defaultValues(); - void values(); - void disabled(); - -private: - QDeclarativeEngine engine; -}; - -tst_qdeclarativespringanimation::tst_qdeclarativespringanimation() -{ -} - -void tst_qdeclarativespringanimation::defaultValues() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation1.qml"))); - QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 0.); - QCOMPARE(obj->velocity(), 0.); - QCOMPARE(obj->spring(), 0.); - QCOMPARE(obj->damping(), 0.); - QCOMPARE(obj->epsilon(), 0.01); - QCOMPARE(obj->modulus(), 0.); - QCOMPARE(obj->mass(), 1.); - QCOMPARE(obj->isRunning(), false); - - delete obj; -} - -void tst_qdeclarativespringanimation::values() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation2.qml"))); - QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 1.44); - QCOMPARE(obj->velocity(), 0.9); - QCOMPARE(obj->spring(), 1.0); - QCOMPARE(obj->damping(), 0.5); - QCOMPARE(obj->epsilon(), 0.25); - QCOMPARE(obj->modulus(), 360.0); - QCOMPARE(obj->mass(), 2.0); - QCOMPARE(obj->isRunning(), true); - - QTRY_COMPARE(obj->isRunning(), false); - - delete obj; -} - -void tst_qdeclarativespringanimation::disabled() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation3.qml"))); - QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - - QCOMPARE(obj->to(), 1.44); - QCOMPARE(obj->velocity(), 0.9); - QCOMPARE(obj->spring(), 1.0); - QCOMPARE(obj->damping(), 0.5); - QCOMPARE(obj->epsilon(), 0.25); - QCOMPARE(obj->modulus(), 360.0); - QCOMPARE(obj->mass(), 2.0); - QCOMPARE(obj->isRunning(), false); - - delete obj; -} - -QTEST_MAIN(tst_qdeclarativespringanimation) - -#include "tst_qdeclarativespringanimation.moc" diff --git a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro index 2d0efec9a5..8b8c19c44c 100644 --- a/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro +++ b/tests/auto/declarative/qdeclarativesqldatabase/qdeclarativesqldatabase.pro @@ -10,4 +10,4 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private sql testlib +QT += core-private gui-private v8-private declarative-private quick-private sql testlib diff --git a/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp b/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp index f7c520d283..1a6b08cb79 100644 --- a/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp +++ b/tests/auto/declarative/qdeclarativesqldatabase/tst_qdeclarativesqldatabase.cpp @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include /* @@ -53,7 +53,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativesqldatabase : public QObject { diff --git a/tests/auto/declarative/qdeclarativestates/data/ExtendedRectangle.qml b/tests/auto/declarative/qdeclarativestates/data/ExtendedRectangle.qml deleted file mode 100644 index 1ea346b841..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/ExtendedRectangle.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: extendedRect - objectName: "extendedRect" - property color extendedColor: "orange" - - width: 100; height: 100 - color: "red" - states: State { - name: "green" - PropertyChanges { - target: rect - onDidSomething: { - extendedRect.color = "green" - extendedColor = "green" - } - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/Implementation/MyType.qml b/tests/auto/declarative/qdeclarativestates/data/Implementation/MyType.qml deleted file mode 100644 index 01eb32cd4d..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/Implementation/MyType.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.0 - -Item { - Column { - anchors.centerIn: parent - Image { id: image1; objectName: "image1" } - Image { id: image2; objectName: "image2" } - Image { id: image3; objectName: "image3" } - } - - states: State { - name: "SetImageState" - PropertyChanges { - target: image1 - source: "images/qt-logo.png" - } - PropertyChanges { - target: image2 - source: "images/" + "qt-logo.png" - } - PropertyChanges { - target: image3 - source: "images/" + (true ? "qt-logo.png" : "") - } - } - - MouseArea { - anchors.fill: parent - onClicked: parent.state = "SetImageState" - } - -} diff --git a/tests/auto/declarative/qdeclarativestates/data/Implementation/images/qt-logo.png b/tests/auto/declarative/qdeclarativestates/data/Implementation/images/qt-logo.png deleted file mode 100644 index 14ddf2a028..0000000000 Binary files a/tests/auto/declarative/qdeclarativestates/data/Implementation/images/qt-logo.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativestates/data/QTBUG-14830.qml b/tests/auto/declarative/qdeclarativestates/data/QTBUG-14830.qml deleted file mode 100644 index 5ba7c3ad6f..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/QTBUG-14830.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 1024 - height: 768 - - Item { - id: area - objectName: "area" - property int numx: 6 - property int cellwidth: 1024/numx - - onWidthChanged: { - width = width>1024?1024:width; - } - - state: 'minimal' - states: [ - State { - name: 'minimal' - PropertyChanges { - target: area - width: cellwidth - } - } - ] - - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml deleted file mode 100644 index 378f5390f9..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges1.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - width: 50; height: 50 - color: "green"; - anchors.left: parent.left - anchors.leftMargin: 5 - } - states: State { - name: "right" - AnchorChanges { - id: ancCh - target: myRect; - anchors.left: undefined - anchors.right: container.right - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges2.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges2.qml deleted file mode 100644 index dc7f8ef0d1..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges2.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - width: 50; height: 50 - color: "green"; - anchors.left: parent.left - anchors.leftMargin: 5 - } - states: State { - name: "right" - AnchorChanges { - target: myRect; - anchors.left: undefined - anchors.right: parent.right - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges3.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges3.qml deleted file mode 100644 index af49575854..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges3.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - color: "green"; - anchors.left: parent.left - anchors.right: rightGuideline.left - anchors.top: topGuideline.top - anchors.bottom: container.bottom - } - Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } - Item { id: rightGuideline; x: 150 } - Item { id: topGuideline; y: 10 } - Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } - states: State { - name: "reanchored" - AnchorChanges { - target: myRect; - anchors.left: leftGuideline.left - anchors.right: container.right - anchors.top: container.top - anchors.bottom: bottomGuideline.bottom - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges4.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges4.qml deleted file mode 100644 index 28b55818bd..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges4.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - color: "green"; - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - } - Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } - Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } - states: State { - name: "reanchored" - AnchorChanges { - target: myRect; - anchors.horizontalCenter: bottomGuideline.horizontalCenter - anchors.verticalCenter: leftGuideline.verticalCenter - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChanges5.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChanges5.qml deleted file mode 100644 index b1ca968fb9..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChanges5.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - id: myRect - objectName: "MyRect" - color: "green"; - anchors.horizontalCenter: parent.horizontalCenter - anchors.baseline: parent.baseline - } - Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } - Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } - states: State { - name: "reanchored" - AnchorChanges { - target: myRect; - anchors.horizontalCenter: bottomGuideline.horizontalCenter - anchors.baseline: leftGuideline.baseline - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorChangesCrash.qml b/tests/auto/declarative/qdeclarativestates/data/anchorChangesCrash.qml deleted file mode 100644 index 9af0e4645a..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorChangesCrash.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - width: 400 - height: 400 - - states: State { - name: "reanchored" - AnchorChanges { - anchors.top: container.top - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug.qml b/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug.qml deleted file mode 100644 index 60c537b1ed..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: container - color: "red" - height: 200 - width: 200 - Column { - id: column - objectName: "column" - anchors.left: container.right - anchors.bottom: container.bottom - - Rectangle { - id: rectangle - color: "blue" - height: 100 - width: 200 - } - Rectangle { - color: "blue" - height: 100 - width: 200 - } - } - states: State { - name: "reanchored" - AnchorChanges { - target: column - anchors.left: undefined - anchors.right: container.right - } - PropertyChanges { - target: rectangle - visible: false - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml b/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml deleted file mode 100644 index 574ef473ce..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/anchorRewindBug2.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width:200; height:300 - - Rectangle { - id: rectangle - objectName: "mover" - color: "green" - width:50; height:50 - } - - states: [ - State { - name: "anchored" - AnchorChanges { - target: rectangle - anchors.left: root.left - anchors.right: root.right - anchors.bottom: root.bottom - } - } - ] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/attachedPropertyChanges.qml b/tests/auto/declarative/qdeclarativestates/data/attachedPropertyChanges.qml deleted file mode 100644 index 413af2ee42..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/attachedPropertyChanges.qml +++ /dev/null @@ -1,20 +0,0 @@ -import Qt.test 1.0 -import QtQuick 2.0 - -Item { - id: item - width: 100; height: 100 - MyRectangle.foo: 0 - - states: State { - name: "foo1" - PropertyChanges { - target: item - MyRectangle.foo: 1 - width: 50 - } - } - - Component.onCompleted: item.state = "foo1" -} - diff --git a/tests/auto/declarative/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml b/tests/auto/declarative/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml deleted file mode 100644 index 6cbf524ec2..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int input: 1 - property int test: 9 - - states: [ - State { - name: "portrait" - when: root.input == 1 - PropertyChanges { - target: root - test: 3 - } - } - ] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/avoidFastForward.qml b/tests/auto/declarative/qdeclarativestates/data/avoidFastForward.qml deleted file mode 100644 index 519befc31e..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/avoidFastForward.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: rect - width: 200 - height: 200 - - property int updateCount: 0 - onColorChanged: updateCount++ - - property color aColor: "green" - - states: State { - name: "a" - PropertyChanges { target: rect; color: aColor } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicBinding.qml b/tests/auto/declarative/qdeclarativestates/data/basicBinding.qml deleted file mode 100644 index 59b67d0863..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicBinding.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - property color sourceColor: "blue" - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: sourceColor } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicBinding2.qml b/tests/auto/declarative/qdeclarativestates/data/basicBinding2.qml deleted file mode 100644 index 55f88120aa..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicBinding2.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - property color sourceColor: "red" - width: 100; height: 100 - color: sourceColor - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicBinding3.qml b/tests/auto/declarative/qdeclarativestates/data/basicBinding3.qml deleted file mode 100644 index 361ab0b091..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicBinding3.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - property color sourceColor: "red" - property color sourceColor2: "blue" - width: 100; height: 100 - color: sourceColor - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: sourceColor2 } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicBinding4.qml b/tests/auto/declarative/qdeclarativestates/data/basicBinding4.qml deleted file mode 100644 index b29f0fcf22..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicBinding4.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - property color sourceColor: "blue" - width: 100; height: 100 - color: "red" - states: [ - State { - name: "blue" - PropertyChanges { target: myRectangle; color: sourceColor } - }, - State { - name: "green" - PropertyChanges { target: myRectangle; color: "green" } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicChanges.qml b/tests/auto/declarative/qdeclarativestates/data/basicChanges.qml deleted file mode 100644 index 3e2b73acde..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicChanges.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicChanges2.qml b/tests/auto/declarative/qdeclarativestates/data/basicChanges2.qml deleted file mode 100644 index 5ff46cc60c..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicChanges2.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: [ - State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - }, - State { - name: "green" - PropertyChanges { target: myRectangle; color: "green" } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicChanges3.qml b/tests/auto/declarative/qdeclarativestates/data/basicChanges3.qml deleted file mode 100644 index e46e98f75e..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicChanges3.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: [ - State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - }, - State { - name: "bordered" - PropertyChanges { target: myRectangle; border.width: 2 } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml b/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml deleted file mode 100644 index 7da1e0fb2e..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicChanges4.qml +++ /dev/null @@ -1,19 +0,0 @@ -import Qt.test 1.0 -import QtQuick 2.0 - -MyRectangle { - id: rect - width: 100; height: 100 - color: "red" - - states: State { - name: "aBlueDay" - PropertyChanges { - target: rect - onPropertyWithNotifyChanged: { rect.color = "blue"; } - } - } - - Component.onCompleted: rect.state = "aBlueDay" -} - diff --git a/tests/auto/declarative/qdeclarativestates/data/basicExtension.qml b/tests/auto/declarative/qdeclarativestates/data/basicExtension.qml deleted file mode 100644 index 00f5fee287..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/basicExtension.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: [ - State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - }, - State { - name: "bordered" - extend: "blue" - PropertyChanges { target: myRectangle; border.width: 2 } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/deleting.qml b/tests/auto/declarative/qdeclarativestates/data/deleting.qml deleted file mode 100644 index b8e8d33c17..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/deleting.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue"; objectName: "pc1" } - PropertyChanges { target: myRectangle; radius: 5; objectName: "pc2" } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/deletingState.qml b/tests/auto/declarative/qdeclarativestates/data/deletingState.qml deleted file mode 100644 index 68a9c2a24d..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/deletingState.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - StateGroup { - id: stateGroup - states: State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/editProperties.qml b/tests/auto/declarative/qdeclarativestates/data/editProperties.qml deleted file mode 100644 index 9bff3657ba..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/editProperties.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - property color sourceColor: "blue" - width: 400; height: 400 - color: "red" - - Rectangle { - id: rect2 - objectName: "rect2" - width: parent.width + 2 - height: 200 - color: "yellow" - } - - states: [ - State { - name: "blue" - PropertyChanges { - target: rect2 - width:50 - height: 40 - } - }, - State { - name: "green" - PropertyChanges { - target: rect2 - width: myRectangle.width / 2 - height: myRectangle.width / 4 - } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/explicit.qml b/tests/auto/declarative/qdeclarativestates/data/explicit.qml deleted file mode 100644 index d09893a1db..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/explicit.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - property color sourceColor: "blue" - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { - objectName: "changes" - target: myRectangle; explicit: true - color: sourceColor - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml b/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml deleted file mode 100644 index 573341520d..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/extendsBug.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 200 - - Rectangle { - id: rect - objectName: "greenRect" - width: 100 - height: 100 - color: "green" - } - - states:[ - State { - name: "a" - PropertyChanges { target: rect; x: 100 } - }, - State { - name: "b" - extend:"a" - PropertyChanges { target: rect; y: 100 } - } - ] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/fakeExtension.qml b/tests/auto/declarative/qdeclarativestates/data/fakeExtension.qml deleted file mode 100644 index 6a5c7003f6..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/fakeExtension.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: [ - State { - name: "blue" - PropertyChanges { target: myRectangle; color: "blue" } - }, - State { - name: "green" - extend: "blue" - PropertyChanges { target: myRectangle; color: "green" } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml b/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml deleted file mode 100644 index a2bbd5d32b..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/illegalObj.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: myItem - - states : State { - PropertyChanges { - target: myItem - children: Item { id: newItem } - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/illegalTempState.qml b/tests/auto/declarative/qdeclarativestates/data/illegalTempState.qml deleted file mode 100644 index 9cb39c0728..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/illegalTempState.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: card - width: 100; height: 100 - - states: [ - State { - name: "placed" - PropertyChanges { target: card; state: "idle" } - }, - State { - name: "idle" - } - ] - - MouseArea { - anchors.fill: parent - onClicked: card.state = "placed" - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/image.png b/tests/auto/declarative/qdeclarativestates/data/image.png deleted file mode 100644 index ed1833c95b..0000000000 Binary files a/tests/auto/declarative/qdeclarativestates/data/image.png and /dev/null differ diff --git a/tests/auto/declarative/qdeclarativestates/data/legalTempState.qml b/tests/auto/declarative/qdeclarativestates/data/legalTempState.qml deleted file mode 100644 index a93860f5cc..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/legalTempState.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: card - width: 100; height: 100 - - states: [ - State { - name: "placed" - onCompleted: card.state = "idle" - StateChangeScript { script: console.log("entering placed") } - }, - State { - name: "idle" - StateChangeScript { script: console.log("entering idle") } - } - ] - - MouseArea { - anchors.fill: parent - onClicked: card.state = "placed" - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/nonExistantProp.qml b/tests/auto/declarative/qdeclarativestates/data/nonExistantProp.qml deleted file mode 100644 index ce502699bb..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/nonExistantProp.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { target: myRectangle; colr: "blue" } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml deleted file mode 100644 index 663ad1a264..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange1.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - Item { - x: 10; y: 10 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5 - width: 100; height: 100 - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: -100; y: -50 - Item { - id: newParent - objectName: "NewParent" - x: 248; y: 360 - } - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange2.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange2.qml deleted file mode 100644 index ae290e961e..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange2.qml +++ /dev/null @@ -1,31 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: newParent - width: 400; height: 400 - Item { - scale: .5 - rotation: 15 - x: 10; y: 10 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5 - width: 100; height: 100 - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange3.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange3.qml deleted file mode 100644 index 46665cb4c8..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange3.qml +++ /dev/null @@ -1,42 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - Item { - scale: .5 - rotation: 15 - transformOrigin: "Center" - x: 10; y: 10 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5 - width: 100; height: 100 - transformOrigin: "BottomLeft" - color: "red" - } - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - x: 200; y: 200 - rotation: 52; - scale: 2 - Item { - id: newParent - x: 100; y: 100 - } - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange4.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange4.qml deleted file mode 100644 index 22de72f8c9..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange4.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5; y: 5 - width: 100; height: 100 - color: "red" - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - id: newParent - transform: Scale { xScale: .5; yScale: .7} - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange5.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange5.qml deleted file mode 100644 index c353d2637f..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange5.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5; y: 5 - width: 100; height: 100 - color: "red" - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - id: newParent - transform: Rotation { angle: 30; axis { x: 0; y: 1; z: 0 } } - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/parentChange6.qml b/tests/auto/declarative/qdeclarativestates/data/parentChange6.qml deleted file mode 100644 index b373dbba20..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/parentChange6.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - Rectangle { - id: myRect - objectName: "MyRect" - x: 5; y: 5 - width: 100; height: 100 - color: "red" - } - MouseArea { - id: clickable - anchors.fill: parent - } - - Item { - id: newParent - rotation: 180 - } - - states: State { - name: "reparented" - when: clickable.pressed - ParentChange { - target: myRect - parent: newParent - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/propertyErrors.qml b/tests/auto/declarative/qdeclarativestates/data/propertyErrors.qml deleted file mode 100644 index ddd636493d..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/propertyErrors.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { target: myRectangle; colr: "blue"; activeFocus: true } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/reset.qml b/tests/auto/declarative/qdeclarativestates/data/reset.qml deleted file mode 100644 index f0ecab0950..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/reset.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 640 - height: 480 - Image { - id: image - width: 40 - source: "image.png" - } - - states: State { - name: "state1" - PropertyChanges { - target: image - width: undefined - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/restoreEntryValues.qml b/tests/auto/declarative/qdeclarativestates/data/restoreEntryValues.qml deleted file mode 100644 index 950a522841..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/restoreEntryValues.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - PropertyChanges { - target: myRectangle - restoreEntryValues: false - color: "blue" - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/returnToBase.qml b/tests/auto/declarative/qdeclarativestates/data/returnToBase.qml deleted file mode 100644 index 9a0ee82397..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/returnToBase.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: theRect - property bool triggerState: false - property string stateString: "" - states: [ State { - when: triggerState - PropertyChanges { - target: theRect - stateString: "inState" - } - }, - State { - name: "" - PropertyChanges { - target: theRect - stateString: "originalState" - } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml b/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml deleted file mode 100644 index fbc4bc5ecc..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/revertListBug.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - - property Item targetItem: rect1 - - function switchTargetItem() { - if (targetItem === rect1) - targetItem = rect2; - else - targetItem = rect1; - } - - states: State { - name: "reparented" - ParentChange { - target: targetItem - parent: newParent - x: 0; y: 0 - } - } - - Item { - objectName: "originalParent1" - Rectangle { - id: rect1; objectName: "rect1" - width: 50; height: 50 - color: "green" - } - } - - Item { - objectName: "originalParent2" - Rectangle { - id: rect2; objectName: "rect2" - x: 50; y: 50 - width: 50; height: 50 - color: "green" - } - } - - Item { - id: newParent; objectName: "newParent" - x: 200; y: 100 - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/script.qml b/tests/auto/declarative/qdeclarativestates/data/script.qml deleted file mode 100644 index 218f0fae74..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/script.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: myRectangle - width: 100; height: 100 - color: "red" - states: State { - name: "blue" - StateChangeScript { script: myRectangle.color = "blue"; } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverride.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverride.qml deleted file mode 100644 index 9ab8037e51..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/signalOverride.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -MyRectangle { - id: rect - - onDidSomething: color = "blue" - - width: 100; height: 100 - color: "red" - states: State { - name: "green" - PropertyChanges { - target: rect - onDidSomething: color = "green" - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverride2.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverride2.qml deleted file mode 100644 index 4e5e335b8b..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/signalOverride2.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -MyRectangle { - id: rect - onDidSomething: color = "blue" - width: 100; height: 100 - ExtendedRectangle {} -} diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash.qml deleted file mode 100644 index 3e2ae1e93d..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 -import Qt.test 1.0 - -MyRectangle { - id: rect - - width: 100; height: 100 - states: State { - name: "overridden" - PropertyChanges { - target: rect - onDidSomething: rect.state = "" - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml deleted file mode 100644 index 3937874aa2..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash2.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: myRect - width: 400 - height: 400 - - states: [ - State { - name: "state1" - PropertyChanges { - target: myRect - onHeightChanged: console.log("Hello World") - color: "green" - } - }, - State { - name: "state2"; extend: "state1" - PropertyChanges { - target: myRect - color: "red" - } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml b/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml deleted file mode 100644 index 98d4c57219..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/signalOverrideCrash3.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: myRect - width: 400 - height: 400 - - onHeightChanged: console.log("base state") - - states: [ - State { - name: "state1" - PropertyChanges { - target: myRect - onHeightChanged: console.log("state1") - color: "green" - } - }, - State { - name: "state2"; - PropertyChanges { - target: myRect - onHeightChanged: console.log("state2") - color: "red" - } - }] -} diff --git a/tests/auto/declarative/qdeclarativestates/data/unnamedWhen.qml b/tests/auto/declarative/qdeclarativestates/data/unnamedWhen.qml deleted file mode 100644 index 35eacff07b..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/unnamedWhen.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: theRect - property bool triggerState: false - property string stateString: "" - states: State { - when: triggerState - PropertyChanges { - target: theRect - stateString: "inState" - } - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/urlResolution.qml b/tests/auto/declarative/qdeclarativestates/data/urlResolution.qml deleted file mode 100644 index 516ac034d6..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/urlResolution.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 -import "Implementation" - -Rectangle { - width: 100 - height: 200 - - MyType { - objectName: "MyType" - anchors.fill: parent - } -} diff --git a/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml b/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml deleted file mode 100644 index 92025a2054..0000000000 --- a/tests/auto/declarative/qdeclarativestates/data/whenOrdering.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property bool condition1: false - property bool condition2: false - - states: [ - State { name: "state1"; when: condition1 }, - State { name: "state2"; when: condition2 } - ] -} diff --git a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro b/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro deleted file mode 100644 index c0ffda7828..0000000000 --- a/tests/auto/declarative/qdeclarativestates/qdeclarativestates.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativestates -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativestates.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp deleted file mode 100644 index 2535f89030..0000000000 --- a/tests/auto/declarative/qdeclarativestates/tst_qdeclarativestates.cpp +++ /dev/null @@ -1,1596 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class MyAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(int foo READ foo WRITE setFoo) -public: - MyAttached(QObject *parent) : QObject(parent), m_foo(13) {} - - int foo() const { return m_foo; } - void setFoo(int f) { m_foo = f; } - -private: - int m_foo; -}; - -class MyRect : public QQuickRectangle -{ - Q_OBJECT - Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal) -public: - MyRect() {} - - void doSomething() { emit didSomething(); } - - int propertyWithNotify() const { return m_prop; } - void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); } - - static MyAttached *qmlAttachedProperties(QObject *o) { - return new MyAttached(o); - } -Q_SIGNALS: - void didSomething(); - void oddlyNamedNotifySignal(); - -private: - int m_prop; -}; - -QML_DECLARE_TYPE(MyRect) -QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES) - -class tst_qdeclarativestates : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativestates() {} - -private: - static QByteArray fullDataPath(const QString &path); - -private slots: - void initTestCase(); - - void basicChanges(); - void attachedPropertyChanges(); - void basicExtension(); - void basicBinding(); - void signalOverride(); - void signalOverrideCrash(); - void signalOverrideCrash2(); - void signalOverrideCrash3(); - void parentChange(); - void parentChangeErrors(); - void anchorChanges(); - void anchorChanges2(); - void anchorChanges3(); - void anchorChanges4(); - void anchorChanges5(); - void anchorChangesRTL(); - void anchorChangesRTL2(); - void anchorChangesRTL3(); - void anchorChangesCrash(); - void anchorRewindBug(); - void anchorRewindBug2(); - void script(); - void restoreEntryValues(); - void explicitChanges(); - void propertyErrors(); - void incorrectRestoreBug(); - void autoStateAtStartupRestoreBug(); - void deletingChange(); - void deletingState(); - void tempState(); - void illegalTempState(); - void nonExistantProperty(); - void reset(); - void illegalObjectCreation(); - void whenOrdering(); - void urlResolution(); - void unnamedWhen(); - void returnToBase(); - void extendsBug(); - void editProperties(); - void QTBUG_14830(); - void avoidFastForward(); - void revertListBug(); -}; - -void tst_qdeclarativestates::initTestCase() -{ - qmlRegisterType("Qt.test", 1, 0, "MyRectangle"); -} - -QByteArray tst_qdeclarativestates::fullDataPath(const QString &path) -{ - return QUrl::fromLocalFile(TESTDATA(path)).toString().toUtf8(); -} - -void tst_qdeclarativestates::basicChanges() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState("bordered"); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),2.0); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),1.0); - //### we should be checking that this is an implicit rather than explicit 1 (which currently fails) - - rectPrivate->setState("bordered"); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),2.0); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),1.0); - - } - - { - // Test basicChanges4.qml can magically connect to propertyWithNotify's notify - // signal using 'onPropertyWithNotifyChanged' even though the signal name is - // actually 'oddlyNamedNotifySignal' - - QDeclarativeComponent component(&engine, TESTDATA("basicChanges4.qml")); - QVERIFY(component.isReady()); - - MyRect *rect = qobject_cast(component.create()); - QVERIFY(rect != 0); - - QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify")); - QVERIFY(prop.hasNotifySignal()); - QString notifySignal = QByteArray(prop.notifySignal().signature()); - QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged(")); - - QCOMPARE(rect->color(), QColor(Qt::red)); - - rect->setPropertyWithNotify(100); - QCOMPARE(rect->color(), QColor(Qt::blue)); - } -} - -void tst_qdeclarativestates::attachedPropertyChanges() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent component(&engine, TESTDATA("attachedPropertyChanges.qml")); - QVERIFY(component.isReady()); - - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QCOMPARE(item->width(), 50.0); - - // Ensure attached property has been changed - QObject *attObj = qmlAttachedPropertiesObject(item, false); - QVERIFY(attObj); - - MyAttached *att = qobject_cast(attObj); - QVERIFY(att); - - QCOMPARE(att->foo(), 1); -} - -void tst_qdeclarativestates::basicExtension() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicExtension.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState("bordered"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),2.0); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),1.0); - - rectPrivate->setState("bordered"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->border()->width(),2.0); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->border()->width(),1.0); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("fakeExtension.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - } -} - -void tst_qdeclarativestates::basicBinding() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - rect->setProperty("sourceColor", QColor("green")); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - rect->setProperty("sourceColor", QColor("yellow")); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("yellow")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - rect->setProperty("sourceColor", QColor("green")); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("green")); - rect->setProperty("sourceColor", QColor("yellow")); - QCOMPARE(rect->color(),QColor("yellow")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("yellow")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - rect->setProperty("sourceColor", QColor("green")); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - rect->setProperty("sourceColor", QColor("red")); - QCOMPARE(rect->color(),QColor("blue")); - rect->setProperty("sourceColor2", QColor("yellow")); - QCOMPARE(rect->color(),QColor("yellow")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - rect->setProperty("sourceColor2", QColor("green")); - QCOMPARE(rect->color(),QColor("red")); - rect->setProperty("sourceColor", QColor("yellow")); - QCOMPARE(rect->color(),QColor("yellow")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding4.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - rect->setProperty("sourceColor", QColor("yellow")); - QCOMPARE(rect->color(),QColor("yellow")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - rect->setProperty("sourceColor", QColor("purple")); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("purple")); - - rectPrivate->setState("green"); - QCOMPARE(rect->color(),QColor("green")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - } -} - -void tst_qdeclarativestates::signalOverride() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride.qml")); - MyRect *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - rect->doSomething(); - QCOMPARE(rect->color(),QColor("blue")); - - QQuickItemPrivate::get(rect)->setState("green"); - rect->doSomething(); - QCOMPARE(rect->color(),QColor("green")); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride2.qml")); - MyRect *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("white")); - rect->doSomething(); - QCOMPARE(rect->color(),QColor("blue")); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("extendedRect")); - QQuickItemPrivate::get(innerRect)->setState("green"); - rect->doSomething(); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(innerRect->color(),QColor("green")); - QCOMPARE(innerRect->property("extendedColor").value(),QColor("green")); - } -} - -void tst_qdeclarativestates::signalOverrideCrash() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash.qml")); - MyRect *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate::get(rect)->setState("overridden"); - rect->doSomething(); -} - -void tst_qdeclarativestates::signalOverrideCrash2() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate::get(rect)->setState("state1"); - QQuickItemPrivate::get(rect)->setState("state2"); - QQuickItemPrivate::get(rect)->setState("state1"); - - delete rect; -} - -void tst_qdeclarativestates::signalOverrideCrash3() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate::get(rect)->setState("state1"); - QQuickItemPrivate::get(rect)->setState(""); - QQuickItemPrivate::get(rect)->setState("state2"); - QQuickItemPrivate::get(rect)->setState(""); - - delete rect; -} - -void tst_qdeclarativestates::parentChange() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange1.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickParentChange *pChange = qobject_cast(state->operationAt(0)); - QVERIFY(pChange != 0); - QQuickItem *nParent = qobject_cast(rect->findChild("NewParent")); - QVERIFY(nParent != 0); - - QCOMPARE(pChange->parent(), nParent); - - QQuickItemPrivate::get(rect)->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(0)); - QCOMPARE(innerRect->scale(), qreal(1)); - QCOMPARE(innerRect->x(), qreal(-133)); - QCOMPARE(innerRect->y(), qreal(-300)); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - rectPrivate->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(15)); - QCOMPARE(innerRect->scale(), qreal(.5)); - QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-19.9075)); - QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-8.73433)); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - rectPrivate->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(-37)); - QCOMPARE(innerRect->scale(), qreal(.25)); - QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-217.305)); - QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-164.413)); - - rectPrivate->setState(""); - QCOMPARE(innerRect->rotation(), qreal(0)); - QCOMPARE(innerRect->scale(), qreal(1)); - QCOMPARE(innerRect->x(), qreal(5)); - //do a non-qFuzzyCompare fuzzy compare - QVERIFY(innerRect->y() < qreal(0.00001) && innerRect->y() > qreal(-0.00001)); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange6.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QQuickItemPrivate::get(rect)->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(180)); - QCOMPARE(innerRect->scale(), qreal(1)); - QCOMPARE(innerRect->x(), qreal(-105)); - QCOMPARE(innerRect->y(), qreal(-105)); - } -} - -void tst_qdeclarativestates::parentChangeErrors() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange4.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale"); - QQuickItemPrivate::get(rect)->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(0)); - QCOMPARE(innerRect->scale(), qreal(1)); - QCOMPARE(innerRect->x(), qreal(5)); - QCOMPARE(innerRect->y(), qreal(5)); - } - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange5.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform"); - QQuickItemPrivate::get(rect)->setState("reparented"); - QCOMPARE(innerRect->rotation(), qreal(0)); - QCOMPARE(innerRect->scale(), qreal(1)); - QCOMPARE(innerRect->x(), qreal(5)); - QCOMPARE(innerRect->y(), qreal(5)); - } -} - -void tst_qdeclarativestates::anchorChanges() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - rectPrivate->setState("right"); - QCOMPARE(innerRect->x(), qreal(150)); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all) - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), qreal(5)); - - delete rect; -} - -void tst_qdeclarativestates::anchorChanges2() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - rectPrivate->setState("right"); - QCOMPARE(innerRect->x(), qreal(150)); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), qreal(5)); - - delete rect; -} - -void tst_qdeclarativestates::anchorChanges3() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); - QVERIFY(leftGuideline != 0); - - QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); - QVERIFY(bottomGuideline != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - rectPrivate->setState("reanchored"); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine); - - QCOMPARE(innerRect->x(), qreal(10)); - QCOMPARE(innerRect->y(), qreal(0)); - QCOMPARE(innerRect->width(), qreal(190)); - QCOMPARE(innerRect->height(), qreal(150)); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), qreal(0)); - QCOMPARE(innerRect->y(), qreal(10)); - QCOMPARE(innerRect->width(), qreal(150)); - QCOMPARE(innerRect->height(), qreal(190)); - - delete rect; -} - -void tst_qdeclarativestates::anchorChanges4() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges4.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); - QVERIFY(leftGuideline != 0); - - QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); - QVERIFY(bottomGuideline != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - QQuickItemPrivate::get(rect)->setState("reanchored"); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QQuickItemPrivate::get(leftGuideline)->verticalCenter().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QQuickItemPrivate::get(leftGuideline)->verticalCenter().anchorLine); - - delete rect; -} - -void tst_qdeclarativestates::anchorChanges5() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges5.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - - QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); - QVERIFY(leftGuideline != 0); - - QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); - QVERIFY(bottomGuideline != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - QQuickItemPrivate::get(rect)->setState("reanchored"); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - //QCOMPARE(aChanges->anchors()->horizontalCenter().item, bottomGuideline->horizontalCenter().item); - //QCOMPARE(aChanges->anchors()->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); - //QCOMPARE(aChanges->anchors()->baseline().item, leftGuideline->baseline().item); - //QCOMPARE(aChanges->anchors()->baseline().anchorLine, leftGuideline->baseline().anchorLine); - - delete rect; -} - -void mirrorAnchors(QQuickItem *item) { - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->setLayoutMirror(true); -} - -qreal offsetRTL(QQuickItem *anchorItem, QQuickItem *item) { - return anchorItem->width()+2*anchorItem->x()-item->width(); -} - -void tst_qdeclarativestates::anchorChangesRTL() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - mirrorAnchors(innerRect); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - rectPrivate->setState("right"); - QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150)); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all) - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5)); - - delete rect; -} - -void tst_qdeclarativestates::anchorChangesRTL2() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - mirrorAnchors(innerRect); - - rectPrivate->setState("right"); - QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150)); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(5)); - - delete rect; -} - -void tst_qdeclarativestates::anchorChangesRTL3() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); - QVERIFY(innerRect != 0); - mirrorAnchors(innerRect); - - QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); - QVERIFY(leftGuideline != 0); - - QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); - QVERIFY(bottomGuideline != 0); - - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); - QVERIFY(aChanges != 0); - - rectPrivate->setState("reanchored"); - QCOMPARE(aChanges->object(), qobject_cast(innerRect)); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item); - QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine); - - QCOMPARE(innerRect->x(), offsetRTL(leftGuideline, innerRect) - qreal(10)); - QCOMPARE(innerRect->y(), qreal(0)); - // between left side of parent and leftGuideline.x: 10, which has width 0 - QCOMPARE(innerRect->width(), qreal(10)); - QCOMPARE(innerRect->height(), qreal(150)); - - rectPrivate->setState(""); - QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(0)); - QCOMPARE(innerRect->y(), qreal(10)); - // between right side of parent and left side of rightGuideline.x: 150, which has width 0 - QCOMPARE(innerRect->width(), qreal(50)); - QCOMPARE(innerRect->height(), qreal(190)); - - delete rect; -} - -//QTBUG-9609 -void tst_qdeclarativestates::anchorChangesCrash() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChangesCrash.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate::get(rect)->setState("reanchored"); - - delete rect; -} - -// QTBUG-12273 -void tst_qdeclarativestates::anchorRewindBug() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("anchorRewindBug.qml"))); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - - QQuickRectangle *rect = qobject_cast(view->rootObject()); - QVERIFY(rect != 0); - - QQuickItem * column = rect->findChild("column"); - - QVERIFY(column != 0); - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); - QCOMPARE(column->height(), 200.0); - QQuickItemPrivate::get(rect)->setState("reanchored"); - - // column height and width should stay implicit - // and column's implicit resizing should still work - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); - QTRY_COMPARE(column->height(), 100.0); - - QQuickItemPrivate::get(rect)->setState(""); - - // column height and width should stay implicit - // and column's implicit resizing should still work - QVERIFY(!QQuickItemPrivate::get(column)->heightValid); - QVERIFY(!QQuickItemPrivate::get(column)->widthValid); - QTRY_COMPARE(column->height(), 200.0); - - delete view; -} - -// QTBUG-11834 -void tst_qdeclarativestates::anchorRewindBug2() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorRewindBug2.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QQuickRectangle *mover = rect->findChild("mover"); - - QVERIFY(mover != 0); - QCOMPARE(mover->y(), qreal(0.0)); - QCOMPARE(mover->width(), qreal(50.0)); - - QQuickItemPrivate::get(rect)->setState("anchored"); - QCOMPARE(mover->y(), qreal(250.0)); - QCOMPARE(mover->width(), qreal(200.0)); - - QQuickItemPrivate::get(rect)->setState(""); - QCOMPARE(mover->y(), qreal(0.0)); - QCOMPARE(mover->width(), qreal(50.0)); - - delete rect; -} - -void tst_qdeclarativestates::script() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent rectComponent(&engine, TESTDATA("script.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted - } -} - -void tst_qdeclarativestates::restoreEntryValues() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("restoreEntryValues.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("blue")); -} - -void tst_qdeclarativestates::explicitChanges() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("explicit.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QDeclarativeListReference list(rect, "states"); - QDeclarativeState *state = qobject_cast(list.at(0)); - QVERIFY(state != 0); - - qmlExecuteDeferred(state); - QDeclarativePropertyChanges *changes = qobject_cast(rect->findChild("changes")); - QVERIFY(changes != 0); - QVERIFY(changes->isExplicit()); - - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rect->setProperty("sourceColor", QColor("green")); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - rect->setProperty("sourceColor", QColor("yellow")); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("yellow")); -} - -void tst_qdeclarativestates::propertyErrors() -{ - QDeclarativeEngine engine; - QDeclarativeComponent rectComponent(&engine, TESTDATA("propertyErrors.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QCOMPARE(rect->color(),QColor("red")); - - QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\""); - QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\""); - QQuickItemPrivate::get(rect)->setState("blue"); -} - -void tst_qdeclarativestates::incorrectRestoreBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QCOMPARE(rect->color(),QColor("red")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - // make sure if we change the base state value, we then restore to it correctly - rect->setColor(QColor("green")); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("green")); -} - -void tst_qdeclarativestates::autoStateAtStartupRestoreBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent component(&engine, TESTDATA("autoStateAtStartupRestoreBug.qml")); - QObject *obj = component.create(); - - QVERIFY(obj != 0); - QCOMPARE(obj->property("test").toInt(), 3); - - obj->setProperty("input", 2); - - QCOMPARE(obj->property("test").toInt(), 9); - - delete obj; -} - -void tst_qdeclarativestates::deletingChange() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("deleting.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - QCOMPARE(rect->radius(),qreal(5)); - - rectPrivate->setState(""); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->radius(),qreal(0)); - - QDeclarativePropertyChanges *pc = rect->findChild("pc1"); - QVERIFY(pc != 0); - delete pc; - - QDeclarativeState *state = rect->findChild(); - QVERIFY(state != 0); - qmlExecuteDeferred(state); - QCOMPARE(state->operationCount(), 1); - - rectPrivate->setState("blue"); - QCOMPARE(rect->color(),QColor("red")); - QCOMPARE(rect->radius(),qreal(5)); - - delete rect; -} - -void tst_qdeclarativestates::deletingState() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("deletingState.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - - QDeclarativeStateGroup *sg = rect->findChild(); - QVERIFY(sg != 0); - QVERIFY(sg->findState("blue") != 0); - - sg->setState("blue"); - QCOMPARE(rect->color(),QColor("blue")); - - sg->setState(""); - QCOMPARE(rect->color(),QColor("red")); - - QDeclarativeState *state = rect->findChild(); - QVERIFY(state != 0); - delete state; - - QVERIFY(sg->findState("blue") == 0); - - //### should we warn that state doesn't exist - sg->setState("blue"); - QCOMPARE(rect->color(),QColor("red")); - - delete rect; -} - -void tst_qdeclarativestates::tempState() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("legalTempState.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QTest::ignoreMessage(QtDebugMsg, "entering placed"); - QTest::ignoreMessage(QtDebugMsg, "entering idle"); - rectPrivate->setState("placed"); - QCOMPARE(rectPrivate->state(), QLatin1String("idle")); -} - -void tst_qdeclarativestates::illegalTempState() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("illegalTempState.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QTest::ignoreMessage(QtWarningMsg, ": QML StateGroup: Can't apply a state change as part of a state definition."); - rectPrivate->setState("placed"); - QCOMPARE(rectPrivate->state(), QLatin1String("placed")); -} - -void tst_qdeclarativestates::nonExistantProperty() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent rectComponent(&engine, TESTDATA("nonExistantProp.qml")); - QQuickRectangle *rect = qobject_cast(rectComponent.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QTest::ignoreMessage(QtWarningMsg, fullDataPath("nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\""); - rectPrivate->setState("blue"); - QCOMPARE(rectPrivate->state(), QLatin1String("blue")); -} - -void tst_qdeclarativestates::reset() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("reset.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickImage *image = rect->findChild(); - QVERIFY(image != 0); - QCOMPARE(image->width(), qreal(40.)); - QCOMPARE(image->height(), qreal(20.)); - - QQuickItemPrivate::get(rect)->setState("state1"); - - QCOMPARE(image->width(), 20.0); - QCOMPARE(image->height(), qreal(20.)); - - delete rect; -} - -void tst_qdeclarativestates::illegalObjectCreation() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent component(&engine, TESTDATA("illegalObj.qml")); - QList errors = component.errors(); - QVERIFY(errors.count() == 1); - const QDeclarativeError &error = errors.at(0); - QCOMPARE(error.line(), 9); - QCOMPARE(error.column(), 23); - QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects."); -} - -void tst_qdeclarativestates::whenOrdering() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("whenOrdering.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QCOMPARE(rectPrivate->state(), QLatin1String("")); - rect->setProperty("condition2", true); - QCOMPARE(rectPrivate->state(), QLatin1String("state2")); - rect->setProperty("condition1", true); - QCOMPARE(rectPrivate->state(), QLatin1String("state1")); - rect->setProperty("condition2", false); - QCOMPARE(rectPrivate->state(), QLatin1String("state1")); - rect->setProperty("condition2", true); - QCOMPARE(rectPrivate->state(), QLatin1String("state1")); - rect->setProperty("condition1", false); - rect->setProperty("condition2", false); - QCOMPARE(rectPrivate->state(), QLatin1String("")); -} - -void tst_qdeclarativestates::urlResolution() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("urlResolution.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickItem *myType = rect->findChild("MyType"); - QQuickImage *image1 = rect->findChild("image1"); - QQuickImage *image2 = rect->findChild("image2"); - QQuickImage *image3 = rect->findChild("image3"); - QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0); - - QQuickItemPrivate::get(myType)->setState("SetImageState"); - QUrl resolved = QUrl::fromLocalFile(TESTDATA("Implementation/images/qt-logo.png")); - QCOMPARE(image1->source(), resolved); - QCOMPARE(image2->source(), resolved); - QCOMPARE(image3->source(), resolved); - - delete rect; -} - -void tst_qdeclarativestates::unnamedWhen() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("unnamedWhen.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QCOMPARE(rectPrivate->state(), QLatin1String("")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); - rect->setProperty("triggerState", true); - QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState")); - rect->setProperty("triggerState", false); - QCOMPARE(rectPrivate->state(), QLatin1String("")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); -} - -void tst_qdeclarativestates::returnToBase() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("returnToBase.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QCOMPARE(rectPrivate->state(), QLatin1String("")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); - rect->setProperty("triggerState", true); - QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState")); - rect->setProperty("triggerState", false); - QCOMPARE(rectPrivate->state(), QLatin1String("")); - QCOMPARE(rect->property("stateString").toString(), QLatin1String("originalState")); -} - -//QTBUG-12559 -void tst_qdeclarativestates::extendsBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("extendsBug.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QQuickRectangle *greenRect = rect->findChild("greenRect"); - - rectPrivate->setState("b"); - QCOMPARE(greenRect->x(), qreal(100)); - QCOMPARE(greenRect->y(), qreal(100)); -} - -void tst_qdeclarativestates::editProperties() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("editProperties.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QDeclarativeStateGroup *stateGroup = rectPrivate->_states(); - QVERIFY(stateGroup != 0); - qmlExecuteDeferred(stateGroup); - - QDeclarativeState *blueState = stateGroup->findState("blue"); - QVERIFY(blueState != 0); - qmlExecuteDeferred(blueState); - - QDeclarativePropertyChanges *propertyChangesBlue = qobject_cast(blueState->operationAt(0)); - QVERIFY(propertyChangesBlue != 0); - - QDeclarativeState *greenState = stateGroup->findState("green"); - QVERIFY(greenState != 0); - qmlExecuteDeferred(greenState); - - QDeclarativePropertyChanges *propertyChangesGreen = qobject_cast(greenState->operationAt(0)); - QVERIFY(propertyChangesGreen != 0); - - QQuickRectangle *childRect = rect->findChild("rect2"); - QVERIFY(childRect != 0); - QCOMPARE(childRect->width(), qreal(402)); - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - QCOMPARE(childRect->height(), qreal(200)); - - rectPrivate->setState("blue"); - QCOMPARE(childRect->width(), qreal(50)); - QCOMPARE(childRect->height(), qreal(40)); - QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - QVERIFY(blueState->bindingInRevertList(childRect, "width")); - - - rectPrivate->setState("green"); - QCOMPARE(childRect->width(), qreal(200)); - QCOMPARE(childRect->height(), qreal(100)); - QVERIFY(greenState->bindingInRevertList(childRect, "width")); - - - rectPrivate->setState(""); - - - QCOMPARE(propertyChangesBlue->actions().length(), 2); - QVERIFY(propertyChangesBlue->containsValue("width")); - QVERIFY(!propertyChangesBlue->containsProperty("x")); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); - QVERIFY(!propertyChangesBlue->value("x").isValid()); - - propertyChangesBlue->changeValue("width", 60); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); - QCOMPARE(propertyChangesBlue->actions().length(), 2); - - - propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); - QVERIFY(!propertyChangesBlue->containsValue("width")); - QVERIFY(propertyChangesBlue->containsExpression("width")); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); - QCOMPARE(propertyChangesBlue->actions().length(), 2); - - propertyChangesBlue->changeValue("width", 50); - QVERIFY(propertyChangesBlue->containsValue("width")); - QVERIFY(!propertyChangesBlue->containsExpression("width")); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); - QCOMPARE(propertyChangesBlue->actions().length(), 2); - - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - rectPrivate->setState("blue"); - QCOMPARE(childRect->width(), qreal(50)); - QCOMPARE(childRect->height(), qreal(40)); - - propertyChangesBlue->changeValue("width", 60); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); - QCOMPARE(propertyChangesBlue->actions().length(), 2); - QCOMPARE(childRect->width(), qreal(60)); - QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - - propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); - QVERIFY(!propertyChangesBlue->containsValue("width")); - QVERIFY(propertyChangesBlue->containsExpression("width")); - QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); - QCOMPARE(propertyChangesBlue->actions().length(), 2); - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - QCOMPARE(childRect->width(), qreal(200)); - - propertyChangesBlue->changeValue("width", 50); - QCOMPARE(childRect->width(), qreal(50)); - - rectPrivate->setState(""); - QCOMPARE(childRect->width(), qreal(402)); - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - - QCOMPARE(propertyChangesGreen->actions().length(), 2); - rectPrivate->setState("green"); - QCOMPARE(childRect->width(), qreal(200)); - QCOMPARE(childRect->height(), qreal(100)); - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - QVERIFY(greenState->bindingInRevertList(childRect, "width")); - QCOMPARE(propertyChangesGreen->actions().length(), 2); - - - propertyChangesGreen->removeProperty("height"); - QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "height"))); - QCOMPARE(childRect->height(), qreal(200)); - - QVERIFY(greenState->bindingInRevertList(childRect, "width")); - QVERIFY(greenState->containsPropertyInRevertList(childRect, "width")); - propertyChangesGreen->removeProperty("width"); - QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); - QCOMPARE(childRect->width(), qreal(402)); - QVERIFY(!greenState->bindingInRevertList(childRect, "width")); - QVERIFY(!greenState->containsPropertyInRevertList(childRect, "width")); - - propertyChangesBlue->removeProperty("width"); - QCOMPARE(childRect->width(), qreal(402)); - - rectPrivate->setState("blue"); - QCOMPARE(childRect->width(), qreal(402)); - QCOMPARE(childRect->height(), qreal(40)); -} - -void tst_qdeclarativestates::QTBUG_14830() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("QTBUG-14830.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - QQuickItem *item = rect->findChild("area"); - - QCOMPARE(item->width(), qreal(171)); -} - -void tst_qdeclarativestates::avoidFastForward() -{ - QDeclarativeEngine engine; - - //shouldn't fast forward if there isn't a transition - QDeclarativeComponent c(&engine, TESTDATA("avoidFastForward.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - rectPrivate->setState("a"); - QCOMPARE(rect->property("updateCount").toInt(), 1); -} - -//QTBUG-22583 -void tst_qdeclarativestates::revertListBug() -{ - QDeclarativeEngine engine; - - QDeclarativeComponent c(&engine, TESTDATA("revertListBug.qml")); - QQuickRectangle *rect = qobject_cast(c.create()); - QVERIFY(rect != 0); - - QQuickRectangle *rect1 = rect->findChild("rect1"); - QQuickRectangle *rect2 = rect->findChild("rect2"); - QQuickItem *origParent1 = rect->findChild("originalParent1"); - QQuickItem *origParent2 = rect->findChild("originalParent2"); - QQuickItem *newParent = rect->findChild("newParent"); - - QCOMPARE(rect1->parentItem(), origParent1); - QCOMPARE(rect2->parentItem(), origParent2); - - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - rectPrivate->setState("reparented"); - - QCOMPARE(rect1->parentItem(), newParent); - QCOMPARE(rect2->parentItem(), origParent2); - - rectPrivate->setState(""); - - QCOMPARE(rect1->parentItem(), origParent1); - QCOMPARE(rect2->parentItem(), origParent2); - - QMetaObject::invokeMethod(rect, "switchTargetItem"); - - rectPrivate->setState("reparented"); - - QCOMPARE(rect1->parentItem(), origParent1); - QCOMPARE(rect2->parentItem(), newParent); - - rectPrivate->setState(""); - - QCOMPARE(rect1->parentItem(), origParent1); - QCOMPARE(rect2->parentItem(), origParent2); //QTBUG-22583 causes rect2's parent item to be origParent1 -} - -QTEST_MAIN(tst_qdeclarativestates) - -#include "tst_qdeclarativestates.moc" diff --git a/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro b/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro deleted file mode 100644 index 70e6fafe59..0000000000 --- a/tests/auto/declarative/qdeclarativestyledtext/qdeclarativestyledtext.pro +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativestyledtext -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativestyledtext.cpp - -CONFIG += parallel_test -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp b/tests/auto/declarative/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp deleted file mode 100644 index b09c33302e..0000000000 --- a/tests/auto/declarative/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include - -class tst_qdeclarativestyledtext : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativestyledtext() - { - } - -private slots: - void textOutput(); - void textOutput_data(); -}; - -// For malformed input all we test is that we get the expected text out. -// -void tst_qdeclarativestyledtext::textOutput_data() -{ - QTest::addColumn("input"); - QTest::addColumn("output"); - - QTest::newRow("bold") << "bold" << "bold"; - QTest::newRow("italic") << "italic" << "italic"; - QTest::newRow("missing >") << "text") << "text") << "text<" << "text"; - QTest::newRow("missing ") << "text" << "text"; - QTest::newRow("bad nest") << "text italic" << "text italic"; - QTest::newRow("font color") << "red text" << "red text"; - QTest::newRow("font color: single quote") << "red text" << "red text"; - QTest::newRow("font size") << "text" << "text"; - QTest::newRow("font empty") << "text" << "text"; - QTest::newRow("font bad 1") << "text" << "text"; - QTest::newRow("font bad 2") << "text" << ""; - QTest::newRow("extra close") << "text" << "text"; - QTest::newRow("extra space") << "text" << "text"; - QTest::newRow("entities") << "<b>this & that</b>" << "this & that"; - QTest::newRow("newline") << "text
more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") ; - QTest::newRow("self-closing newline") << "text
more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") ; - QTest::newRow("empty") << "" << ""; -} - -void tst_qdeclarativestyledtext::textOutput() -{ - QFETCH(QString, input); - QFETCH(QString, output); - - QTextLayout layout; - QDeclarativeStyledText::parse(input, layout); - - QCOMPARE(layout.text(), output); -} - - -QTEST_MAIN(tst_qdeclarativestyledtext) - -#include "tst_qdeclarativestyledtext.moc" diff --git a/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro b/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro deleted file mode 100644 index 4eee37678f..0000000000 --- a/tests/auto/declarative/qdeclarativesystempalette/qdeclarativesystempalette.pro +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativesystempalette -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativesystempalette.cpp - -CONFIG += parallel_test -QT += core-private gui-private declarative-private widgets testlib diff --git a/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp b/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp deleted file mode 100644 index 8c9543273c..0000000000 --- a/tests/auto/declarative/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include - -class tst_qdeclarativesystempalette : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativesystempalette(); - -private slots: - void activePalette(); - void inactivePalette(); - void disabledPalette(); - void paletteChanged(); - -private: - QDeclarativeEngine engine; -}; - -tst_qdeclarativesystempalette::tst_qdeclarativesystempalette() -{ -} - -void tst_qdeclarativesystempalette::activePalette() -{ - QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeSystemPalette *object = qobject_cast(component.create()); - - QVERIFY(object != 0); - - QPalette palette; - palette.setCurrentColorGroup(QPalette::Active); - QCOMPARE(palette.window().color(), object->window()); - QCOMPARE(palette.windowText().color(), object->windowText()); - QCOMPARE(palette.base().color(), object->base()); - QCOMPARE(palette.text().color(), object->text()); - QCOMPARE(palette.alternateBase().color(), object->alternateBase()); - QCOMPARE(palette.button().color(), object->button()); - QCOMPARE(palette.buttonText().color(), object->buttonText()); - QCOMPARE(palette.light().color(), object->light()); - QCOMPARE(palette.midlight().color(), object->midlight()); - QCOMPARE(palette.dark().color(), object->dark()); - QCOMPARE(palette.mid().color(), object->mid()); - QCOMPARE(palette.shadow().color(), object->shadow()); - QCOMPARE(palette.highlight().color(), object->highlight()); - QCOMPARE(palette.highlightedText().color(), object->highlightedText()); - - delete object; -} - -void tst_qdeclarativesystempalette::inactivePalette() -{ - QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Inactive }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeSystemPalette *object = qobject_cast(component.create()); - - QVERIFY(object != 0); - QVERIFY(object->colorGroup() == QDeclarativeSystemPalette::Inactive); - - QPalette palette; - palette.setCurrentColorGroup(QPalette::Inactive); - QCOMPARE(palette.window().color(), object->window()); - QCOMPARE(palette.windowText().color(), object->windowText()); - QCOMPARE(palette.base().color(), object->base()); - QCOMPARE(palette.text().color(), object->text()); - QCOMPARE(palette.alternateBase().color(), object->alternateBase()); - QCOMPARE(palette.button().color(), object->button()); - QCOMPARE(palette.buttonText().color(), object->buttonText()); - QCOMPARE(palette.light().color(), object->light()); - QCOMPARE(palette.midlight().color(), object->midlight()); - QCOMPARE(palette.dark().color(), object->dark()); - QCOMPARE(palette.mid().color(), object->mid()); - QCOMPARE(palette.shadow().color(), object->shadow()); - QCOMPARE(palette.highlight().color(), object->highlight()); - QCOMPARE(palette.highlightedText().color(), object->highlightedText()); - - delete object; -} - -void tst_qdeclarativesystempalette::disabledPalette() -{ - QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Disabled }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeSystemPalette *object = qobject_cast(component.create()); - - QVERIFY(object != 0); - QVERIFY(object->colorGroup() == QDeclarativeSystemPalette::Disabled); - - QPalette palette; - palette.setCurrentColorGroup(QPalette::Disabled); - QCOMPARE(palette.window().color(), object->window()); - QCOMPARE(palette.windowText().color(), object->windowText()); - QCOMPARE(palette.base().color(), object->base()); - QCOMPARE(palette.text().color(), object->text()); - QCOMPARE(palette.alternateBase().color(), object->alternateBase()); - QCOMPARE(palette.button().color(), object->button()); - QCOMPARE(palette.buttonText().color(), object->buttonText()); - QCOMPARE(palette.light().color(), object->light()); - QCOMPARE(palette.midlight().color(), object->midlight()); - QCOMPARE(palette.dark().color(), object->dark()); - QCOMPARE(palette.mid().color(), object->mid()); - QCOMPARE(palette.shadow().color(), object->shadow()); - QCOMPARE(palette.highlight().color(), object->highlight()); - QCOMPARE(palette.highlightedText().color(), object->highlightedText()); - - delete object; -} - -void tst_qdeclarativesystempalette::paletteChanged() -{ - QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QDeclarativeSystemPalette *object = qobject_cast(component.create()); - - QVERIFY(object != 0); - - QPalette p; - p.setCurrentColorGroup(QPalette::Active); - p.setColor(QPalette::Active, QPalette::Text, QColor("red")); - p.setColor(QPalette::Active, QPalette::ButtonText, QColor("green")); - p.setColor(QPalette::Active, QPalette::WindowText, QColor("blue")); - - qApp->setPalette(p); - - object->setColorGroup(QDeclarativeSystemPalette::Active); - QTRY_COMPARE(QColor("red"), object->text()); - QTRY_COMPARE(QColor("green"), object->buttonText()); - QTRY_COMPARE(QColor("blue"), object->windowText()); - - delete object; -} - -QTEST_MAIN(tst_qdeclarativesystempalette) - -#include "tst_qdeclarativesystempalette.moc" diff --git a/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro b/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro deleted file mode 100644 index 60e59f01f6..0000000000 --- a/tests/auto/declarative/qdeclarativetimer/qdeclarativetimer.pro +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativetimer -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativetimer.cpp - -CONFIG += parallel_test -QT += core-private gui-private declarative-private gui testlib diff --git a/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp b/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp deleted file mode 100644 index 1e795099e8..0000000000 --- a/tests/auto/declarative/qdeclarativetimer/tst_qdeclarativetimer.cpp +++ /dev/null @@ -1,334 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -class tst_qdeclarativetimer : public QObject -{ - Q_OBJECT -public: - tst_qdeclarativetimer(); - -private slots: - void notRepeating(); - void notRepeatingStart(); - void repeat(); - void noTriggerIfNotRunning(); - void triggeredOnStart(); - void triggeredOnStartRepeat(); - void changeDuration(); - void restart(); - void parentProperty(); -}; - -class TimerHelper : public QObject -{ - Q_OBJECT -public: - TimerHelper() : QObject(), count(0) - { - } - - int count; - -public slots: - void timeout() { - ++count; - } -}; - -#define TIMEOUT_TIMEOUT 200 - -tst_qdeclarativetimer::tst_qdeclarativetimer() -{ -} - -void tst_qdeclarativetimer::notRepeating() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - QVERIFY(timer->isRunning()); - QVERIFY(!timer->isRepeating()); - QCOMPARE(timer->interval(), 100); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 1); - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 1); - QVERIFY(timer->isRunning() == false); -} - -void tst_qdeclarativetimer::notRepeatingStart() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100 }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - QVERIFY(!timer->isRunning()); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 0); - - timer->start(); - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 1); - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 1); - QVERIFY(timer->isRunning() == false); - - delete timer; -} - -void tst_qdeclarativetimer::repeat() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; repeat: true; running: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - QCOMPARE(helper.count, 0); - - QTest::qWait(TIMEOUT_TIMEOUT); - QVERIFY(helper.count > 0); - int oldCount = helper.count; - - QTest::qWait(TIMEOUT_TIMEOUT); - QVERIFY(helper.count > oldCount); - QVERIFY(timer->isRunning()); - - oldCount = helper.count; - timer->stop(); - - QTest::qWait(TIMEOUT_TIMEOUT); - QVERIFY(helper.count == oldCount); - QVERIFY(timer->isRunning() == false); - - QSignalSpy spy(timer, SIGNAL(repeatChanged())); - - timer->setRepeating(false); - QVERIFY(!timer->isRepeating()); - QCOMPARE(spy.count(),1); - - timer->setRepeating(false); - QCOMPARE(spy.count(),1); - - timer->setRepeating(true); - QCOMPARE(spy.count(),2); - - delete timer; -} - -void tst_qdeclarativetimer::triggeredOnStart() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true; triggeredOnStart: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - QVERIFY(timer->triggeredOnStart()); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - QTest::qWait(1); - QCOMPARE(helper.count, 1); - - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 2); - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(helper.count, 2); - QVERIFY(timer->isRunning() == false); - - QSignalSpy spy(timer, SIGNAL(triggeredOnStartChanged())); - - timer->setTriggeredOnStart(false); - QVERIFY(!timer->triggeredOnStart()); - QCOMPARE(spy.count(),1); - - timer->setTriggeredOnStart(false); - QCOMPARE(spy.count(),1); - - timer->setTriggeredOnStart(true); - QCOMPARE(spy.count(),2); - - delete timer; -} - -void tst_qdeclarativetimer::triggeredOnStartRepeat() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true; triggeredOnStart: true; repeat: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - QTest::qWait(1); - QCOMPARE(helper.count, 1); - - QTest::qWait(TIMEOUT_TIMEOUT); - QVERIFY(helper.count > 1); - int oldCount = helper.count; - QTest::qWait(TIMEOUT_TIMEOUT); - QVERIFY(helper.count > oldCount); - QVERIFY(timer->isRunning()); - - delete timer; -} - -void tst_qdeclarativetimer::noTriggerIfNotRunning() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray( - "import QtQuick 2.0\n" - "Item { property bool ok: true\n" - "Timer { id: t1; interval: 100; repeat: true; running: true; onTriggered: if (!running) ok=false }" - "Timer { interval: 10; running: true; onTriggered: t1.running=false }" - "}" - ), QUrl::fromLocalFile("")); - QObject *item = component.create(); - QVERIFY(item != 0); - QTest::qWait(TIMEOUT_TIMEOUT); - QCOMPARE(item->property("ok").toBool(), true); - - delete item; -} - -void tst_qdeclarativetimer::changeDuration() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 200; repeat: true; running: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - QCOMPARE(helper.count, 0); - - QTest::qWait(500); - QCOMPARE(helper.count, 2); - - timer->setInterval(500); - - QTest::qWait(600); - QCOMPARE(helper.count, 3); - QVERIFY(timer->isRunning()); - - QSignalSpy spy(timer, SIGNAL(intervalChanged())); - - timer->setInterval(200); - QCOMPARE(timer->interval(), 200); - QCOMPARE(spy.count(),1); - - timer->setInterval(200); - QCOMPARE(spy.count(),1); - - timer->setInterval(300); - QCOMPARE(spy.count(),2); - - delete timer; -} - -void tst_qdeclarativetimer::restart() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 500; repeat: true; running: true }"), QUrl::fromLocalFile("")); - QDeclarativeTimer *timer = qobject_cast(component.create()); - QVERIFY(timer != 0); - - TimerHelper helper; - connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); - QCOMPARE(helper.count, 0); - - QTest::qWait(600); - QCOMPARE(helper.count, 1); - - QTest::qWait(300); - - timer->restart(); - - QTest::qWait(700); - - QCOMPARE(helper.count, 2); - QVERIFY(timer->isRunning()); - - delete timer; -} - -void tst_qdeclarativetimer::parentProperty() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nItem { Timer { objectName: \"timer\"; running: parent.visible } }"), QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item != 0); - QDeclarativeTimer *timer = item->findChild("timer"); - QVERIFY(timer != 0); - - QVERIFY(timer->isRunning()); - - delete timer; -} - -QTEST_MAIN(tst_qdeclarativetimer) - -#include "tst_qdeclarativetimer.moc" diff --git a/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp index be257fdc41..da84167148 100644 --- a/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp +++ b/tests/auto/declarative/qdeclarativetranslation/tst_qdeclarativetranslation.cpp @@ -43,7 +43,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" class tst_qdeclarativetranslation : public QObject { diff --git a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp index db0e05bcf2..c6880b96ce 100644 --- a/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp +++ b/tests/auto/declarative/qdeclarativevaluetypes/tst_qdeclarativevaluetypes.cpp @@ -44,7 +44,7 @@ #include #include #include -#include "../shared/util.h" +#include "../../shared/util.h" #include "testtypes.h" QT_BEGIN_NAMESPACE diff --git a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp index eb3413ec10..7dccbb35a0 100644 --- a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp +++ b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp @@ -50,7 +50,7 @@ #include #include -#include "../shared/util.h" +#include "../../shared/util.h" inline QUrl TEST_FILE(const QString &filename) { diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro index 0e6073b503..5715f3c114 100644 --- a/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro +++ b/tests/auto/declarative/qdeclarativexmlhttprequest/qdeclarativexmlhttprequest.pro @@ -2,11 +2,11 @@ CONFIG += testcase TARGET = tst_qdeclarativexmlhttprequest macx:CONFIG -= app_bundle -INCLUDEPATH += ../shared/ -HEADERS += ../shared/testhttpserver.h +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h SOURCES += tst_qdeclarativexmlhttprequest.cpp \ - ../shared/testhttpserver.cpp + ../../shared/testhttpserver.cpp testDataFiles.files = data testDataFiles.path = . diff --git a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp index 1caec581cc..da5431c50b 100644 --- a/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp +++ b/tests/auto/declarative/qdeclarativexmlhttprequest/tst_qdeclarativexmlhttprequest.cpp @@ -45,7 +45,7 @@ #include #include #include "testhttpserver.h" -#include "../shared/util.h" +#include "../../shared/util.h" #define SERVER_PORT 14445 diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/empty.xml b/tests/auto/declarative/qdeclarativexmllistmodel/data/empty.xml deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/get.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/get.qml deleted file mode 100644 index 509da7174b..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/get.qml +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { name: "name"; query: "name/string()" } - XmlRole { name: "type"; query: "type/string()" } - XmlRole { name: "age"; query: "age/number()" } - XmlRole { name: "size"; query: "size/string()" } - - id: root - - property bool preTest: false - property bool postTest: false - - function runPreTest() { - if (root.get(0) != undefined) - return; - - preTest = true; - } - - function runPostTest() { - if (root.get(-1) != undefined) - return; - - var row = root.get(0); - if (row.name != "Polly" || - row.type != "Parrot" || - row.age != 12 || - row.size != "Small") - return; - - row = root.get(1); - if (row.name != "Penny" || - row.type != "Turtle" || - row.age != 4 || - row.size != "Small") - return; - - row = root.get(7); - if (row.name != "Rover" || - row.type != "Dog" || - row.age != 0 || - row.size != "Large") - return; - - row = root.get(8); - if (row.name != "Tiny" || - row.type != "Elephant" || - row.age != 15 || - row.size != "Large") - return; - - if (root.get(9) != undefined) - return; - - postTest = true; - } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/model.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/model.qml deleted file mode 100644 index 2df3927479..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/model.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { name: "name"; query: "name/string()" } - XmlRole { name: "type"; query: "type/string()" } - XmlRole { name: "age"; query: "age/number()" } - XmlRole { name: "size"; query: "size/string()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/model.xml b/tests/auto/declarative/qdeclarativexmllistmodel/data/model.xml deleted file mode 100644 index 40cd6d0432..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/model.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - Polly - Parrot - 12 - Small - - - Penny - Turtle - 4 - Small - - - Warren - Rabbit - 2 - Small - - - Spot - Dog - 9 - Medium - - - Whiskers - Cat - 2 - Medium - - - Joey - Kangaroo - 1 - - - Kimba - Bunny - 65 - Large - - - Rover - Dog - Large - - - Tiny - Elephant - 15 - Large - - diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.xml b/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.xml deleted file mode 100644 index dab2ec6dc0..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/model2.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - Polly - Parrot - 12 - Small - - - Penny - Turtle - 4 - Small - - diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/propertychanges.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/propertychanges.qml deleted file mode 100644 index f8a97bffc3..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/propertychanges.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { objectName: "role"; name: "name"; query: "name/string()" } - XmlRole { name: "type"; query: "type/string()" } - XmlRole { name: "age"; query: "age/number()" } - XmlRole { name: "size"; query: "size/string()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.qml deleted file mode 100644 index dc609e95e3..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "recipes.xml" - query: "/recipes/recipe" - XmlRole { name: "title"; query: "@title/string()" } - XmlRole { name: "picture"; query: "picture/string()" } - XmlRole { name: "ingredients"; query: "ingredients/string()" } - XmlRole { name: "preparation"; query: "method/string()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.xml b/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.xml deleted file mode 100644 index d71de60710..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/recipes.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - content/pics/pancakes.jpg - -
    -
  • 1 cup (150g) self-raising flour -
  • 1 tbs caster sugar -
  • 3/4 cup (185ml) milk -
  • 1 egg -
- - ]]>
- -
    -
  1. Sift flour and sugar together into a bowl. Add a pinch of salt. -
  2. Beat milk and egg together, then add to dry ingredients. Beat until smooth. -
  3. Pour mixture into a pan on medium heat and cook until bubbles appear on the surface. -
  4. Turn over and cook other side until golden. -
- - ]]>
-
- - content/pics/fruit-salad.jpg - - - - - content/pics/vegetable-soup.jpg - -
    -
  • 1 onion -
  • 1 turnip -
  • 1 potato -
  • 1 carrot -
  • 1 head of celery -
  • 1 1/2 litres of water -
- - ]]>
- -
    -
  1. Chop vegetables. -
  2. Boil in water until vegetables soften. -
  3. Season with salt and pepper to taste. -
- - ]]>
-
- - content/pics/hamburger.jpg - -
    -
  • 500g minced beef -
  • Seasoning -
  • lettuce, tomato, onion, cheese -
  • 1 hamburger bun for each burger -
- - ]]>
- -
    -
  1. Mix the beef, together with seasoning, in a food processor. -
  2. Shape the beef into burgers. -
  3. Grill the burgers for about 5 mins on each side (until cooked through) -
  4. Serve each burger on a bun with ketchup, cheese, lettuce, tomato and onion. -
- - ]]>
-
- - content/pics/lemonade.jpg - -
    -
  • 1 cup Lemon Juice -
  • 1 cup Sugar -
  • 6 Cups of Water (2 cups warm water, 4 cups cold water) -
- - ]]>
- -
    -
  1. Pour 2 cups of warm water into a pitcher and stir in sugar until it dissolves. -
  2. Pour in lemon juice, stir again, and add 4 cups of cold water. -
  3. Chill or serve over ice cubes. -
- - ]]>
-
-
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml deleted file mode 100644 index 6a7059bb45..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleCrash.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - id: model - XmlRole {} - Component.onCompleted: model.roles = 0 -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleErrors.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/roleErrors.qml deleted file mode 100644 index 91664b6d4a..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleErrors.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { name: "name"; query: "/name/string()" } //starts with '/' - XmlRole { name: "type"; query: "type" } //no type - XmlRole { name: "age"; query: "age/" } //ends with '/' - XmlRole { name: "size"; query: "size/number()" } //wrong type -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleKeys.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/roleKeys.qml deleted file mode 100644 index 9f667d86e5..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/roleKeys.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - query: "/data/item" - XmlRole { id: nameRole; name: "name"; query: "name/string()"; isKey: true } - XmlRole { name: "age"; query: "age/number()"; isKey: true } - XmlRole { name: "sport"; query: "sport/string()" } - - function disableNameKey() { - nameRole.isKey = false; - } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml deleted file mode 100644 index 5ec1ffa35f..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/testtypes.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - query: "/data" - XmlRole { name: "stringValue"; query: "a-string/string()" } - XmlRole { name: "numberValue"; query: "a-number/number()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/data/unique.qml b/tests/auto/declarative/qdeclarativexmllistmodel/data/unique.qml deleted file mode 100644 index 322a2e4e5c..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/data/unique.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import QtQuick.XmlListModel 2.0 - -XmlListModel { - source: "model.xml" - query: "/Pets/Pet" - XmlRole { name: "name"; query: "name/string()" } - XmlRole { name: "name"; query: "type/string()" } -} diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro deleted file mode 100644 index 10944bcb41..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qdeclarativexmllistmodel -macx:CONFIG -= app_bundle - -SOURCES += tst_qdeclarativexmllistmodel.cpp -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private network testlib xmlpatterns diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp deleted file mode 100644 index c2cf4a69f6..0000000000 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ /dev/null @@ -1,961 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include - -#include -#include -#include -#include "../../../../src/imports/xmllistmodel/qdeclarativexmllistmodel_p.h" - -typedef QPair QDeclarativeXmlListRange; -typedef QList QDeclarativeXmlModelData; - -Q_DECLARE_METATYPE(QList) -Q_DECLARE_METATYPE(QDeclarativeXmlModelData) -Q_DECLARE_METATYPE(QDeclarativeXmlListModel::Status) - -class tst_qdeclarativexmllistmodel : public QObject - -{ - Q_OBJECT -public: - tst_qdeclarativexmllistmodel() {} - -private slots: - void initTestCase() { - qRegisterMetaType(); - } - - void buildModel(); - void testTypes(); - void testTypes_data(); - void cdata(); - void attributes(); - void roles(); - void roleErrors(); - void uniqueRoleNames(); - void headers(); - void xml(); - void xml_data(); - void source(); - void source_data(); - void data(); - void get(); - void reload(); - void useKeys(); - void useKeys_data(); - void noKeysValueChanges(); - void keysChanged(); - void threading(); - void threading_data(); - void propertyChanges(); - - void roleCrash(); - -private: - QString errorString(QListModelInterface* model) { - QString ret; - QMetaObject::invokeMethod(model, "errorString", Q_RETURN_ARG(QString, ret)); - return ret; - } - - QString makeItemXmlAndData(const QString &data, QDeclarativeXmlModelData *modelData = 0) const - { - if (modelData) - modelData->clear(); - QString xml; - - if (!data.isEmpty()) { - QStringList items = data.split(";"); - foreach(const QString &item, items) { - if (item.isEmpty()) - continue; - QVariantList variants; - xml += QLatin1String(""); - QStringList fields = item.split(","); - foreach(const QString &field, fields) { - QStringList values = field.split("="); - if (values.count() != 2) { - qWarning() << "makeItemXmlAndData: invalid field:" << field; - continue; - } - xml += QString("<%1>%2").arg(values[0], values[1]); - if (!modelData) - continue; - bool isNum = false; - int number = values[1].toInt(&isNum); - if (isNum) - variants << number; - else - variants << values[1]; - } - xml += QLatin1String(""); - if (modelData) - modelData->append(variants); - } - } - - QString decl = ""; - return decl + QLatin1String("") + xml + QLatin1String(""); - } - - QDeclarativeEngine engine; -}; - -class CustomNetworkAccessManagerFactory : public QObject, public QDeclarativeNetworkAccessManagerFactory -{ - Q_OBJECT -public: - QVariantMap lastSentHeaders; - -protected: - QNetworkAccessManager *create(QObject *parent); -}; - -class CustomNetworkAccessManager : public QNetworkAccessManager -{ - Q_OBJECT -public: - CustomNetworkAccessManager(CustomNetworkAccessManagerFactory *factory, QObject *parent) - : QNetworkAccessManager(parent), m_factory(factory) {} - -protected: - QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0) - { - if (m_factory) { - QVariantMap map; - foreach (const QString &header, req.rawHeaderList()) - map[header] = req.rawHeader(header.toUtf8()); - m_factory->lastSentHeaders = map; - } - return QNetworkAccessManager::createRequest(op, req, outgoingData); - } - - QPointer m_factory; -}; - -QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent) -{ - return new CustomNetworkAccessManager(this, parent); -} - - -void tst_qdeclarativexmllistmodel::buildModel() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - QCOMPARE(model->data(3, Qt::UserRole).toString(), QLatin1String("Spot")); - QCOMPARE(model->data(3, Qt::UserRole+1).toString(), QLatin1String("Dog")); - QCOMPARE(model->data(3, Qt::UserRole+2).toInt(), 9); - QCOMPARE(model->data(3, Qt::UserRole+3).toString(), QLatin1String("Medium")); - - delete model; -} - -void tst_qdeclarativexmllistmodel::testTypes() -{ - QFETCH(QString, xml); - QFETCH(QString, roleName); - QFETCH(QVariant, expectedValue); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("testtypes.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - model->setProperty("xml",xml.toUtf8()); - QMetaObject::invokeMethod(model, "reload"); - QTRY_COMPARE(model->count(), 1); - - int role = -1; - foreach (int i, model->roles()) { - if (model->toString(i) == roleName) { - role = i; - break; - } - } - QVERIFY(role >= 0); - - if (expectedValue.toString() == "nan") - QVERIFY(qIsNaN(model->data(0, role).toDouble())); - else - QCOMPARE(model->data(0, role), expectedValue); - - delete model; -} - -void tst_qdeclarativexmllistmodel::testTypes_data() -{ - QTest::addColumn("xml"); - QTest::addColumn("roleName"); - QTest::addColumn("expectedValue"); - - QTest::newRow("missing string field") << "" - << "stringValue" << QVariant(""); - QTest::newRow("empty string") << "" - << "stringValue" << QVariant(""); - QTest::newRow("1-char string") << "5" - << "stringValue" << QVariant("5"); - QTest::newRow("string ok") << "abc def g" - << "stringValue" << QVariant("abc def g"); - - QTest::newRow("missing number field") << "" - << "numberValue" << QVariant(""); - double nan = qQNaN(); - QTest::newRow("empty number field") << "" - << "numberValue" << QVariant(nan); - QTest::newRow("number field with string") << "a string" - << "numberValue" << QVariant(nan); - QTest::newRow("-1") << "-1" - << "numberValue" << QVariant("-1"); - QTest::newRow("-1.5") << "-1.5" - << "numberValue" << QVariant("-1.5"); - QTest::newRow("0") << "0" - << "numberValue" << QVariant("0"); - QTest::newRow("+1") << "1" - << "numberValue" << QVariant("1"); - QTest::newRow("+1.5") << "1.5" - << "numberValue" << QVariant("1.5"); -} - -void tst_qdeclarativexmllistmodel::cdata() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 5); - - QVERIFY(model->data(2, Qt::UserRole+2).toString().startsWith(QLatin1String(""))); - - delete model; -} - -void tst_qdeclarativexmllistmodel::attributes() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 5); - QCOMPARE(model->data(2, Qt::UserRole).toString(), QLatin1String("Vegetable Soup")); - - delete model; -} - -void tst_qdeclarativexmllistmodel::roles() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - QList roles = model->roles(); - QCOMPARE(roles.count(), 4); - QCOMPARE(model->toString(roles.at(0)), QLatin1String("name")); - QCOMPARE(model->toString(roles.at(1)), QLatin1String("type")); - QCOMPARE(model->toString(roles.at(2)), QLatin1String("age")); - QCOMPARE(model->toString(roles.at(3)), QLatin1String("size")); - - delete model; -} - -void tst_qdeclarativexmllistmodel::roleErrors() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleErrors.qml"))); - QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":7:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData()); - QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":10:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData()); - - //### make sure we receive all expected warning messages. - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - - //### should any of these return valid values? - QCOMPARE(model->data(3, Qt::UserRole), QVariant()); - QCOMPARE(model->data(3, Qt::UserRole+1), QVariant()); - QCOMPARE(model->data(3, Qt::UserRole+2), QVariant()); - - QEXPECT_FAIL("", "QTBUG-10797", Continue); - QCOMPARE(model->data(3, Qt::UserRole+3), QVariant()); - - delete model; -} - -void tst_qdeclarativexmllistmodel::uniqueRoleNames() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("unique.qml"))); - QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("unique.qml")).toString() + ":8:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData()); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - QList roles = model->roles(); - QCOMPARE(roles.count(), 1); - - delete model; -} - - -void tst_qdeclarativexmllistmodel::xml() -{ - QFETCH(QString, xml); - QFETCH(int, count); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - - QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status))); - QVERIFY(errorString(model).isEmpty()); - QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Loading); - QTRY_COMPARE(spy.count(), 1); spy.clear(); - QTest::qWait(50); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Ready); - QVERIFY(errorString(model).isEmpty()); - QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); - QCOMPARE(model->count(), 9); - - // if xml is empty (i.e. clearing) it won't have any effect if a source is set - if (xml.isEmpty()) - model->setProperty("source",QUrl()); - model->setProperty("xml",xml); - QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); // immediately goes to 1.0 if using setXml() - QTRY_COMPARE(spy.count(), 1); spy.clear(); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Loading); - QTRY_COMPARE(spy.count(), 1); spy.clear(); - if (xml.isEmpty()) - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Null); - else - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Ready); - QVERIFY(errorString(model).isEmpty()); - QCOMPARE(model->count(), count); - - delete model; -} - -void tst_qdeclarativexmllistmodel::xml_data() -{ - QTest::addColumn("xml"); - QTest::addColumn("count"); - - QTest::newRow("xml with no items") << "" << 0; - QTest::newRow("empty xml") << "" << 0; - QTest::newRow("one item") << "HobbesTiger7Large" << 1; -} - -void tst_qdeclarativexmllistmodel::headers() -{ - // ensure the QNetworkAccessManagers created for this test are immediately deleted - QDeclarativeEngine qmlEng; - - CustomNetworkAccessManagerFactory factory; - qmlEng.setNetworkAccessManagerFactory(&factory); - - QDeclarativeComponent component(&qmlEng, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Ready); - - QVariantMap expectedHeaders; - expectedHeaders["Accept"] = "application/xml,*/*"; - - QCOMPARE(factory.lastSentHeaders.count(), expectedHeaders.count()); - foreach (const QString &header, expectedHeaders.keys()) { - QVERIFY(factory.lastSentHeaders.contains(header)); - QCOMPARE(factory.lastSentHeaders[header].toString(), expectedHeaders[header].toString()); - } - - delete model; -} - -void tst_qdeclarativexmllistmodel::source() -{ - QFETCH(QUrl, source); - QFETCH(int, count); - QFETCH(QDeclarativeXmlListModel::Status, status); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status))); - - QVERIFY(errorString(model).isEmpty()); - QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Loading); - QTRY_COMPARE(spy.count(), 1); spy.clear(); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Ready); - QVERIFY(errorString(model).isEmpty()); - QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); - QCOMPARE(model->count(), 9); - - model->setProperty("source",source); - if (model->property("source").toString().isEmpty()) - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Null); - QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); - QTRY_COMPARE(spy.count(), 1); spy.clear(); - QCOMPARE(qvariant_cast(model->property("status")), - QDeclarativeXmlListModel::Loading); - QVERIFY(errorString(model).isEmpty()); - - QEventLoop loop; - QTimer timer; - timer.setSingleShot(true); - connect(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status)), &loop, SLOT(quit())); - connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); - timer.start(20000); - loop.exec(); - - if (spy.count() == 0 && status != QDeclarativeXmlListModel::Ready) { - qWarning("QDeclarativeXmlListModel invalid source test timed out"); - } else { - QCOMPARE(spy.count(), 1); spy.clear(); - } - - QCOMPARE(qvariant_cast(model->property("status")), status); - QCOMPARE(model->count(), count); - - if (status == QDeclarativeXmlListModel::Ready) - QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); - - QCOMPARE(errorString(model).isEmpty(), status == QDeclarativeXmlListModel::Ready); - - delete model; -} - -void tst_qdeclarativexmllistmodel::source_data() -{ - QTest::addColumn("source"); - QTest::addColumn("count"); - QTest::addColumn("status"); - - QTest::newRow("valid") << QUrl::fromLocalFile(TESTDATA("model2.xml")) << 2 - << QDeclarativeXmlListModel::Ready; - QTest::newRow("invalid") << QUrl("http://blah.blah/blah.xml") << 0 - << QDeclarativeXmlListModel::Error; - - // empty file - QTemporaryFile *temp = new QTemporaryFile(this); - if (temp->open()) - QTest::newRow("empty file") << QUrl::fromLocalFile(temp->fileName()) << 0 - << QDeclarativeXmlListModel::Ready; - temp->close(); -} - -void tst_qdeclarativexmllistmodel::data() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - - for (int i=0; i<9; i++) { - for (int j=0; jroles().count(); j++) { - QCOMPARE(model->data(i, j), QVariant()); - } - } - QTRY_COMPARE(model->count(), 9); - - delete model; -} - -void tst_qdeclarativexmllistmodel::get() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("get.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - - QVERIFY(model != 0); - - QVERIFY(QMetaObject::invokeMethod(model, "runPreTest")); - QCOMPARE(model->property("preTest").toBool(), true); - - QTRY_COMPARE(model->count(), 9); - - QVERIFY(QMetaObject::invokeMethod(model, "runPostTest")); - QCOMPARE(model->property("postTest").toBool(), true); - - delete model; -} - -void tst_qdeclarativexmllistmodel::reload() -{ - // If no keys are used, the model should be rebuilt from scratch when - // reload() is called. - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); - QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); - QSignalSpy spyCount(model, SIGNAL(countChanged())); - //reload multiple times to test the xml query aborting - QMetaObject::invokeMethod(model, "reload"); - QMetaObject::invokeMethod(model, "reload"); - QCoreApplication::processEvents(); - QMetaObject::invokeMethod(model, "reload"); - QMetaObject::invokeMethod(model, "reload"); - QTRY_COMPARE(spyCount.count(), 1); - QTRY_COMPARE(spyInsert.count(), 1); - QTRY_COMPARE(spyRemove.count(), 1); - - QCOMPARE(spyInsert[0][0].toInt(), 0); - QCOMPARE(spyInsert[0][1].toInt(), 9); - - QCOMPARE(spyRemove[0][0].toInt(), 0); - QCOMPARE(spyRemove[0][1].toInt(), 9); - - delete model; -} - -void tst_qdeclarativexmllistmodel::useKeys() -{ - // If using incremental updates through keys, the model should only - // insert & remove some of the items, instead of throwing everything - // away and causing the view to repaint the whole view. - - QFETCH(QString, oldXml); - QFETCH(int, oldCount); - QFETCH(QString, newXml); - QFETCH(QDeclarativeXmlModelData, newData); - QFETCH(QList, insertRanges); - QFETCH(QList, removeRanges); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - - model->setProperty("xml",oldXml); - QTRY_COMPARE(model->count(), oldCount); - - QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); - QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); - QSignalSpy spyCount(model, SIGNAL(countChanged())); - - model->setProperty("xml",newXml); - - if (oldCount != newData.count()) { - QTRY_COMPARE(model->count(), newData.count()); - QCOMPARE(spyCount.count(), 1); - } else { - QTRY_VERIFY(spyInsert.count() > 0 || spyRemove.count() > 0); - QCOMPARE(spyCount.count(), 0); - } - - QList roles = model->roles(); - for (int i=0; icount(); i++) { - for (int j=0; jdata(i, roles[j]), newData[i][j]); - } - - QCOMPARE(spyInsert.count(), insertRanges.count()); - for (int i=0; i("oldXml"); - QTest::addColumn("oldCount"); - QTest::addColumn("newXml"); - QTest::addColumn("newData"); - QTest::addColumn >("insertRanges"); - QTest::addColumn >("removeRanges"); - - QDeclarativeXmlModelData modelData; - - QTest::newRow("append 1") - << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics", &modelData) - << modelData - << (QList() << qMakePair(1, 1)) - << QList(); - - QTest::newRow("append multiple") - << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData) - << modelData - << (QList() << qMakePair(1, 2)) - << QList(); - - QTest::newRow("insert in different spots") - << makeItemXmlAndData("name=B,age=35,sport=Athletics") << 1 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) - << modelData - << (QList() << qMakePair(0, 1) << qMakePair(2,2)) - << QList(); - - QTest::newRow("insert in middle") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=D,age=55,sport=Golf") << 2 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) - << modelData - << (QList() << qMakePair(1, 2)) - << QList(); - - QTest::newRow("remove first") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2 - << makeItemXmlAndData("name=B,age=35,sport=Athletics", &modelData) - << modelData - << QList() - << (QList() << qMakePair(0, 1)); - - QTest::newRow("remove last") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2 - << makeItemXmlAndData("name=A,age=25,sport=Football", &modelData) - << modelData - << QList() - << (QList() << qMakePair(1, 1)); - - QTest::newRow("remove from multiple spots") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 5 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=C,age=45,sport=Curling", &modelData) - << modelData - << QList() - << (QList() << qMakePair(1, 1) << qMakePair(3,2)); - - QTest::newRow("remove all") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3 - << makeItemXmlAndData("", &modelData) - << modelData - << QList() - << (QList() << qMakePair(0, 3)); - - QTest::newRow("replace item") - << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 - << makeItemXmlAndData("name=ZZZ,age=25,sport=Football", &modelData) - << modelData - << (QList() << qMakePair(0, 1)) - << (QList() << qMakePair(0, 1)); - - QTest::newRow("add and remove simultaneously, in different spots") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf") << 4 - << makeItemXmlAndData("name=B,age=35,sport=Athletics;name=E,age=65,sport=Fencing", &modelData) - << modelData - << (QList() << qMakePair(1, 1)) - << (QList() << qMakePair(0, 1) << qMakePair(2,2)); - - QTest::newRow("insert at start, remove at end i.e. rss feed") - << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 3 - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData) - << modelData - << (QList() << qMakePair(0, 2)) - << (QList() << qMakePair(1, 2)); - - QTest::newRow("remove at start, insert at end") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3 - << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing", &modelData) - << modelData - << (QList() << qMakePair(1, 2)) - << (QList() << qMakePair(0, 2)); - - QTest::newRow("all data has changed") - << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35") << 2 - << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) - << modelData - << (QList() << qMakePair(0, 2)) - << (QList() << qMakePair(0, 2)); -} - -void tst_qdeclarativexmllistmodel::noKeysValueChanges() -{ - // The 'key' roles are 'name' and 'age', as defined in roleKeys.qml. - // If a 'sport' value is changed, the model should not be reloaded, - // since 'sport' is not marked as a key. - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - - QString xml; - - xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics"); - model->setProperty("xml",xml); - QTRY_COMPARE(model->count(), 2); - - model->setProperty("xml",""); - - QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); - QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); - QSignalSpy spyCount(model, SIGNAL(countChanged())); - - xml = makeItemXmlAndData("name=A,age=25,sport=AussieRules;name=B,age=35,sport=Athletics"); - model->setProperty("xml",xml); - - // wait for the new xml data to be set, and verify no signals were emitted - QTRY_VERIFY(model->data(0, model->roles()[2]).toString() != QLatin1String("Football")); - QCOMPARE(model->data(0, model->roles()[2]).toString(), QLatin1String("AussieRules")); - - QVERIFY(spyInsert.count() == 0); - QVERIFY(spyRemove.count() == 0); - QVERIFY(spyCount.count() == 0); - - QCOMPARE(model->count(), 2); - - delete model; -} - -void tst_qdeclarativexmllistmodel::keysChanged() -{ - // If the key roles change, the next time the data is reloaded, it should - // delete all its data and build a clean model (i.e. same behaviour as - // if no keys are set). - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - - QString xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics"); - model->setProperty("xml",xml); - QTRY_COMPARE(model->count(), 2); - - model->setProperty("xml",""); - - QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); - QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); - QSignalSpy spyCount(model, SIGNAL(countChanged())); - - QVERIFY(QMetaObject::invokeMethod(model, "disableNameKey")); - model->setProperty("xml",xml); - - QTRY_VERIFY(spyInsert.count() > 0 && spyRemove.count() > 0); - - QCOMPARE(spyInsert.count(), 1); - QCOMPARE(spyInsert[0][0].toInt(), 0); - QCOMPARE(spyInsert[0][1].toInt(), 2); - - QCOMPARE(spyRemove.count(), 1); - QCOMPARE(spyRemove[0][0].toInt(), 0); - QCOMPARE(spyRemove[0][1].toInt(), 2); - - QCOMPARE(spyCount.count(), 0); - - delete model; -} - -void tst_qdeclarativexmllistmodel::threading() -{ - QFETCH(int, xmlDataCount); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); - - QListModelInterface *m1 = qobject_cast(component.create()); - QVERIFY(m1 != 0); - QListModelInterface *m2 = qobject_cast(component.create()); - QVERIFY(m2 != 0); - QListModelInterface *m3 = qobject_cast(component.create()); - QVERIFY(m3 != 0); - - for (int dataCount=0; dataCountsetProperty("xml",makeItemXmlAndData(data1)); - m2->setProperty("xml",makeItemXmlAndData(data2)); - m3->setProperty("xml",makeItemXmlAndData(data3)); - QCoreApplication::processEvents(); - m2->setProperty("xml",makeItemXmlAndData(data2)); - m1->setProperty("xml",makeItemXmlAndData(data1)); - m2->setProperty("xml",makeItemXmlAndData(data2)); - QCoreApplication::processEvents(); - m3->setProperty("xml",makeItemXmlAndData(data3)); - QCoreApplication::processEvents(); - m2->setProperty("xml",makeItemXmlAndData(data2)); - m1->setProperty("xml",makeItemXmlAndData(data1)); - m2->setProperty("xml",makeItemXmlAndData(data2)); - m3->setProperty("xml",makeItemXmlAndData(data3)); - QCoreApplication::processEvents(); - m2->setProperty("xml",makeItemXmlAndData(data2)); - m3->setProperty("xml",makeItemXmlAndData(data3)); - m3->setProperty("xml",makeItemXmlAndData(data3)); - QCoreApplication::processEvents(); - - QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount); - - for (int i=0; idata(i, m1->roles()[0]).toString(), QString("A" + QString::number(i))); - QCOMPARE(m1->data(i, m1->roles()[1]).toString(), QString("1" + QString::number(i))); - QCOMPARE(m1->data(i, m1->roles()[2]).toString(), QString("Football")); - - QCOMPARE(m2->data(i, m2->roles()[0]).toString(), QString("B" + QString::number(i))); - QCOMPARE(m2->data(i, m2->roles()[1]).toString(), QString("2" + QString::number(i))); - QCOMPARE(m2->data(i, m2->roles()[2]).toString(), QString("Athletics")); - - QCOMPARE(m3->data(i, m3->roles()[0]).toString(), QString("C" + QString::number(i))); - QCOMPARE(m3->data(i, m3->roles()[1]).toString(), QString("3" + QString::number(i))); - QCOMPARE(m3->data(i, m3->roles()[2]).toString(), QString("Curling")); - } - } - - delete m1; - delete m2; - delete m3; -} - -void tst_qdeclarativexmllistmodel::threading_data() -{ - QTest::addColumn("xmlDataCount"); - - QTest::newRow("1") << 1; - QTest::newRow("2") << 2; - QTest::newRow("10") << 10; -} - -void tst_qdeclarativexmllistmodel::propertyChanges() -{ - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - QTRY_COMPARE(model->count(), 9); - - QObject *role = model->findChild("role"); - QVERIFY(role); - - QSignalSpy nameSpy(role, SIGNAL(nameChanged())); - QSignalSpy querySpy(role, SIGNAL(queryChanged())); - QSignalSpy isKeySpy(role, SIGNAL(isKeyChanged())); - - role->setProperty("name","size"); - role->setProperty("query","size/string()"); - role->setProperty("isKey",true); - - QCOMPARE(role->property("name").toString(), QString("size")); - QCOMPARE(role->property("query").toString(), QString("size/string()")); - QVERIFY(role->property("isKey").toBool()); - - QCOMPARE(nameSpy.count(),1); - QCOMPARE(querySpy.count(),1); - QCOMPARE(isKeySpy.count(),1); - - role->setProperty("name","size"); - role->setProperty("query","size/string()"); - role->setProperty("isKey",true); - - QCOMPARE(nameSpy.count(),1); - QCOMPARE(querySpy.count(),1); - QCOMPARE(isKeySpy.count(),1); - - QSignalSpy sourceSpy(model, SIGNAL(sourceChanged())); - QSignalSpy xmlSpy(model, SIGNAL(xmlChanged())); - QSignalSpy modelQuerySpy(model, SIGNAL(queryChanged())); - QSignalSpy namespaceDeclarationsSpy(model, SIGNAL(namespaceDeclarationsChanged())); - - model->setProperty("source",QUrl("")); - model->setProperty("xml","PollyParrot12Small"); - model->setProperty("query","/Pets"); - model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";"); - - QCOMPARE(model->property("source").toUrl(), QUrl("")); - QCOMPARE(model->property("xml").toString(), QString("PollyParrot12Small")); - QCOMPARE(model->property("query").toString(), QString("/Pets")); - QCOMPARE(model->property("namespaceDeclarations").toString(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";")); - - QTRY_VERIFY(model->count() == 1); - - QCOMPARE(sourceSpy.count(),1); - QCOMPARE(xmlSpy.count(),1); - QCOMPARE(modelQuerySpy.count(),1); - QCOMPARE(namespaceDeclarationsSpy.count(),1); - - model->setProperty("source",QUrl("")); - model->setProperty("xml","PollyParrot12Small"); - model->setProperty("query","/Pets"); - model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";"); - - QCOMPARE(sourceSpy.count(),1); - QCOMPARE(xmlSpy.count(),1); - QCOMPARE(modelQuerySpy.count(),1); - QCOMPARE(namespaceDeclarationsSpy.count(),1); - - QTRY_VERIFY(model->count() == 1); - delete model; -} - -void tst_qdeclarativexmllistmodel::roleCrash() -{ - // don't crash - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleCrash.qml"))); - QListModelInterface *model = qobject_cast(component.create()); - QVERIFY(model != 0); - delete model; -} - -QTEST_MAIN(tst_qdeclarativexmllistmodel) - -#include "tst_qdeclarativexmllistmodel.moc" diff --git a/tests/auto/declarative/qmlmin/tst_qmlmin.cpp b/tests/auto/declarative/qmlmin/tst_qmlmin.cpp index 53b0e3772a..1c4f72191b 100644 --- a/tests/auto/declarative/qmlmin/tst_qmlmin.cpp +++ b/tests/auto/declarative/qmlmin/tst_qmlmin.cpp @@ -94,7 +94,7 @@ void tst_qmlmin::initTestCase() excludedDirs << "doc/src/snippets/qtquick1/imports"; // Add invalid files (i.e. files with syntax errors) - invalidFiles << "tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml"; + invalidFiles << "tests/auto/qtquick2/qquickloader/data/InvalidSourceComponent.qml"; invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/dynamicObjectProperties.2.qml"; invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/signal.3.qml"; invalidFiles << "tests/auto/declarative/qdeclarativelanguage/data/property.4.qml"; diff --git a/tests/auto/declarative/qquickanchors/data/anchors.qml b/tests/auto/declarative/qquickanchors/data/anchors.qml deleted file mode 100644 index 4be49a3468..0000000000 --- a/tests/auto/declarative/qquickanchors/data/anchors.qml +++ /dev/null @@ -1,162 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 240 - height: 320 - Rectangle { id: masterRect; objectName: "masterRect"; x: 26; width: 96; height: 20; color: "red" } - Rectangle { - id: rect1; objectName: "rect1" - y: 20; width: 10; height: 10 - anchors.left: masterRect.left - } - Rectangle { - id: rect2; objectName: "rect2" - y: 20; width: 10; height: 10 - anchors.left: masterRect.right - } - Rectangle { - id: rect3; objectName: "rect3" - y: 20; width: 10; height: 10 - anchors.left: masterRect.horizontalCenter - } - Rectangle { - id: rect4; objectName: "rect4" - y: 30; width: 10; height: 10 - anchors.right: masterRect.left - } - Rectangle { - id: rect5; objectName: "rect5" - y: 30; width: 10; height: 10 - anchors.right: masterRect.right - } - Rectangle { - id: rect6; objectName: "rect6" - y: 30; width: 10; height: 10 - anchors.right: masterRect.horizontalCenter - } - Rectangle { - id: rect7; objectName: "rect7" - y: 50; width: 10; height: 10 - anchors.left: parent.left - } - Rectangle { - id: rect8; objectName: "rect8" - y: 50; width: 10; height: 10 - anchors.left: parent.right - } - Rectangle { - id: rect9; objectName: "rect9" - y: 50; width: 10; height: 10 - anchors.left: parent.horizontalCenter - } - Rectangle { - id: rect10; objectName: "rect10" - y: 60; width: 10; height: 10 - anchors.right: parent.left - } - Rectangle { - id: rect11; objectName: "rect11" - y: 60; width: 10; height: 10 - anchors.right: parent.right - } - Rectangle { - id: rect12; objectName: "rect12" - y: 60; width: 10; height: 10 - anchors.right: parent.horizontalCenter - } - Rectangle { - id: rect13; objectName: "rect13" - x: 200; width: 10; height: 10 - anchors.top: masterRect.bottom - } - Rectangle { - id: rect14; objectName: "rect14" - width: 10; height: 10; color: "steelblue" - anchors.verticalCenter: parent.verticalCenter - } - Rectangle { - id: rect15; objectName: "rect15" - y: 200; height: 10 - anchors.left: masterRect.left - anchors.right: masterRect.right - } - Rectangle { - id: rect16; objectName: "rect16" - y: 220; height: 10 - anchors.left: masterRect.left - anchors.horizontalCenter: masterRect.right - } - Rectangle { - id: rect17; objectName: "rect17" - y: 240; height: 10 - anchors.right: masterRect.right - anchors.horizontalCenter: masterRect.left - } - Rectangle { - id: rect18; objectName: "rect18" - x: 180; width: 10 - anchors.top: masterRect.bottom - anchors.bottom: rect12.top - } - Rectangle { - id: rect19; objectName: "rect19" - y: 70; width: 10; height: 10 - anchors.horizontalCenter: parent.horizontalCenter - } - Rectangle { - id: rect20; objectName: "rect20" - y: 70; width: 10; height: 10 - anchors.horizontalCenter: parent.right - } - Rectangle { - id: rect21; objectName: "rect21" - y: 70; width: 10; height: 10 - anchors.horizontalCenter: parent.left - } - Rectangle { - id: rect22; objectName: "rect22" - width: 10; height: 10 - anchors.centerIn: masterRect - } - Rectangle { - id: rect23; objectName: "rect23" - anchors.left: masterRect.left - anchors.leftMargin: 5 - anchors.right: masterRect.right - anchors.rightMargin: 5 - anchors.top: masterRect.top - anchors.topMargin: 5 - anchors.bottom: masterRect.bottom - anchors.bottomMargin: 5 - } - Rectangle { - id: rect24; objectName: "rect24" - width: 10; height: 10 - anchors.horizontalCenter: masterRect.left - anchors.horizontalCenterOffset: width/2 - } - Rectangle { - id: rect25; objectName: "rect25" - width: 10; height: 10 - anchors.verticalCenter: rect12.top - anchors.verticalCenterOffset: height/2 - } - Rectangle { - id: rect26; objectName: "rect26" - width: 10; height: 10 - anchors.baseline: masterRect.top - anchors.baselineOffset: height/2 - } - Text { - id: text1; objectName: "text1" - y: 200; - text: "Hello" - } - Text { - id: text2; objectName: "text2" - anchors.baseline: text1.baseline - anchors.left: text1.right - text: "World" - } -} diff --git a/tests/auto/declarative/qquickanchors/data/centerin.qml b/tests/auto/declarative/qquickanchors/data/centerin.qml deleted file mode 100644 index e5f64f1e47..0000000000 --- a/tests/auto/declarative/qquickanchors/data/centerin.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - objectName: "centered" - width: 50; height: 50; color: "blue" - anchors.centerIn: parent; - anchors.verticalCenterOffset: 30 - anchors.horizontalCenterOffset: 10 - } -} diff --git a/tests/auto/declarative/qquickanchors/data/centerinRotation.qml b/tests/auto/declarative/qquickanchors/data/centerinRotation.qml deleted file mode 100644 index 933a25c100..0000000000 --- a/tests/auto/declarative/qquickanchors/data/centerinRotation.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - objectName: "outer" - rotation: 90 - width: 101; height: 101; color: "blue" - anchors.centerIn: parent; - - Rectangle { - objectName: "inner" - width: 50; height: 50; color: "blue" - anchors.centerIn: parent; - } - } -} diff --git a/tests/auto/declarative/qquickanchors/data/crash1.qml b/tests/auto/declarative/qquickanchors/data/crash1.qml deleted file mode 100644 index 98dd6cfa41..0000000000 --- a/tests/auto/declarative/qquickanchors/data/crash1.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Column { - Text { - text: "foo" - anchors.fill: parent - } - Text { - text: "bar" - } -} diff --git a/tests/auto/declarative/qquickanchors/data/fill.qml b/tests/auto/declarative/qquickanchors/data/fill.qml deleted file mode 100644 index 08db199d7b..0000000000 --- a/tests/auto/declarative/qquickanchors/data/fill.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - objectName: "filler" - width: 50; height: 50; color: "blue" - anchors.fill: parent; - anchors.leftMargin: 10; - anchors.rightMargin: 20; - anchors.topMargin: 30; - anchors.bottomMargin: 40; - } -} diff --git a/tests/auto/declarative/qquickanchors/data/hvCenter.qml b/tests/auto/declarative/qquickanchors/data/hvCenter.qml deleted file mode 100644 index 6763f8eb75..0000000000 --- a/tests/auto/declarative/qquickanchors/data/hvCenter.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 77; height: 95 - Rectangle { - objectName: "centered" - width: 57; height: 57; color: "blue" - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } -} diff --git a/tests/auto/declarative/qquickanchors/data/loop1.qml b/tests/auto/declarative/qquickanchors/data/loop1.qml deleted file mode 100644 index 342b2af052..0000000000 --- a/tests/auto/declarative/qquickanchors/data/loop1.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: rect - width: 120; height: 200; color: "white" - Text { id: text1; anchors.right: text2.right; text: "Hello" } - Text { id: text2; anchors.right: text1.right; anchors.rightMargin: 10; text: "World" } -} diff --git a/tests/auto/declarative/qquickanchors/data/loop2.qml b/tests/auto/declarative/qquickanchors/data/loop2.qml deleted file mode 100644 index e1875be025..0000000000 --- a/tests/auto/declarative/qquickanchors/data/loop2.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container; - width: 600; - height: 600; - - Image { - id: image1 - source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/3311388091_ac2a257feb.jpg" - anchors.right: image2.left - } - - Image { - id: image2 - source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/oslo_groupphoto.jpg" - anchors.left: image1.right - anchors.leftMargin: 20 - } -} diff --git a/tests/auto/declarative/qquickanchors/data/margins.qml b/tests/auto/declarative/qquickanchors/data/margins.qml deleted file mode 100644 index 9403f65a61..0000000000 --- a/tests/auto/declarative/qquickanchors/data/margins.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 200 - Rectangle { - objectName: "filler" - width: 50; height: 50; color: "blue" - anchors.fill: parent; - anchors.margins: 10 - anchors.leftMargin: 5 - anchors.topMargin: 6 - } -} diff --git a/tests/auto/declarative/qquickanchors/qquickanchors.pro b/tests/auto/declarative/qquickanchors/qquickanchors.pro deleted file mode 100644 index 0d085d367d..0000000000 --- a/tests/auto/declarative/qquickanchors/qquickanchors.pro +++ /dev/null @@ -1,12 +0,0 @@ -TARGET = tst_qquickanchors -CONFIG += testcase -SOURCES += tst_qquickanchors.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private v8-private testlib diff --git a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp b/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp deleted file mode 100644 index 00b52ebc50..0000000000 --- a/tests/auto/declarative/qquickanchors/tst_qquickanchors.cpp +++ /dev/null @@ -1,692 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -Q_DECLARE_METATYPE(QQuickAnchors::Anchor) -Q_DECLARE_METATYPE(QQuickAnchorLine::AnchorLine) - -class tst_qquickanchors : public QObject -{ - Q_OBJECT -public: - tst_qquickanchors() {} - -private slots: - void basicAnchors(); - void basicAnchorsRTL(); - void loops(); - void illegalSets(); - void illegalSets_data(); - void reset(); - void reset_data(); - void resetConvenience(); - void nullItem(); - void nullItem_data(); - void crash1(); - void centerIn(); - void centerInRTL(); - void centerInRotation(); - void hvCenter(); - void hvCenterRTL(); - void fill(); - void fillRTL(); - void margins(); - void marginsRTL(); -}; - -/* - Find an item with the specified objectName. -*/ -template -T *findItem(QQuickItem *parent, const QString &objectName) -{ - if (!parent) - return 0; - - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->QQuickItem::children().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) - return static_cast(item); - item = findItem(item, objectName); - if (item) - return static_cast(item); - } - - return 0; -} - -void tst_qquickanchors::basicAnchors() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml"))); - - qApp->processEvents(); - - //sibling horizontal - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect1"))->x(), 26.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect2"))->x(), 122.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect3"))->x(), 74.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect4"))->x(), 16.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect5"))->x(), 112.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect6"))->x(), 64.0); - - //parent horizontal - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect7"))->x(), 0.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect8"))->x(), 240.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect9"))->x(), 120.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect10"))->x(), -10.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect11"))->x(), 230.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect12"))->x(), 110.0); - - //vertical - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect13"))->y(), 20.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect14"))->y(), 155.0); - - //stretch - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect15"))->x(), 26.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect15"))->width(), 96.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect16"))->x(), 26.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect16"))->width(), 192.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect17"))->x(), -70.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect17"))->width(), 192.0); - - //vertical stretch - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect18"))->y(), 20.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect18"))->height(), 40.0); - - //more parent horizontal - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect19"))->x(), 115.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect20"))->x(), 235.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect21"))->x(), -5.0); - - //centerIn - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect22"))->x(), 69.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect22"))->y(), 5.0); - - //margins - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->x(), 31.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->y(), 5.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->width(), 86.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->height(), 10.0); - - // offsets - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect24"))->x(), 26.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect25"))->y(), 60.0); - QCOMPARE(findItem(view->rootObject(), QLatin1String("rect26"))->y(), 5.0); - - //baseline - QQuickText *text1 = findItem(view->rootObject(), QLatin1String("text1")); - QQuickText *text2 = findItem(view->rootObject(), QLatin1String("text2")); - QCOMPARE(text1->y(), text2->y()); - - delete view; -} - -QQuickItem* childItem(QQuickItem *parentItem, const char * itemString) { - return findItem(parentItem, QLatin1String(itemString)); -} - -qreal offsetMasterRTL(QQuickItem *rootItem, const char * itemString) { - QQuickItem* masterItem = findItem(rootItem, QLatin1String("masterRect")); - return masterItem->width()+2*masterItem->x()-findItem(rootItem, QLatin1String(itemString))->width(); -} - -qreal offsetParentRTL(QQuickItem *rootItem, const char * itemString) { - return rootItem->width()+2*rootItem->x()-findItem(rootItem, QLatin1String(itemString))->width(); -} - -void mirrorAnchors(QQuickItem *item) { - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - itemPrivate->setLayoutMirror(true); -} - -void tst_qquickanchors::basicAnchorsRTL() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml"))); - - qApp->processEvents(); - - QQuickItem* rootItem = qobject_cast(view->rootObject()); - foreach (QObject *child, rootItem->children()) { - bool mirrored = QQuickItemPrivate::get(qobject_cast(child))->anchors()->property("mirrored").toBool(); - QCOMPARE(mirrored, false); - } - - foreach (QObject *child, rootItem->children()) - mirrorAnchors(qobject_cast(child)); - - foreach (QObject *child, rootItem->children()) { - bool mirrored = QQuickItemPrivate::get(qobject_cast(child))->anchors()->property("mirrored").toBool(); - QCOMPARE(mirrored, true); - } - - //sibling horizontal - QCOMPARE(childItem(rootItem, "rect1")->x(), offsetMasterRTL(rootItem, "rect1")-26.0); - QCOMPARE(childItem(rootItem, "rect2")->x(), offsetMasterRTL(rootItem, "rect2")-122.0); - QCOMPARE(childItem(rootItem, "rect3")->x(), offsetMasterRTL(rootItem, "rect3")-74.0); - QCOMPARE(childItem(rootItem, "rect4")->x(), offsetMasterRTL(rootItem, "rect4")-16.0); - QCOMPARE(childItem(rootItem, "rect5")->x(), offsetMasterRTL(rootItem, "rect5")-112.0); - QCOMPARE(childItem(rootItem, "rect6")->x(), offsetMasterRTL(rootItem, "rect6")-64.0); - - //parent horizontal - QCOMPARE(childItem(rootItem, "rect7")->x(), offsetParentRTL(rootItem, "rect7")-0.0); - QCOMPARE(childItem(rootItem, "rect8")->x(), offsetParentRTL(rootItem, "rect8")-240.0); - QCOMPARE(childItem(rootItem, "rect9")->x(), offsetParentRTL(rootItem, "rect9")-120.0); - QCOMPARE(childItem(rootItem, "rect10")->x(), offsetParentRTL(rootItem, "rect10")+10.0); - QCOMPARE(childItem(rootItem, "rect11")->x(), offsetParentRTL(rootItem, "rect11")-230.0); - QCOMPARE(childItem(rootItem, "rect12")->x(), offsetParentRTL(rootItem, "rect12")-110.0); - - //vertical - QCOMPARE(childItem(rootItem, "rect13")->y(), 20.0); - QCOMPARE(childItem(rootItem, "rect14")->y(), 155.0); - - //stretch - QCOMPARE(childItem(rootItem, "rect15")->x(), offsetMasterRTL(rootItem, "rect15")-26.0); - QCOMPARE(childItem(rootItem, "rect15")->width(), 96.0); - QCOMPARE(childItem(rootItem, "rect16")->x(), offsetMasterRTL(rootItem, "rect16")-26.0); - QCOMPARE(childItem(rootItem, "rect16")->width(), 192.0); - QCOMPARE(childItem(rootItem, "rect17")->x(), offsetMasterRTL(rootItem, "rect17")+70.0); - QCOMPARE(childItem(rootItem, "rect17")->width(), 192.0); - - //vertical stretch - QCOMPARE(childItem(rootItem, "rect18")->y(), 20.0); - QCOMPARE(childItem(rootItem, "rect18")->height(), 40.0); - - //more parent horizontal - QCOMPARE(childItem(rootItem, "rect19")->x(), offsetParentRTL(rootItem, "rect19")-115.0); - QCOMPARE(childItem(rootItem, "rect20")->x(), offsetParentRTL(rootItem, "rect20")-235.0); - QCOMPARE(childItem(rootItem, "rect21")->x(), offsetParentRTL(rootItem, "rect21")+5.0); - - //centerIn - QCOMPARE(childItem(rootItem, "rect22")->x(), offsetMasterRTL(rootItem, "rect22")-69.0); - QCOMPARE(childItem(rootItem, "rect22")->y(), 5.0); - - //margins - QCOMPARE(childItem(rootItem, "rect23")->x(), offsetMasterRTL(rootItem, "rect23")-31.0); - QCOMPARE(childItem(rootItem, "rect23")->y(), 5.0); - QCOMPARE(childItem(rootItem, "rect23")->width(), 86.0); - QCOMPARE(childItem(rootItem, "rect23")->height(), 10.0); - - // offsets - QCOMPARE(childItem(rootItem, "rect24")->x(), offsetMasterRTL(rootItem, "rect24")-26.0); - QCOMPARE(childItem(rootItem, "rect25")->y(), 60.0); - QCOMPARE(childItem(rootItem, "rect26")->y(), 5.0); - - //baseline - QQuickText *text1 = findItem(rootItem, QLatin1String("text1")); - QQuickText *text2 = findItem(rootItem, QLatin1String("text2")); - QCOMPARE(text1->y(), text2->y()); - - delete view; -} - -// mostly testing that we don't crash -void tst_qquickanchors::loops() -{ - { - QUrl source(QUrl::fromLocalFile(TESTDATA("loop1.qml"))); - - QString expect = source.toString() + ":6:5: QML Text: Possible anchor loop detected on horizontal anchor."; - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - - QQuickView *view = new QQuickView; - view->setSource(source); - qApp->processEvents(); - - delete view; - } - - { - QUrl source(QUrl::fromLocalFile(TESTDATA("loop2.qml"))); - - QString expect = source.toString() + ":8:3: QML Image: Possible anchor loop detected on horizontal anchor."; - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - - QQuickView *view = new QQuickView; - view->setSource(source); - qApp->processEvents(); - - delete view; - } -} - -void tst_qquickanchors::illegalSets() -{ - QFETCH(QString, qml); - QFETCH(QString, warning); - - QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); - - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 1.0\n" + qml.toUtf8()), QUrl::fromLocalFile("")); - if (!component.isReady()) - qWarning() << "Test errors:" << component.errors(); - QVERIFY(component.isReady()); - QObject *o = component.create(); - delete o; -} - -void tst_qquickanchors::illegalSets_data() -{ - QTest::addColumn("qml"); - QTest::addColumn("warning"); - - QTest::newRow("H - too many anchors") - << "Rectangle { id: rect; Rectangle { anchors.left: rect.left; anchors.right: rect.right; anchors.horizontalCenter: rect.horizontalCenter } }" - << "file::2:23: QML Rectangle: Cannot specify left, right, and hcenter anchors."; - - foreach (const QString &side, QStringList() << "left" << "right") { - QTest::newRow("H - anchor to V") - << QString("Rectangle { Rectangle { anchors.%1: parent.top } }").arg(side) - << "file::2:13: QML Rectangle: Cannot anchor a horizontal edge to a vertical edge."; - - QTest::newRow("H - anchor to non parent/sibling") - << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) - << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; - - QTest::newRow("H - anchor to self") - << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) - << "file::2:1: QML Rectangle: Cannot anchor item to self."; - } - - - QTest::newRow("V - too many anchors") - << "Rectangle { id: rect; Rectangle { anchors.top: rect.top; anchors.bottom: rect.bottom; anchors.verticalCenter: rect.verticalCenter } }" - << "file::2:23: QML Rectangle: Cannot specify top, bottom, and vcenter anchors."; - - QTest::newRow("V - too many anchors with baseline") - << "Rectangle { Text { id: text1; text: \"Hello\" } Text { anchors.baseline: text1.baseline; anchors.top: text1.top; } }" - << "file::2:47: QML Text: Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors."; - - foreach (const QString &side, QStringList() << "top" << "bottom" << "baseline") { - - QTest::newRow("V - anchor to H") - << QString("Rectangle { Rectangle { anchors.%1: parent.left } }").arg(side) - << "file::2:13: QML Rectangle: Cannot anchor a vertical edge to a horizontal edge."; - - QTest::newRow("V - anchor to non parent/sibling") - << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) - << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; - - QTest::newRow("V - anchor to self") - << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) - << "file::2:1: QML Rectangle: Cannot anchor item to self."; - } - - - QTest::newRow("centerIn - anchor to non parent/sibling") - << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.centerIn: rect} }" - << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; - - - QTest::newRow("fill - anchor to non parent/sibling") - << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.fill: rect} }" - << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; -} - -void tst_qquickanchors::reset() -{ - QFETCH(QString, side); - QFETCH(QQuickAnchorLine::AnchorLine, anchorLine); - QFETCH(QQuickAnchors::Anchor, usedAnchor); - - QQuickItem *baseItem = new QQuickItem; - - QQuickAnchorLine anchor; - anchor.item = baseItem; - anchor.anchorLine = anchorLine; - - QQuickItem *item = new QQuickItem; - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - - const QMetaObject *meta = itemPrivate->anchors()->metaObject(); - QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); - - QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor))); - QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), true); - - QVERIFY(p.reset(itemPrivate->anchors())); - QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), false); - - delete item; - delete baseItem; -} - -void tst_qquickanchors::reset_data() -{ - QTest::addColumn("side"); - QTest::addColumn("anchorLine"); - QTest::addColumn("usedAnchor"); - - QTest::newRow("left") << "left" << QQuickAnchorLine::Left << QQuickAnchors::LeftAnchor; - QTest::newRow("top") << "top" << QQuickAnchorLine::Top << QQuickAnchors::TopAnchor; - QTest::newRow("right") << "right" << QQuickAnchorLine::Right << QQuickAnchors::RightAnchor; - QTest::newRow("bottom") << "bottom" << QQuickAnchorLine::Bottom << QQuickAnchors::BottomAnchor; - - QTest::newRow("hcenter") << "horizontalCenter" << QQuickAnchorLine::HCenter << QQuickAnchors::HCenterAnchor; - QTest::newRow("vcenter") << "verticalCenter" << QQuickAnchorLine::VCenter << QQuickAnchors::VCenterAnchor; - QTest::newRow("baseline") << "baseline" << QQuickAnchorLine::Baseline << QQuickAnchors::BaselineAnchor; -} - -void tst_qquickanchors::resetConvenience() -{ - QQuickItem *baseItem = new QQuickItem; - QQuickItem *item = new QQuickItem; - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - - //fill - itemPrivate->anchors()->setFill(baseItem); - QVERIFY(itemPrivate->anchors()->fill() == baseItem); - itemPrivate->anchors()->resetFill(); - QVERIFY(itemPrivate->anchors()->fill() == 0); - - //centerIn - itemPrivate->anchors()->setCenterIn(baseItem); - QVERIFY(itemPrivate->anchors()->centerIn() == baseItem); - itemPrivate->anchors()->resetCenterIn(); - QVERIFY(itemPrivate->anchors()->centerIn() == 0); - - delete item; - delete baseItem; -} - -void tst_qquickanchors::nullItem() -{ - QFETCH(QString, side); - - QQuickAnchorLine anchor; - QQuickItem *item = new QQuickItem; - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - - const QMetaObject *meta = itemPrivate->anchors()->metaObject(); - QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); - - QTest::ignoreMessage(QtWarningMsg, ": QML Item: Cannot anchor to a null item."); - QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor))); - - delete item; -} - -void tst_qquickanchors::nullItem_data() -{ - QTest::addColumn("side"); - - QTest::newRow("left") << "left"; - QTest::newRow("top") << "top"; - QTest::newRow("right") << "right"; - QTest::newRow("bottom") << "bottom"; - - QTest::newRow("hcenter") << "horizontalCenter"; - QTest::newRow("vcenter") << "verticalCenter"; - QTest::newRow("baseline") << "baseline"; -} - -//QTBUG-5428 -void tst_qquickanchors::crash1() -{ - QUrl source(QUrl::fromLocalFile(TESTDATA("crash1.qml"))); - - QString expect = source.toString() + ":3:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"; - - QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); - - QQuickView *view = new QQuickView(source); - qApp->processEvents(); - - delete view; -} - -void tst_qquickanchors::fill() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QCOMPARE(rect->x(), 0.0 + 10.0); - QCOMPARE(rect->y(), 0.0 + 30.0); - QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0); - //Alter Offsets (tests QTBUG-6631) - rectPrivate->anchors()->setLeftMargin(20.0); - rectPrivate->anchors()->setRightMargin(0.0); - rectPrivate->anchors()->setBottomMargin(0.0); - rectPrivate->anchors()->setTopMargin(10.0); - QCOMPARE(rect->x(), 0.0 + 20.0); - QCOMPARE(rect->y(), 0.0 + 10.0); - QCOMPARE(rect->width(), 200.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 10.0); - - delete view; -} - -void tst_qquickanchors::fillRTL() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - mirrorAnchors(rect); - - QCOMPARE(rect->x(), 0.0 + 20.0); - QCOMPARE(rect->y(), 0.0 + 30.0); - QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0); - //Alter Offsets (tests QTBUG-6631) - rectPrivate->anchors()->setLeftMargin(20.0); - rectPrivate->anchors()->setRightMargin(0.0); - rectPrivate->anchors()->setBottomMargin(0.0); - rectPrivate->anchors()->setTopMargin(10.0); - QCOMPARE(rect->x(), 0.0 + 0.0); - QCOMPARE(rect->y(), 0.0 + 10.0); - QCOMPARE(rect->width(), 200.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 10.0); - - delete view; -} - -void tst_qquickanchors::centerIn() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - QCOMPARE(rect->x(), 75.0 + 10); - QCOMPARE(rect->y(), 75.0 + 30); - //Alter Offsets (tests QTBUG-6631) - rectPrivate->anchors()->setHorizontalCenterOffset(-20.0); - rectPrivate->anchors()->setVerticalCenterOffset(-10.0); - QCOMPARE(rect->x(), 75.0 - 20.0); - QCOMPARE(rect->y(), 75.0 - 10.0); - - delete view; -} - -void tst_qquickanchors::centerInRTL() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - mirrorAnchors(rect); - - QCOMPARE(rect->x(), 75.0 - 10); - QCOMPARE(rect->y(), 75.0 + 30); - //Alter Offsets (tests QTBUG-6631) - rectPrivate->anchors()->setHorizontalCenterOffset(-20.0); - rectPrivate->anchors()->setVerticalCenterOffset(-10.0); - QCOMPARE(rect->x(), 75.0 + 20.0); - QCOMPARE(rect->y(), 75.0 - 10.0); - - delete view; -} - -//QTBUG-12441 -void tst_qquickanchors::centerInRotation() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerinRotation.qml"))); - - qApp->processEvents(); - QQuickRectangle* outer = findItem(view->rootObject(), QLatin1String("outer")); - QQuickRectangle* inner = findItem(view->rootObject(), QLatin1String("inner")); - - QEXPECT_FAIL("", "QTBUG-12441", Abort); - QCOMPARE(outer->x(), qreal(49.5)); - QCOMPARE(outer->y(), qreal(49.5)); - QCOMPARE(inner->x(), qreal(25.5)); - QCOMPARE(inner->y(), qreal(25.5)); - - delete view; -} - -void tst_qquickanchors::hvCenter() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - - // test QTBUG-10999 - QCOMPARE(rect->x(), 10.0); - QCOMPARE(rect->y(), 19.0); - - rectPrivate->anchors()->setHorizontalCenterOffset(-5.0); - rectPrivate->anchors()->setVerticalCenterOffset(5.0); - QCOMPARE(rect->x(), 10.0 - 5.0); - QCOMPARE(rect->y(), 19.0 + 5.0); - - delete view; -} - -void tst_qquickanchors::hvCenterRTL() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - mirrorAnchors(rect); - - // test QTBUG-10999 - QCOMPARE(rect->x(), 10.0); - QCOMPARE(rect->y(), 19.0); - - rectPrivate->anchors()->setHorizontalCenterOffset(-5.0); - rectPrivate->anchors()->setVerticalCenterOffset(5.0); - QCOMPARE(rect->x(), 10.0 + 5.0); - QCOMPARE(rect->y(), 19.0 + 5.0); - - delete view; -} -void tst_qquickanchors::margins() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml"))); - - qApp->processEvents(); - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - QCOMPARE(rect->x(), 5.0); - QCOMPARE(rect->y(), 6.0); - QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0); - QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0); - - rectPrivate->anchors()->setTopMargin(0.0); - rectPrivate->anchors()->setMargins(20.0); - - QCOMPARE(rect->x(), 5.0); - QCOMPARE(rect->y(), 20.0); - QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0); - - delete view; -} - -void tst_qquickanchors::marginsRTL() -{ - QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml"))); - - QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - mirrorAnchors(rect); - - QCOMPARE(rect->x(), 10.0); - QCOMPARE(rect->y(), 6.0); - QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0); - QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0); - - rectPrivate->anchors()->setTopMargin(0.0); - rectPrivate->anchors()->setMargins(20.0); - - QCOMPARE(rect->x(), 20.0); - QCOMPARE(rect->y(), 20.0); - QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0); - QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0); - - delete view; -} - - -QTEST_MAIN(tst_qquickanchors) - -#include "tst_qquickanchors.moc" diff --git a/tests/auto/declarative/qquickanimatedimage/data/colors.gif b/tests/auto/declarative/qquickanimatedimage/data/colors.gif deleted file mode 100644 index 1270bfaa79..0000000000 Binary files a/tests/auto/declarative/qquickanimatedimage/data/colors.gif and /dev/null differ diff --git a/tests/auto/declarative/qquickanimatedimage/data/colors.qml b/tests/auto/declarative/qquickanimatedimage/data/colors.qml deleted file mode 100644 index 5ccc0148dd..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/colors.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - source: "colors.gif" -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/hearts.gif b/tests/auto/declarative/qquickanimatedimage/data/hearts.gif deleted file mode 100644 index cfb55f27f5..0000000000 Binary files a/tests/auto/declarative/qquickanimatedimage/data/hearts.gif and /dev/null differ diff --git a/tests/auto/declarative/qquickanimatedimage/data/hearts.qml b/tests/auto/declarative/qquickanimatedimage/data/hearts.qml deleted file mode 100644 index 717bab430b..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/hearts.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - source: "hearts.gif" - playing: false -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/qmldir b/tests/auto/declarative/qquickanimatedimage/data/qmldir deleted file mode 100644 index ef7c1f44f3..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/qmldir +++ /dev/null @@ -1 +0,0 @@ -# No local types diff --git a/tests/auto/declarative/qquickanimatedimage/data/qtbug-16520.qml b/tests/auto/declarative/qquickanimatedimage/data/qtbug-16520.qml deleted file mode 100644 index da77a4063b..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/qtbug-16520.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 500 - height: 500 - - AnimatedImage { - objectName: "anim" - anchors.centerIn: parent - asynchronous: true - opacity: status == AnimatedImage.Ready ? 1 : 0 - - Behavior on opacity { - NumberAnimation { duration: 1000 } - } - } -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickman.gif b/tests/auto/declarative/qquickanimatedimage/data/stickman.gif deleted file mode 100644 index 7c4cd18687..0000000000 Binary files a/tests/auto/declarative/qquickanimatedimage/data/stickman.gif and /dev/null differ diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickman.qml b/tests/auto/declarative/qquickanimatedimage/data/stickman.qml deleted file mode 100644 index a47924de21..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/stickman.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - source: "stickman.gif" -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickmanerror1.qml b/tests/auto/declarative/qquickanimatedimage/data/stickmanerror1.qml deleted file mode 100644 index 4f823b3d70..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/stickmanerror1.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - sourceSize: "240x180" - source: "stickman.gif" -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickmanpause.qml b/tests/auto/declarative/qquickanimatedimage/data/stickmanpause.qml deleted file mode 100644 index ef771ed56f..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/stickmanpause.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - source: "stickman.gif" - paused: true - currentFrame: 2 -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickmanscaled.qml b/tests/auto/declarative/qquickanimatedimage/data/stickmanscaled.qml deleted file mode 100644 index 1ef1f95165..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/stickmanscaled.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - width: 240 - height: 180 - source: "stickman.gif" -} diff --git a/tests/auto/declarative/qquickanimatedimage/data/stickmanstopped.qml b/tests/auto/declarative/qquickanimatedimage/data/stickmanstopped.qml deleted file mode 100644 index 0bf80b8972..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/data/stickmanstopped.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -AnimatedImage { - source: "stickman.gif" - playing: false -} diff --git a/tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro b/tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro deleted file mode 100644 index d6a40e11ce..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/qquickanimatedimage.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickanimatedimage -HEADERS += ../shared/testhttpserver.h -SOURCES += tst_qquickanimatedimage.cpp ../shared/testhttpserver.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp deleted file mode 100644 index 542811efc1..0000000000 --- a/tests/auto/declarative/qquickanimatedimage/tst_qquickanimatedimage.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../shared/testhttpserver.h" -#include "../shared/util.h" - -Q_DECLARE_METATYPE(QQuickImageBase::Status) - -class tst_qquickanimatedimage : public QObject -{ - Q_OBJECT -public: - tst_qquickanimatedimage() {} - -private slots: - void play(); - void pause(); - void stopped(); - void setFrame(); - void frameCount(); - void mirror_running(); - void mirror_notRunning(); - void mirror_notRunning_data(); - void remote(); - void remote_data(); - void sourceSize(); - void sourceSizeReadOnly(); - void invalidSource(); - void qtbug_16520(); - void progressAndStatusChanges(); - -}; - -void tst_qquickanimatedimage::play() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickman.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QVERIFY(anim->isPlaying()); - - delete anim; -} - -void tst_qquickanimatedimage::pause() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QVERIFY(anim->isPlaying()); - QVERIFY(anim->isPaused()); - - delete anim; -} - -void tst_qquickanimatedimage::stopped() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QVERIFY(!anim->isPlaying()); - QCOMPARE(anim->currentFrame(), 0); - - delete anim; -} - -void tst_qquickanimatedimage::setFrame() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QVERIFY(anim->isPlaying()); - QCOMPARE(anim->currentFrame(), 2); - - delete anim; -} - -void tst_qquickanimatedimage::frameCount() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("colors.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QVERIFY(anim->isPlaying()); - QCOMPARE(anim->frameCount(), 3); - - delete anim; -} - -void tst_qquickanimatedimage::mirror_running() -{ - // test where mirror is set to true after animation has started - - QQuickView *canvas = new QQuickView; - canvas->show(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("hearts.qml"))); - QQuickAnimatedImage *anim = qobject_cast(canvas->rootObject()); - QVERIFY(anim); - - int width = anim->property("width").toInt(); - - QCOMPARE(anim->currentFrame(), 0); - QPixmap frame0 = QPixmap::fromImage(canvas->grabFrameBuffer()); - - anim->setCurrentFrame(1); - QPixmap frame1 = QPixmap::fromImage(canvas->grabFrameBuffer()); - - anim->setCurrentFrame(0); - - QSignalSpy spy(anim, SIGNAL(frameChanged())); - anim->setPlaying(true); - - QTRY_VERIFY(spy.count() == 1); spy.clear(); - anim->setProperty("mirror", true); - - QCOMPARE(anim->currentFrame(), 1); - QPixmap frame1_flipped = QPixmap::fromImage(canvas->grabFrameBuffer()); - - QTRY_VERIFY(spy.count() == 1); spy.clear(); - QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first - QPixmap frame0_flipped = QPixmap::fromImage(canvas->grabFrameBuffer()); - - QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved"); - - QTransform transform; - transform.translate(width, 0).scale(-1, 1.0); - QPixmap frame0_expected = frame0.transformed(transform); - QPixmap frame1_expected = frame1.transformed(transform); - - QCOMPARE(frame0_flipped, frame0_expected); - QCOMPARE(frame1_flipped, frame1_expected); - - delete canvas; -} - -void tst_qquickanimatedimage::mirror_notRunning() -{ - QFETCH(QUrl, fileUrl); - - QQuickView *canvas = new QQuickView; - canvas->show(); - - canvas->setSource(fileUrl); - QQuickAnimatedImage *anim = qobject_cast(canvas->rootObject()); - QVERIFY(anim); - - int width = anim->property("width").toInt(); - QPixmap screenshot = QPixmap::fromImage(canvas->grabFrameBuffer()); - - QTransform transform; - transform.translate(width, 0).scale(-1, 1.0); - QPixmap expected = screenshot.transformed(transform); - - int frame = anim->currentFrame(); - bool playing = anim->isPlaying(); - bool paused = anim->isPlaying(); - - anim->setProperty("mirror", true); - screenshot = QPixmap::fromImage(canvas->grabFrameBuffer()); - - QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved"); - QCOMPARE(screenshot, expected); - - // mirroring should not change the current frame or playing status - QCOMPARE(anim->currentFrame(), frame); - QCOMPARE(anim->isPlaying(), playing); - QCOMPARE(anim->isPaused(), paused); - - delete canvas; -} - -void tst_qquickanimatedimage::mirror_notRunning_data() -{ - QTest::addColumn("fileUrl"); - - QTest::newRow("paused") << QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")); - QTest::newRow("stopped") << QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml")); -} - -void tst_qquickanimatedimage::remote() -{ - QFETCH(QString, fileName); - QFETCH(bool, paused); - - TestHTTPServer server(14449); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName)); - QTRY_VERIFY(component.isReady()); - - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - - QTRY_VERIFY(anim->isPlaying()); - if (paused) { - QTRY_VERIFY(anim->isPaused()); - QCOMPARE(anim->currentFrame(), 2); - } - QVERIFY(anim->status() != QQuickAnimatedImage::Error); - - delete anim; -} - -void tst_qquickanimatedimage::sourceSize() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanscaled.qml"))); - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - QCOMPARE(anim->width(),240.0); - QCOMPARE(anim->height(),180.0); - QCOMPARE(anim->sourceSize(),QSize(160,120)); - - delete anim; -} - -void tst_qquickanimatedimage::sourceSizeReadOnly() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanerror1.qml"))); - QVERIFY(component.isError()); - QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property")); -} - -void tst_qquickanimatedimage::remote_data() -{ - QTest::addColumn("fileName"); - QTest::addColumn("paused"); - - QTest::newRow("playing") << "stickman.qml" << false; - QTest::newRow("paused") << "stickmanpause.qml" << true; -} - -void tst_qquickanimatedimage::invalidSource() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile("")); - QVERIFY(component.isReady()); - - QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif"); - - QQuickAnimatedImage *anim = qobject_cast(component.create()); - QVERIFY(anim); - - QVERIFY(!anim->isPlaying()); - QVERIFY(!anim->isPaused()); - QCOMPARE(anim->currentFrame(), 0); - QCOMPARE(anim->frameCount(), 0); - QTRY_VERIFY(anim->status() == 3); -} - -void tst_qquickanimatedimage::qtbug_16520() -{ - TestHTTPServer server(14449); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("qtbug-16520.qml"))); - QTRY_VERIFY(component.isReady()); - - QQuickRectangle *root = qobject_cast(component.create()); - QVERIFY(root); - QQuickAnimatedImage *anim = root->findChild("anim"); - - anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif"); - - QTRY_VERIFY(anim->opacity() == 0); - QTRY_VERIFY(anim->opacity() == 1); - - delete anim; -} - -void tst_qquickanimatedimage::progressAndStatusChanges() -{ - TestHTTPServer server(14449); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - QDeclarativeEngine engine; - QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("stickman.gif"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - - qRegisterMetaType(); - QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &))); - QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); - QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status))); - - // Loading local file - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.gif"))); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - QTRY_COMPARE(sourceSpy.count(), 1); - QTRY_COMPARE(progressSpy.count(), 0); - QTRY_COMPARE(statusSpy.count(), 0); - - // Loading remote file - ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif"); - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - QTRY_COMPARE(sourceSpy.count(), 2); - QTRY_VERIFY(progressSpy.count() > 1); - QTRY_COMPARE(statusSpy.count(), 2); - - ctxt->setContextProperty("srcImage", ""); - QTRY_VERIFY(obj->status() == QQuickImage::Null); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_COMPARE(sourceSpy.count(), 3); - QTRY_VERIFY(progressSpy.count() > 2); - QTRY_COMPARE(statusSpy.count(), 3); -} - -QTEST_MAIN(tst_qquickanimatedimage) - -#include "tst_qquickanimatedimage.moc" diff --git a/tests/auto/declarative/qquickborderimage/data/colors-mirror.png b/tests/auto/declarative/qquickborderimage/data/colors-mirror.png deleted file mode 100644 index e30870dd1e..0000000000 Binary files a/tests/auto/declarative/qquickborderimage/data/colors-mirror.png and /dev/null differ diff --git a/tests/auto/declarative/qquickborderimage/data/colors-round-quotes.sci b/tests/auto/declarative/qquickborderimage/data/colors-round-quotes.sci deleted file mode 100644 index 294f3cfe48..0000000000 --- a/tests/auto/declarative/qquickborderimage/data/colors-round-quotes.sci +++ /dev/null @@ -1,7 +0,0 @@ -border.left:10 -border.top:20 -border.right:30 -border.bottom:40 -horizontalTileRule:Round -verticalTileRule:Repeat -source:"colors.png" diff --git a/tests/auto/declarative/qquickborderimage/data/colors-round-remote.sci b/tests/auto/declarative/qquickborderimage/data/colors-round-remote.sci deleted file mode 100644 index c673bed598..0000000000 --- a/tests/auto/declarative/qquickborderimage/data/colors-round-remote.sci +++ /dev/null @@ -1,7 +0,0 @@ -border.left:10 -border.top:20 -border.right:30 -border.bottom:40 -horizontalTileRule:Round -verticalTileRule:Repeat -source:http://127.0.0.1:14446/colors.png diff --git a/tests/auto/declarative/qquickborderimage/data/colors-round.sci b/tests/auto/declarative/qquickborderimage/data/colors-round.sci deleted file mode 100644 index 5d2f49f0e1..0000000000 --- a/tests/auto/declarative/qquickborderimage/data/colors-round.sci +++ /dev/null @@ -1,7 +0,0 @@ -border.left:10 -border.top:20 -border.right:30 -border.bottom:40 -horizontalTileRule:Round -verticalTileRule:Repeat -source:colors.png diff --git a/tests/auto/declarative/qquickborderimage/data/colors.png b/tests/auto/declarative/qquickborderimage/data/colors.png deleted file mode 100644 index dfb62f3d64..0000000000 Binary files a/tests/auto/declarative/qquickborderimage/data/colors.png and /dev/null differ diff --git a/tests/auto/declarative/qquickborderimage/data/heart200.png b/tests/auto/declarative/qquickborderimage/data/heart200.png deleted file mode 100644 index 5a31ae8f4d..0000000000 Binary files a/tests/auto/declarative/qquickborderimage/data/heart200.png and /dev/null differ diff --git a/tests/auto/declarative/qquickborderimage/data/invalid.sci b/tests/auto/declarative/qquickborderimage/data/invalid.sci deleted file mode 100644 index 98c72c9bf1..0000000000 --- a/tests/auto/declarative/qquickborderimage/data/invalid.sci +++ /dev/null @@ -1,7 +0,0 @@ -border.left:10 -border.top:20 -border.down:30 -border.up:40 -horizontalTileRule:Roun -verticalTileRule:Repea -source:colors.png diff --git a/tests/auto/declarative/qquickborderimage/data/mirror.qml b/tests/auto/declarative/qquickborderimage/data/mirror.qml deleted file mode 100644 index abab076e08..0000000000 --- a/tests/auto/declarative/qquickborderimage/data/mirror.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -BorderImage { - source: "colors-mirror.png" - width: 300; height: 300 - border { top: 30; right: 30; bottom: 30; left: 30 } -} diff --git a/tests/auto/declarative/qquickborderimage/qquickborderimage.pro b/tests/auto/declarative/qquickborderimage/qquickborderimage.pro deleted file mode 100644 index b1ccf4a939..0000000000 --- a/tests/auto/declarative/qquickborderimage/qquickborderimage.pro +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickborderimage -macx:CONFIG -= app_bundle - -HEADERS += ../shared/testhttpserver.h -SOURCES += tst_qquickborderimage.cpp ../shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network widgets testlib diff --git a/tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp deleted file mode 100644 index 4fb6ed7057..0000000000 --- a/tests/auto/declarative/qquickborderimage/tst_qquickborderimage.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../shared/testhttpserver.h" -#include "../shared/util.h" - -#define SERVER_PORT 14446 -#define SERVER_ADDR "http://127.0.0.1:14446" - -class tst_qquickborderimage : public QObject - -{ - Q_OBJECT -public: - tst_qquickborderimage(); - -private slots: - void noSource(); - void imageSource(); - void imageSource_data(); - void clearSource(); - void resized(); - void smooth(); - void mirror(); - void tileModes(); - void sciSource(); - void sciSource_data(); - void invalidSciFile(); - void pendingRemoteRequest(); - void pendingRemoteRequest_data(); - -private: - QDeclarativeEngine engine; -}; - -tst_qquickborderimage::tst_qquickborderimage() -{ -} - -void tst_qquickborderimage::noSource() -{ - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->source(), QUrl()); - QCOMPARE(obj->width(), 0.); - QCOMPARE(obj->height(), 0.); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); - - delete obj; -} - -void tst_qquickborderimage::imageSource_data() -{ - QTest::addColumn("source"); - QTest::addColumn("remote"); - QTest::addColumn("error"); - - QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << false << ""; - QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << false - << "file::2:1: QML BorderImage: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString(); - QTest::newRow("remote") << SERVER_ADDR "/colors.png" << true << ""; - QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << true - << "file::2:1: QML BorderImage: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; -} - -void tst_qquickborderimage::imageSource() -{ - QFETCH(QString, source); - QFETCH(bool, remote); - QFETCH(QString, error); - - TestHTTPServer *server = 0; - if (remote) { - server = new TestHTTPServer(SERVER_PORT); - QVERIFY(server->isValid()); - server->serveDirectory(TESTDATA("")); - } - - if (!error.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); - - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - - if (remote) - QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); - - QCOMPARE(obj->source(), remote ? source : QUrl(source)); - - if (error.isEmpty()) { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); - QCOMPARE(obj->width(), 120.); - QCOMPARE(obj->height(), 120.); - QCOMPARE(obj->sourceSize().width(), 120); - QCOMPARE(obj->sourceSize().height(), 120); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); - } else { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); - } - - delete obj; - delete server; -} - -void tst_qquickborderimage::clearSource() -{ - QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickBorderImage::Ready); - QCOMPARE(obj->width(), 120.); - QCOMPARE(obj->height(), 120.); - - ctxt->setContextProperty("srcImage", ""); - QVERIFY(obj->source().isEmpty()); - QVERIFY(obj->status() == QQuickBorderImage::Null); - QCOMPARE(obj->width(), 0.); - QCOMPARE(obj->height(), 0.); -} - -void tst_qquickborderimage::resized() -{ - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("colors.png")).toString() + "\"; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->sourceSize().width(), 120); - QCOMPARE(obj->sourceSize().height(), 120); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); - - delete obj; -} - -void tst_qquickborderimage::smooth() -{ - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->smooth(), true); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); - - delete obj; -} - -void tst_qquickborderimage::mirror() -{ - QQuickView *canvas = new QQuickView; - canvas->show(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml"))); - QQuickBorderImage *image = qobject_cast(canvas->rootObject()); - QVERIFY(image != 0); - canvas->show(); - - QImage screenshot = canvas->grabFrameBuffer(); - - QImage srcPixmap(screenshot); - QTransform transform; - transform.translate(image->width(), 0).scale(-1, 1.0); - srcPixmap = srcPixmap.transformed(transform); - - image->setProperty("mirror", true); - screenshot = canvas->grabFrameBuffer(); - QCOMPARE(screenshot, srcPixmap); - - delete canvas; -} - -void tst_qquickborderimage::tileModes() -{ - { - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 100; height: 300; horizontalTileMode: BorderImage.Repeat; verticalTileMode: BorderImage.Repeat }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 100.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Repeat); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat); - - delete obj; - } - { - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 150; horizontalTileMode: BorderImage.Round; verticalTileMode: BorderImage.Round }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 150.); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Round); - - delete obj; - } -} - -void tst_qquickborderimage::sciSource() -{ - QFETCH(QString, source); - QFETCH(bool, valid); - - bool remote = source.startsWith("http"); - TestHTTPServer *server = 0; - if (remote) { - server = new TestHTTPServer(SERVER_PORT); - QVERIFY(server->isValid()); - server->serveDirectory(TESTDATA("")); - } - - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - - if (remote) - QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); - - QCOMPARE(obj->source(), remote ? source : QUrl(source)); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - - if (valid) { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); - QCOMPARE(obj->border()->left(), 10); - QCOMPARE(obj->border()->top(), 20); - QCOMPARE(obj->border()->right(), 30); - QCOMPARE(obj->border()->bottom(), 40); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat); - } else { - QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); - } - - delete obj; - delete server; -} - -void tst_qquickborderimage::sciSource_data() -{ - QTest::addColumn("source"); - QTest::addColumn("valid"); - - QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors-round.sci")).toString() << true; - QTest::newRow("local quoted filename") << QUrl::fromLocalFile(TESTDATA("colors-round-quotes.sci")).toString() << true; - QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.sci")).toString() << false; - QTest::newRow("remote") << SERVER_ADDR "/colors-round.sci" << true; - QTest::newRow("remote filename quoted") << SERVER_ADDR "/colors-round-quotes.sci" << true; - QTest::newRow("remote image") << SERVER_ADDR "/colors-round-remote.sci" << true; - QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.sci" << false; -} - -void tst_qquickborderimage::invalidSciFile() -{ - QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Roun" - QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Repea" - - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("invalid.sci")).toString() +"\"; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->status(), QQuickImageBase::Error); - QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); - QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); - - delete obj; -} - -void tst_qquickborderimage::pendingRemoteRequest() -{ - QFETCH(QString, source); - - QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickBorderImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->status(), QQuickBorderImage::Loading); - - // verify no crash - // This will cause a delayed "QThread: Destroyed while thread is still running" warning - delete obj; - QTest::qWait(50); -} - -void tst_qquickborderimage::pendingRemoteRequest_data() -{ - QTest::addColumn("source"); - - QTest::newRow("png file") << "http://localhost/none.png"; - QTest::newRow("sci file") << "http://localhost/none.sci"; -} - -QTEST_MAIN(tst_qquickborderimage) - -#include "tst_qquickborderimage.moc" diff --git a/tests/auto/declarative/qquickcanvas/data/window.qml b/tests/auto/declarative/qquickcanvas/data/window.qml deleted file mode 100644 index d79d5161b5..0000000000 --- a/tests/auto/declarative/qquickcanvas/data/window.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import QtQuick.Window 2.0 as Window - -Window.Window { - color: "#00FF00" - Item { - objectName: "item" - } -} diff --git a/tests/auto/declarative/qquickcanvas/qquickcanvas.pro b/tests/auto/declarative/qquickcanvas/qquickcanvas.pro deleted file mode 100644 index b45a3597d4..0000000000 --- a/tests/auto/declarative/qquickcanvas/qquickcanvas.pro +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickcanvas -SOURCES += tst_qquickcanvas.cpp - -macx:CONFIG -= app_bundle - -CONFIG += parallel_test -QT += core-private gui-private declarative-private testlib diff --git a/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp deleted file mode 100644 index 829d666b7e..0000000000 --- a/tests/auto/declarative/qquickcanvas/tst_qquickcanvas.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -struct TouchEventData { - QEvent::Type type; - QWidget *widget; - QWindow *window; - Qt::TouchPointStates states; - QList touchPoints; -}; - -static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF()) -{ - QPointF last = lastPoint.isNull() ? p : lastPoint; - - QTouchEvent::TouchPoint tp; - - tp.setPos(p); - tp.setLastPos(last); - tp.setScenePos(item->mapToScene(p)); - tp.setLastScenePos(item->mapToScene(last)); - tp.setScreenPos(item->canvas()->mapToGlobal(tp.scenePos().toPoint())); - tp.setLastScreenPos(item->canvas()->mapToGlobal(tp.lastScenePos().toPoint())); - return tp; -} - -static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QList &touchPoints) -{ - TouchEventData d = { type, w, 0, states, touchPoints }; - return d; -} - -static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint) -{ - QList points; - points << touchPoint; - return makeTouchData(type, w, states, points); -} -static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList& touchPoints) -{ - TouchEventData d = { type, 0, w, states, touchPoints }; - return d; -} -static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint) -{ - QList points; - points << touchPoint; - return makeTouchData(type, w, states, points); -} - -#define COMPARE_TOUCH_POINTS(tp1, tp2) \ -{ \ - QCOMPARE(tp1.pos(), tp2.pos()); \ - QCOMPARE(tp1.lastPos(), tp2.lastPos()); \ - QCOMPARE(tp1.scenePos(), tp2.scenePos()); \ - QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \ - QCOMPARE(tp1.screenPos(), tp2.screenPos()); \ - QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \ -} - -#define COMPARE_TOUCH_DATA(d1, d2) \ -{ \ - QCOMPARE((int)d1.type, (int)d2.type); \ - QCOMPARE(d1.widget, d2.widget); \ - QCOMPARE((int)d1.states, (int)d2.states); \ - QCOMPARE(d1.touchPoints.count(), d2.touchPoints.count()); \ - for (int i=0; isetWidth(1); - setAcceptedMouseButtons(Qt::LeftButton); - setFiltersChildMouseEvents(true); - } - - void reset() { - acceptEvents = true; - setEnabled(true); - setOpacity(1.0); - - lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList());//CHECK_VALID - } - - bool acceptEvents; - TouchEventData lastEvent; - int mousePressId; - -protected: - virtual void touchEvent(QTouchEvent *event) { - if (!acceptEvents) { - event->ignore(); - return; - } - lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints()); - event->accept(); - } - - virtual void mousePressEvent(QMouseEvent *) { - mousePressId = ++mousePressNum; - } - - bool childMouseEventFilter(QQuickItem *, QEvent *event) { - if (event->type() == QEvent::MouseButtonPress) - mousePressId = ++mousePressNum; - return false; - } - - static int mousePressNum; -}; - -int TestTouchItem::mousePressNum = 0; - -class ConstantUpdateItem : public QQuickItem -{ -Q_OBJECT -public: - ConstantUpdateItem(QQuickItem *parent = 0) : QQuickItem(parent), iterations(0) {setFlag(ItemHasContents);} - - int iterations; -protected: - QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){ - iterations++; - update(); - return 0; - } -}; - -class tst_qquickcanvas : public QObject -{ - Q_OBJECT -public: - tst_qquickcanvas(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void constantUpdates(); - - void touchEvent_basic(); - void touchEvent_propagation(); - void touchEvent_propagation_data(); - - void clearCanvas(); - void mouseFiltering(); - - void qmlCreation(); - void clearColor(); -}; - -tst_qquickcanvas::tst_qquickcanvas() -{ -} - -void tst_qquickcanvas::initTestCase() -{ -} - -void tst_qquickcanvas::cleanupTestCase() -{ -} - -//If the item calls update inside updatePaintNode, it should schedule another update -void tst_qquickcanvas::constantUpdates() -{ - QQuickCanvas canvas; - ConstantUpdateItem item(canvas.rootItem()); - canvas.show(); - QTRY_VERIFY(item.iterations > 60); -} - -void tst_qquickcanvas::touchEvent_basic() -{ - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(250, 250); - canvas->move(100, 100); - canvas->show(); - - TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); - bottomItem->setObjectName("Bottom Item"); - bottomItem->setSize(QSizeF(150, 150)); - - TestTouchItem *middleItem = new TestTouchItem(bottomItem); - middleItem->setObjectName("Middle Item"); - middleItem->setPos(QPointF(50, 50)); - middleItem->setSize(QSizeF(150, 150)); - - TestTouchItem *topItem = new TestTouchItem(middleItem); - topItem->setObjectName("Top Item"); - topItem->setPos(QPointF(50, 50)); - topItem->setSize(QSizeF(150, 150)); - - QPointF pos(10, 10); - - // press single point - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas); - QTest::qWait(50); - - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); - TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos)); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); - topItem->reset(); - - // press multiple points - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas) - .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); - topItem->reset(); - bottomItem->reset(); - - // touch point on top item moves to bottom item, but top item should still receive the event - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved, - makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos))); - topItem->reset(); - - // touch point on bottom item moves to top item, but bottom item should still receive the event - QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved, - makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos))); - bottomItem->reset(); - - // a single stationary press on an item shouldn't cause an event - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).stationary(0) - .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); - topItem->reset(); - bottomItem->reset(); - - // move touch point from top item to bottom, and release - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(),canvas); - QTest::qWait(50); - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased, - makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos))); - topItem->reset(); - - // release while another point is pressed - QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas) - .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas); - QTest::qWait(50); - QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(), canvas) - .stationary(1); - QTest::qWait(50); - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased, - makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos)))); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); - topItem->reset(); - bottomItem->reset(); - - delete topItem; - delete middleItem; - delete bottomItem; - delete canvas; -} - -void tst_qquickcanvas::touchEvent_propagation() -{ - QFETCH(bool, acceptEvents); - QFETCH(bool, enableItem); - QFETCH(qreal, itemOpacity); - - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(250, 250); - canvas->move(100, 100); - canvas->show(); - - TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); - bottomItem->setObjectName("Bottom Item"); - bottomItem->setSize(QSizeF(150, 150)); - - TestTouchItem *middleItem = new TestTouchItem(bottomItem); - middleItem->setObjectName("Middle Item"); - middleItem->setPos(QPointF(50, 50)); - middleItem->setSize(QSizeF(150, 150)); - - TestTouchItem *topItem = new TestTouchItem(middleItem); - topItem->setObjectName("Top Item"); - topItem->setPos(QPointF(50, 50)); - topItem->setSize(QSizeF(150, 150)); - - QPointF pos(10, 10); - QPoint pointInBottomItem = bottomItem->mapToScene(pos).toPoint(); // (10, 10) - QPoint pointInMiddleItem = middleItem->mapToScene(pos).toPoint(); // (60, 60) overlaps with bottomItem - QPoint pointInTopItem = topItem->mapToScene(pos).toPoint(); // (110, 110) overlaps with bottom & top items - - // disable topItem - topItem->acceptEvents = acceptEvents; - topItem->setEnabled(enableItem); - topItem->setOpacity(itemOpacity); - - // single touch to top item, should be received by middle item - QTest::touchEvent(canvas).press(0, pointInTopItem, canvas); - QTest::qWait(50); - QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1); - QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); - COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, - makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos)))); - - // touch top and middle items, middle item should get both events - QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) - .press(1, pointInMiddleItem, canvas); - QTest::qWait(50); - QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2); - QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); - COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, - (QList() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos)) - << makeTouchPoint(middleItem, pos) ))); - middleItem->reset(); - - // disable middleItem as well - middleItem->acceptEvents = acceptEvents; - middleItem->setEnabled(enableItem); - middleItem->setOpacity(itemOpacity); - - // touch top and middle items, bottom item should get all events - QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) - .press(1, pointInMiddleItem, canvas); - QTest::qWait(50); - QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, - (QList() << makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos)) - << makeTouchPoint(bottomItem, bottomItem->mapFromItem(middleItem, pos)) ))); - bottomItem->reset(); - - // disable bottom item as well - bottomItem->acceptEvents = acceptEvents; - bottomItem->setEnabled(enableItem); - bottomItem->setOpacity(itemOpacity); - - // no events should be received - QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) - .press(1, pointInMiddleItem, canvas) - .press(2, pointInBottomItem, canvas); - QTest::qWait(50); - QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); - - topItem->reset(); - middleItem->reset(); - bottomItem->reset(); - - // disable middle item, touch on top item - middleItem->acceptEvents = acceptEvents; - middleItem->setEnabled(enableItem); - middleItem->setOpacity(itemOpacity); - QTest::touchEvent(canvas).press(0, pointInTopItem, canvas); - QTest::qWait(50); - if (!enableItem || itemOpacity == 0) { - // middle item is disabled or has 0 opacity, bottom item receives the event - QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); - COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, - makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos)))); - } else { - // middle item ignores event, sends it to the top item (top-most child) - QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); - QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); - QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); - COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, - makeTouchPoint(topItem, pos))); - } - - delete topItem; - delete middleItem; - delete bottomItem; - delete canvas; -} - -void tst_qquickcanvas::touchEvent_propagation_data() -{ - QTest::addColumn("acceptEvents"); - QTest::addColumn("enableItem"); - QTest::addColumn("itemOpacity"); - - QTest::newRow("disable events") << false << true << 1.0; - QTest::newRow("disable item") << true << false << 1.0; - QTest::newRow("opacity of 0") << true << true << 0.0; -} - -void tst_qquickcanvas::clearCanvas() -{ - QQuickCanvas *canvas = new QQuickCanvas; - QQuickItem *item = new QQuickItem; - item->setParentItem(canvas->rootItem()); - - QVERIFY(item->canvas() == canvas); - - delete canvas; - - QVERIFY(item->canvas() == 0); - - delete item; -} - -void tst_qquickcanvas::mouseFiltering() -{ - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(250, 250); - canvas->move(100, 100); - canvas->show(); - - TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); - bottomItem->setObjectName("Bottom Item"); - bottomItem->setSize(QSizeF(150, 150)); - - TestTouchItem *middleItem = new TestTouchItem(bottomItem); - middleItem->setObjectName("Middle Item"); - middleItem->setPos(QPointF(50, 50)); - middleItem->setSize(QSizeF(150, 150)); - - TestTouchItem *topItem = new TestTouchItem(middleItem); - topItem->setObjectName("Top Item"); - topItem->setPos(QPointF(50, 50)); - topItem->setSize(QSizeF(150, 150)); - - QPoint pos(100, 100); - - QTest::mousePress(canvas, Qt::LeftButton, 0, pos); - QTest::qWait(50); - - // Mouse filtering propagates down the stack, so the - // correct order is - // 1. middleItem filters event - // 2. bottomItem filters event - // 3. topItem receives event - QCOMPARE(middleItem->mousePressId, 1); - QCOMPARE(bottomItem->mousePressId, 2); - QCOMPARE(topItem->mousePressId, 3); -} - -void tst_qquickcanvas::qmlCreation() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - component.loadUrl(TESTDATA("window.qml")); - QObject* created = component.create(); - QVERIFY(created); - - QQuickCanvas* canvas = qobject_cast(created); - QVERIFY(canvas); - QCOMPARE(canvas->clearColor(), QColor(Qt::green)); - - QQuickItem* item = canvas->findChild("item"); - QVERIFY(item); - QCOMPARE(item->canvas(), canvas); -} - -void tst_qquickcanvas::clearColor() -{ - //### Can we examine rendering to make sure it is really blue? - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(250, 250); - canvas->move(100, 100); - canvas->setClearColor(Qt::blue); - canvas->show(); - QTest::qWaitForWindowShown(canvas); - QCOMPARE(canvas->clearColor(), QColor(Qt::blue)); - delete canvas; -} - -QTEST_MAIN(tst_qquickcanvas) - -#include "tst_qquickcanvas.moc" diff --git a/tests/auto/declarative/qquickcanvasitem/data/anim-gr.gif b/tests/auto/declarative/qquickcanvasitem/data/anim-gr.gif deleted file mode 100644 index 45263e0afb..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/anim-gr.gif and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/anim-gr.png b/tests/auto/declarative/qquickcanvasitem/data/anim-gr.png deleted file mode 100644 index 925e2efc9a..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/anim-gr.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/anim-poster-gr.png b/tests/auto/declarative/qquickcanvasitem/data/anim-poster-gr.png deleted file mode 100644 index 6941207373..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/anim-poster-gr.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/background.png b/tests/auto/declarative/qquickcanvasitem/data/background.png deleted file mode 100644 index 6db6c6b1b9..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/background.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/broken.png b/tests/auto/declarative/qquickcanvasitem/data/broken.png deleted file mode 100644 index f2581017b4..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/broken.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/ggrr-256x256.png b/tests/auto/declarative/qquickcanvasitem/data/ggrr-256x256.png deleted file mode 100644 index 0342e4a384..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/ggrr-256x256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/green-16x16.png b/tests/auto/declarative/qquickcanvasitem/data/green-16x16.png deleted file mode 100644 index e19a3ffddd..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/green-16x16.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/green-1x1.png b/tests/auto/declarative/qquickcanvasitem/data/green-1x1.png deleted file mode 100644 index 862d1dd10c..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/green-1x1.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/green-256x256.png b/tests/auto/declarative/qquickcanvasitem/data/green-256x256.png deleted file mode 100644 index b06945c310..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/green-256x256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/green-2x2.png b/tests/auto/declarative/qquickcanvasitem/data/green-2x2.png deleted file mode 100644 index adc059449c..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/green-2x2.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/green.png b/tests/auto/declarative/qquickcanvasitem/data/green.png deleted file mode 100644 index 28a1faab37..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/green.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/grgr-256x256.png b/tests/auto/declarative/qquickcanvasitem/data/grgr-256x256.png deleted file mode 100644 index b8c7189d62..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/grgr-256x256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/red-16x16.png b/tests/auto/declarative/qquickcanvasitem/data/red-16x16.png deleted file mode 100644 index 9038fef784..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/red-16x16.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/red.png b/tests/auto/declarative/qquickcanvasitem/data/red.png deleted file mode 100644 index a6e195d59c..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/red.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/redtransparent.png b/tests/auto/declarative/qquickcanvasitem/data/redtransparent.png deleted file mode 100644 index 75da08c3d6..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/redtransparent.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/rgrg-256x256.png b/tests/auto/declarative/qquickcanvasitem/data/rgrg-256x256.png deleted file mode 100644 index e6fba3daa5..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/rgrg-256x256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/rrgg-256x256.png b/tests/auto/declarative/qquickcanvasitem/data/rrgg-256x256.png deleted file mode 100644 index 7f63515654..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/rrgg-256x256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/testhelper.js b/tests/auto/declarative/qquickcanvasitem/data/testhelper.js deleted file mode 100644 index bac0210e16..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/testhelper.js +++ /dev/null @@ -1,18 +0,0 @@ -function comparePixel(ctx,x,y,r,g,b,a, d) -{ - var c = ctx.getImageData(x,y,1,1).data; - if (d === undefined) - d = 0; - r = Math.round(r); - g = Math.round(g); - b = Math.round(b); - a = Math.round(a); - - if (Math.abs(c[0]-r)>d || Math.abs(c[1]-g)>d || Math.abs(c[2]-b)>d || Math.abs(c[3]-a)>d) { - console.log('Pixel compare fail:\nactual :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d); - return false; - } - return true; -} - - diff --git a/tests/auto/declarative/qquickcanvasitem/data/transparent.png b/tests/auto/declarative/qquickcanvasitem/data/transparent.png deleted file mode 100644 index 2b498699a8..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/transparent.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/transparent50.png b/tests/auto/declarative/qquickcanvasitem/data/transparent50.png deleted file mode 100644 index 55f8e69325..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/transparent50.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_arc.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_arc.qml deleted file mode 100644 index 6006a5a4c0..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_arc.qml +++ /dev/null @@ -1,487 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper - -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - name: "arc"; when: windowShown - function test_angle_1() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 0); - ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true); - ctx.fill(); - verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_angle_2() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 0); - ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true); - ctx.fill(); - verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_angle_3() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 0); - ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true); - ctx.fill(); - //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_angle_4() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false); - ctx.fill(); - verify(Helper.comparePixel(ctx,1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx,98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx,1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx,98,48, 0,255,0,255)); - } - function test_angle_5() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 0); - ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false); - ctx.fill(); - /*FIXME: - actual :[255,0,0,255] - expected:[0,255,0,255] +/- 0 - */ - //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - - function test_angle_6() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true); - ctx.fill(); - - verify(Helper.comparePixel(ctx,1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx,98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx,1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx,98,48, 0,255,0,255)); - } - - function test_empty() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arc(200, 25, 5, 0, 2*Math.PI, true); - ctx.stroke(); - /*FIXME: - actual :[255,0,0,255] - expected:[0,255,0,255] +/- 0 - */ - //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_nonempty() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arc(200, 25, 5, 0, 2*Math.PI, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_nonfinite() { - skip("FIXME"); - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true); - ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true); - ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true); - ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true); - ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true); - ctx.arc(0, NaN, 50, 0, 2*Math.PI, true); - ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true); - ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true); - ctx.arc(0, 0, NaN, 0, 2*Math.PI, true); - ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true); - ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true); - ctx.arc(0, 0, 50, NaN, 2*Math.PI, true); - ctx.arc(0, 0, 50, 0, Infinity, true); - ctx.arc(0, 0, 50, 0, -Infinity, true); - ctx.arc(0, 0, 50, 0, NaN, true); - ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true); - ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true); - ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true); - ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true); - ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true); - ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true); - ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true); - ctx.arc(Infinity, Infinity, 50, 0, Infinity, true); - ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true); - ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true); - ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true); - ctx.arc(Infinity, 0, Infinity, 0, Infinity, true); - ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true); - ctx.arc(Infinity, 0, 50, Infinity, Infinity, true); - ctx.arc(Infinity, 0, 50, 0, Infinity, true); - ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true); - ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true); - ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true); - ctx.arc(0, Infinity, Infinity, 0, Infinity, true); - ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true); - ctx.arc(0, Infinity, 50, Infinity, Infinity, true); - ctx.arc(0, Infinity, 50, 0, Infinity, true); - ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true); - ctx.arc(0, 0, Infinity, Infinity, Infinity, true); - ctx.arc(0, 0, Infinity, 0, Infinity, true); - ctx.arc(0, 0, 50, Infinity, Infinity, true); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx,90,45, 0,255,0,255)); - } - function test_end() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(-100, 0); - ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true); - ctx.lineTo(100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); - } - function test_negative() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - try { var err = false; - ctx.arc(0, 0, -1, 0, 0, true); - } catch (e) { - if (e.code != DOMException.INDEX_SIZE_ERR) - fail("expected exception of type INDEX_SIZE_ERR, got: "+e.message); - err = true; - } finally { - verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.arc(0, 0, -1, 0, 0, true)"); - } - - } - - function test_scale_1() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.scale(2, 0.5); - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.arc(25, 50, 56, 0, 2*Math.PI, false); - ctx.fill(); - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(-25, 50); - ctx.arc(-25, 50, 24, 0, 2*Math.PI, false); - ctx.moveTo(75, 50); - ctx.arc(75, 50, 24, 0, 2*Math.PI, false); - ctx.moveTo(25, -25); - ctx.arc(25, -25, 24, 0, 2*Math.PI, false); - ctx.moveTo(25, 125); - ctx.arc(25, 125, 24, 0, 2*Math.PI, false); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - } - - function test_scale_2() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.scale(100, 100); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 1.2; - ctx.beginPath(); - ctx.arc(0, 0, 0.6, 0, Math.PI/2, false); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_selfintersect_1() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 200; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arc(100, 50, 25, 0, -Math.PI/2, true); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(0, 0, 25, 0, -Math.PI/2, true); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_selfintersect_2() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 180; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.arc(-50, 50, 25, 0, -Math.PI/2, true); - ctx.stroke(); - ctx.beginPath(); - ctx.arc(100, 0, 25, 0, -Math.PI/2, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 97,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 97,2, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 97,3, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 2,48, 0,255,0,255)); - } - - function test_shape_1() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arc(50, 50, 50, 0, Math.PI, false); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_shape_2() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 100; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.arc(50, 50, 50, 0, Math.PI, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - function test_shape_3() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 100; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arc(0, 50, 50, 0, -Math.PI/2, false); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_shape_4() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 150; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.arc(-50, 50, 100, 0, -Math.PI/2, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_shape_5() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 200; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arc(300, 0, 100, 0, 5*Math.PI, false); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_twopie() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - } - - function test_zero() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 0, true); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.arc(50, 25, 50, 0, 0, false); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00' - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arc(200, 25, 0, 0, Math.PI, true); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_arcto.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_arcto.qml deleted file mode 100644 index cc1d88672b..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_arcto.qml +++ /dev/null @@ -1,410 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper - -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - name: "arcTo"; when: windowShown - function test_coincide() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(0, 25, 50, 1000, 1); - ctx.lineTo(100, 25); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.arcTo(50, 25, 100, 25, 1); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, 100, 25, 1); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_collinear() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, 200, 25, 1); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(-100, 25); - ctx.arcTo(0, 25, 100, 25, 1); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, 10, 25, 1); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 25); - ctx.arcTo(200, 25, 110, 25, 1); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, -100, 25, 1); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 25); - ctx.arcTo(200, 25, 0, 25, 1); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(-100, 25); - ctx.arcTo(0, 25, -200, 25, 1); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_subpath() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.arcTo(100, 50, 200, 50, 0.1); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.arcTo(0, 25, 50, 250, 0.1); - ctx.lineTo(100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_negative() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - try { var err = false; - ctx.arcTo(0, 0, 0, 0, -1); - } catch (e) { - if (e.code != DOMException.INDEX_SIZE_ERR) - fail("expectes INDEX_SIZE_ERR, got: "+e.message); - err = true; - } - finally { - verify(err, "should throw INDEX_SIZE_ERR: ctx.arcTo(0, 0, 0, 0, -1)"); - } - } - - function test_nonfinite() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - skip("FIXME"); - - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.arcTo(Infinity, 50, 0, 50, 0); - ctx.arcTo(-Infinity, 50, 0, 50, 0); - ctx.arcTo(NaN, 50, 0, 50, 0); - ctx.arcTo(0, Infinity, 0, 50, 0); - ctx.arcTo(0, -Infinity, 0, 50, 0); - ctx.arcTo(0, NaN, 0, 50, 0); - ctx.arcTo(0, 50, Infinity, 50, 0); - ctx.arcTo(0, 50, -Infinity, 50, 0); - ctx.arcTo(0, 50, NaN, 50, 0); - ctx.arcTo(0, 50, 0, Infinity, 0); - ctx.arcTo(0, 50, 0, -Infinity, 0); - ctx.arcTo(0, 50, 0, NaN, 0); - ctx.arcTo(0, 50, 0, 50, Infinity); - ctx.arcTo(0, 50, 0, 50, -Infinity); - ctx.arcTo(0, 50, 0, 50, NaN); - ctx.arcTo(Infinity, Infinity, 0, 50, 0); - ctx.arcTo(Infinity, Infinity, Infinity, 50, 0); - ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0); - ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity); - ctx.arcTo(Infinity, Infinity, 0, Infinity, 0); - ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity); - ctx.arcTo(Infinity, Infinity, 0, 50, Infinity); - ctx.arcTo(Infinity, 50, Infinity, 50, 0); - ctx.arcTo(Infinity, 50, Infinity, Infinity, 0); - ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity); - ctx.arcTo(Infinity, 50, Infinity, 50, Infinity); - ctx.arcTo(Infinity, 50, 0, Infinity, 0); - ctx.arcTo(Infinity, 50, 0, Infinity, Infinity); - ctx.arcTo(Infinity, 50, 0, 50, Infinity); - ctx.arcTo(0, Infinity, Infinity, 50, 0); - ctx.arcTo(0, Infinity, Infinity, Infinity, 0); - ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity); - ctx.arcTo(0, Infinity, Infinity, 50, Infinity); - ctx.arcTo(0, Infinity, 0, Infinity, 0); - ctx.arcTo(0, Infinity, 0, Infinity, Infinity); - ctx.arcTo(0, Infinity, 0, 50, Infinity); - ctx.arcTo(0, 50, Infinity, Infinity, 0); - ctx.arcTo(0, 50, Infinity, Infinity, Infinity); - ctx.arcTo(0, 50, Infinity, 50, Infinity); - ctx.arcTo(0, 50, 0, Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); - - } - function test_scale() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 50); - ctx.translate(100, 0); - ctx.scale(0.1, 1); - ctx.arcTo(50, 50, 50, 0, 50); - ctx.lineTo(-1000, 0); - ctx.fill(); - - skip("FIXME"); - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - } - - function test_shape() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - var tol = 1.5; // tolerance to avoid antialiasing artifacts - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 10; - ctx.beginPath(); - ctx.moveTo(10, 25); - ctx.arcTo(75, 25, 75, 60, 20); - ctx.stroke(); - - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.rect(10, 20, 45, 10); - ctx.moveTo(80, 45); - ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true); - ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 65,45, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.rect(10, 20, 45, 10); - ctx.moveTo(80, 45); - ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true); - ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false); - ctx.fill(); - - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 10; - ctx.beginPath(); - ctx.moveTo(10, 25); - ctx.arcTo(75, 25, 75, 60, 20); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255)); - ctx.reset(); - - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(-100, -100); - ctx.arcTo(-100, 25, 200, 25, 10); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(200, 25, 200, 50, 10); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - - function test_transform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 50); - ctx.translate(100, 0); - ctx.arcTo(50, 50, 50, 0, 50); - ctx.lineTo(-100, 0); - ctx.fill(); - - skip("FIXME"); - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - } - function test_zero() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, 100, 100, 0); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(0, -25); - ctx.arcTo(50, -25, 50, 50, 0); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.lineWidth = 50; - - ctx.strokeStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.arcTo(100, 25, -100, 25, 0); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(100, 25); - ctx.arcTo(200, 25, 50, 25, 0); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_canvas.qml deleted file mode 100644 index 70bedb2131..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_canvas.qml +++ /dev/null @@ -1,274 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 - -Rectangle { - id:container - width:100 - height:100 - Component { - id:canvas - Canvas { - id:c - width:100;height:100 - onPaint: { - context.fillStyle = "red"; - context.fillRect(0, 0, 100, 100); - } - property int paintCount:spyPaint.count - property int paintedCount:spyPainted.count - property int canvasSizeChangedCount:spyCanvasSizeChanged.count - property int tileSizeChangedCount:spyTileSizeChanged.count - property int renderInThreadChangedCount:spyRenderInThreadChanged.count - property int canvasWindowChangedCount:spyCanvasWindowChanged.count - property int renderTargetChangedCount:spyRenderTargetChanged.count - property int imageLoadedCount:spyImageLoaded.count - - SignalSpy {id: spyPaint;target:c;signalName: "paint"} - SignalSpy {id: spyPainted;target:c;signalName: "painted"} - SignalSpy {id: spyCanvasSizeChanged;target:c;signalName: "canvasSizeChanged"} - SignalSpy {id: spyTileSizeChanged;target:c;signalName: "tileSizeChanged"} - SignalSpy {id: spyRenderInThreadChanged;target:c;signalName: "renderInThreadChanged"} - SignalSpy {id: spyCanvasWindowChanged;target:c;signalName: "canvasWindowChanged"} - SignalSpy {id: spyRenderTargetChanged;target:c;signalName: "renderTargetChanged"} - SignalSpy {id: spyImageLoaded;target:c;signalName: "imageLoaded"} - } - } - - TestCase { - name: "Canvas"; when: windowShown - function test_canvasSize() { - var c = canvas.createObject(); - verify(c); - - //by default canvasSize is same with canvas' actual size - // when canvas size changes, canvasSize should be changed as well. - compare(c.canvasSize.width, c.width); - compare(c.canvasSize.height, c.height); - c.width = 20; - compare(c.canvasSize.width, 20); - compare(c.canvasSizeChangedCount, 1); - c.height = 5; - compare(c.canvasSizeChangedCount, 2); - compare(c.canvasSize.height, 5); - - //change canvasSize manually, then canvasSize detaches from canvas - //actual size. - c.canvasSize.width = 100; - compare(c.canvasSizeChangedCount, 3); - compare(c.canvasSize.width, 100); - compare(c.width, 20); - c.canvasSize.height = 50; - compare(c.canvasSizeChangedCount, 4); - compare(c.canvasSize.height, 50); - compare(c.height, 5); - - c.width = 10; - compare(c.canvasSizeChangedCount, 4); - compare(c.canvasSize.width, 100); - compare(c.canvasSize.height, 50); - - c.height = 10; - compare(c.canvasSizeChangedCount, 4); - compare(c.canvasSize.width, 100); - compare(c.canvasSize.height, 50); - c.destroy(); - } - function test_tileSize() { - var c = canvas.createObject(); - verify(c); - - compare(c.tileSize.width, c.width); - compare(c.tileSize.height, c.height); - c.width = 20; - compare(c.tileSize.width, 20); - compare(c.tileSizeChangedCount, 1); - c.height = 5; - compare(c.tileSizeChangedCount, 2); - compare(c.tileSize.height, 5); - - c.tileSize.width = 100; - compare(c.tileSizeChangedCount, 3); - compare(c.tileSize.width, 100); - compare(c.width, 20); - c.tileSize.height = 50; - compare(c.tileSizeChangedCount, 4); - compare(c.tileSize.height, 50); - compare(c.height, 5); - - c.width = 10; - compare(c.tileSizeChangedCount, 4); - compare(c.tileSize.width, 100); - compare(c.tileSize.height, 50); - - c.height = 10; - compare(c.tileSizeChangedCount, 4); - compare(c.tileSize.width, 100); - compare(c.tileSize.height, 50); - c.destroy(); - - } - - function test_canvasWindow() { - var c = canvas.createObject(); - verify(c); - compare(c.canvasWindow.x, 0); - compare(c.canvasWindow.y, 0); - compare(c.canvasWindow.width, c.width); - compare(c.canvasWindow.height, c.height); - - c.width = 20; - compare(c.canvasWindow.width, 20); - compare(c.canvasWindowChangedCount, 1); - c.height = 5; - compare(c.canvasWindowChangedCount, 2); - compare(c.canvasWindow.height, 5); - - c.canvasWindow.x = 5; - c.canvasWindow.y = 6; - c.canvasWindow.width = 10; - c.canvasWindow.height =20; - compare(c.canvasWindowChangedCount, 6); - compare(c.canvasWindow.width, 10); - compare(c.canvasWindow.height, 20); - compare(c.canvasWindow.x, 5); - compare(c.canvasWindow.y, 6); - c.destroy(); - - } - function test_renderTargetAndThread() { - var c = canvas.createObject(); - verify(c); - - compare(c.renderTarget, Canvas.FramebufferObject); - verify(!c.renderInThread); - c.renderTarget = Canvas.Image; - compare(c.renderTargetChangedCount, 1); - compare(c.renderInThreadChangedCount, 0); - - compare(c.renderTarget, Canvas.Image); - verify(!c.renderInThread); - c.renderInThread = true; - verify(c.renderInThread); - compare(c.renderTargetChangedCount, 1); - compare(c.renderInThreadChangedCount, 1); - - ignoreWarning("Canvas: render target does not support thread rendering, force to non-thread rendering mode."); - c.renderTarget = Canvas.FramebufferObject; - verify(!c.renderInThread); - compare(c.renderTargetChangedCount, 2); - compare(c.renderInThreadChangedCount, 2); - c.destroy(); - - } - function test_save() { - var c = canvas.createObject(); - verify(c); - - c.renderTarget = Canvas.Image; - c.requestPaint(); - wait(100); - verify(c.save("c.png")); - c.loadImage("c.png"); - wait(200); - compare(c.imageLoadedCount, 1); - verify(c.isImageLoaded("c.png")); - verify(!c.isImageLoading("c.png")); - verify(!c.isImageError("c.png")); - c.destroy(); - - } - function test_toDataURL_data() { - return [{mimeType:"image/png"}, - {mimeType:"image/bmp"}, - {mimeType:"image/jpeg"}, - {mimeType:"image/x-portable-pixmap"}, - {mimeType:"image/tiff"}, - {mimeType:"image/xpm"}, - ]; - } - - function test_toDataURL(data) { - var c = canvas.createObject(); - verify(c); - - c.renderTarget = Canvas.Image; - var ctx = c.getContext(); - ctx.fillStyle = "red"; - ctx.fillRect(0, 0, c.width, c.height); - - c.requestPaint(); - wait(100); - var dataUrl = c.toDataURL(); - verify(dataUrl != "data:,"); - dataUrl = c.toDataURL("image/invalid"); - verify(dataUrl == "data:,"); - - dataUrl = c.toDataURL(data.mimeType); - verify(dataUrl != "data:,"); - ctx.save(); - ctx.fillStyle = "blue"; - ctx.fillRect(0, 0, c.width, c.height); - ctx.restore(); - c.requestPaint(); - wait(100); - var dataUrl2 = c.toDataURL(data.mimeType); - verify (dataUrl2 != "data:,"); - verify (dataUrl2 != dataUrl); - c.destroy(); - - } - function test_paint() { - var c = canvas.createObject(); - verify(c); - - c.renderTarget = Canvas.Image; - c.renderInThread = true; - var ctx = c.getContext(); - ctx.fillRect(0, 0, c.width, c.height); - c.toDataURL(); - wait(100); - - compare(c.paintedCount, 1); - compare(c.paintCount, 1); - c.destroy(); - - } - function test_loadImage() { - var c = canvas.createObject(); - verify(c); - - c.loadImage("red.png"); - wait(200); - compare(c.imageLoadedCount, 1); - verify(c.isImageLoaded("red.png")); - verify(!c.isImageLoading("red.png")); - verify(!c.isImageError("red.png")); - - c.unloadImage("red.png"); - verify(!c.isImageLoaded("red.png")); - verify(!c.isImageLoading("red.png")); - verify(!c.isImageError("red.png")); - c.destroy(); - - } - - function test_getContext() { - var c = canvas.createObject(); - verify(c); - - var ctx = c.getContext(); - verify(ctx); - compare(ctx.canvas, c); - ctx = c.getContext('2d'); - verify(ctx); - compare(ctx.canvas, c); - ctx = c.getContext('2D'); - verify(ctx); - compare(ctx.canvas, c); - ctx = c.getContext('invalid'); - verify(!ctx); - c.destroy(); - - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_composite.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_composite.qml deleted file mode 100644 index 11e1dce902..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_composite.qml +++ /dev/null @@ -1,380 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget:Canvas.Image - TestCase { - name: "composite"; when: windowShown - function test_clearRect() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-atop'; - ctx.clearRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0)); - } - - function test_clip_data() { - return [ {compsite:"copy"}, - {compsite:"destination-atop"}, - {compsite:"destination-in"}, - {compsite:"destination-out"}, - {compsite:"destination-over"}, - {compsite:"lighter"}, - {compsite:"source-atop"}, - {compsite:"source-in"}, - {compsite:"source-out"}, - {compsite:"source-over"}, - {compsite:"xor"} - ]; - } - - function test_clip(data) { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = data.compsite; - ctx.rect(-20, -20, 10, 10); - ctx.clip(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 50, 50); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - } - - function test_globalAlpha() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - compare(ctx.globalAlpha, 1.0); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 2,253,0,255, 2)); - - ctx.reset(); - ctx.globalAlpha = 0.5; - var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons - ctx.globalAlpha = Infinity; - compare(ctx.globalAlpha, a); - ctx.globalAlpha = -Infinity; - compare(ctx.globalAlpha, a); - ctx.globalAlpha = NaN; - compare(ctx.globalAlpha, a); - - ctx.globalAlpha = 0.5; - a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons - ctx.globalAlpha = 1.1; - compare(ctx.globalAlpha, a); - ctx.globalAlpha = -0.1; - compare(ctx.globalAlpha, a); - ctx.globalAlpha = 0; - compare(ctx.globalAlpha, 0); - ctx.globalAlpha = 1; - compare(ctx.globalAlpha, 1); - - } - - function test_operation() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'Source-over'; - compare(ctx.globalCompositeOperation, 'xor'); - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'clear'; - compare(ctx.globalCompositeOperation, 'xor'); - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'darker'; - compare(ctx.globalCompositeOperation, 'xor'); - - ctx.reset(); - compare(ctx.globalCompositeOperation, 'source-over'); - - - ctx.reset(); - var modes = ['source-atop', 'source-in', 'source-out', 'source-over', - 'destination-atop', 'destination-in', 'destination-out', 'destination-over', - 'lighter', 'copy', 'xor']; - for (var i = 0; i < modes.length; ++i) - { - ctx.globalCompositeOperation = modes[i]; - compare(ctx.globalCompositeOperation, modes[i]); - } - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'highlight'; - compare(ctx.globalCompositeOperation, 'xor'); - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'source-over\\0'; - compare(ctx.globalCompositeOperation, 'xor'); - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'over'; - compare(ctx.globalCompositeOperation, 'xor'); - - - ctx.reset(); - ctx.globalCompositeOperation = 'xor'; - ctx.globalCompositeOperation = 'nonexistent'; - compare(ctx.globalCompositeOperation, 'xor'); - } - - function test_solid() { - skip("FIXME"); - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0); - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'copy'; - ctx.fillStyle = Qt.rgba(1, 1, 0, 1.0); - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-atop'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-in'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-out'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-over'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'lighter'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 255,255,255,255, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-atop'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-in'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-out'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - // verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-over'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'xor'; - ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - } - function test_transparent() { - - skip("FIXME"); - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'copy'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'copy'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-in'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,95, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-out'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,31, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-over'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,145,109,223, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'lighter'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,127,191,255, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-atop'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-in'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-out'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5)); - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-over'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,36,218,223, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'xor'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5)); - - } - - function test_uncovered() { - skip("FIXME"); - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'copy'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.translate(0, 25); - ctx.fillRect(0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-atop'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.translate(0, 25); - ctx.fillRect(0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-in'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.translate(0, 25); - ctx.fillRect(0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-in'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.translate(0, 25); - ctx.fillRect(0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - ctx.reset(); - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'source-out'; - ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; - ctx.translate(0, 25); - ctx.fillRect(0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); - - } - - } -} \ No newline at end of file diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_drawimage.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_drawimage.qml deleted file mode 100644 index 3752f528be..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_drawimage.qml +++ /dev/null @@ -1,662 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - Component.onCompleted: { - canvas.loadImage('green.png'); - canvas.loadImage('red.png'); - canvas.loadImage('rgrg-256x256.png'); - canvas.loadImage('ggrr-256x256.png'); - canvas.loadImage('broken.png'); - } - - TestCase { - //TODO - name: "image"; when: windowShown - function test_3args() { - //make sure all images are loaded - wait(200); - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.drawImage('green.png', 0, 0); - ctx.drawImage('red.png', -100, 0); - ctx.drawImage('red.png', 100, 0); - ctx.drawImage('red.png', 0, -50); - ctx.drawImage('red.png', 0, 50); - - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - } - function test_5args() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('green.png', 50, 0, 50, 50); - ctx.drawImage('red.png', 0, 0, 50, 50); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 50, 50); - - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - } - function test_9args() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, -100, 0, 100, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 100, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, 0, -50, 100, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 50); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('green.png', 1, 1, 1, 1, 0, 0, 100, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, -50, 0, 50, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 50, 50); - ctx.drawImage('red.png', 0, 0, 100, 50, 0, -25, 100, 25); - ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 25); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('rgrg-256x256.png', 140, 20, 100, 50, 0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('rgrg-256x256.png', 0, 0, 256, 256, 0, 0, 100, 50); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 51, 26); - ctx.fillRect(49, 24, 51, 26); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 20,20, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 80,20, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 20,30, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 80,30, 0,255,0,255,2)); - - } - function test_animated() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - //should animated image be supported at all? - } - function test_clip() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.rect(-10, -10, 1, 1); - ctx.clip(); - ctx.drawImage('red.png', 0, 0); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - - } - function test_self() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 50, 50); - ctx.fillStyle = '#f00'; - ctx.fillRect(50, 0, 50, 50); - ctx.drawImage(canvas, 50, 0); - - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 1, 100, 49); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 1); - ctx.drawImage(canvas, 0, 1); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 2); - - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - - } - - function test_outsidesource() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.drawImage('green.png', 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50); - ctx.drawImage('green.png', 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50); - ctx.drawImage('green.png', 100, 50, -5, -5, 0, 0, 100, 50); - try { var err = false; - ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50)"); } - try { var err = false; - ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50)"); } -// try { var err = false; -// ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50); -// } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50)"); } -// verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - } - - function test_null() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - try { var err = false; - ctx.drawImage(null, 0, 0); - } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(null, 0, 0)"); } - - } - - function test_composite() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalCompositeOperation = 'destination-over'; - ctx.drawImage('red.png', 0, 0); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - } - function test_path() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_transform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.translate(100, 0); - ctx.drawImage('red.png', 0, 0); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - } - - function test_imageitem() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - //TODO - } - - function test_imageData() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - //TODO - } - - function test_wrongtype() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - try { var err = false; - ctx.drawImage(undefined, 0, 0); - } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(undefined, 0, 0)"); } - try { var err = false; - ctx.drawImage(0, 0, 0); - } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(0, 0, 0)"); } - try { var err = false; - ctx.drawImage("", 0, 0); - } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(\"\", 0, 0)"); } - } - - function test_nonfinite() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - var red = 'red.png'; - ctx.drawImage(red, Infinity, 0); - ctx.drawImage(red, -Infinity, 0); - ctx.drawImage(red, NaN, 0); - ctx.drawImage(red, 0, Infinity); - ctx.drawImage(red, 0, -Infinity); - ctx.drawImage(red, 0, NaN); - ctx.drawImage(red, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50); - ctx.drawImage(red, -Infinity, 0, 100, 50); - ctx.drawImage(red, NaN, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, -Infinity, 100, 50); - ctx.drawImage(red, 0, NaN, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, -Infinity, 50); - ctx.drawImage(red, 0, 0, NaN, 50); - ctx.drawImage(red, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, -Infinity); - ctx.drawImage(red, 0, 0, 100, NaN); - ctx.drawImage(red, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, -Infinity, 0, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, NaN, 0, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, -Infinity, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, NaN, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, -Infinity, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, NaN, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, -Infinity, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, NaN, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, -Infinity, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, NaN, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, -Infinity, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, NaN, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, -Infinity, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, NaN, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, -Infinity); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, NaN); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, 50); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, 50); - ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, Infinity); - ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, Infinity); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - - function test_negative() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('ggrr-256x256.png', 100, 78, 50, 50, 0, 50, 50, -50); - ctx.drawImage('ggrr-256x256.png', 100, 128, 50, -50, 100, 50, -50, -50); -// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('ggrr-256x256.png', 0, 178, 50, -100, 0, 0, 50, 100); - ctx.drawImage('ggrr-256x256.png', 0, 78, 50, 100, 50, 100, 50, -100); -// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.drawImage('ggrr-256x256.png', 100, 78, -100, 50, 0, 0, 50, 50); - ctx.drawImage('ggrr-256x256.png', 100, 128, -100, -50, 50, 0, 50, 50); -// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); -// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); - - } - - function test_canvas() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas); - canvas2.width = 100; - canvas2.height = 50; - var ctx2 = canvas2.getContext('2d'); - ctx2.fillStyle = '#0f0'; - ctx2.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.drawImage(canvas2, 0, 0); - - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); - - } - - function test_broken() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - var img = 'broken.png'; - verify(!img.complete); - ctx.drawImage(img, 0, 0); - } - - function test_alpha() { - var ctx=canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.globalAlpha = 0; - ctx.drawImage('red.png', 0, 0); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255, 2)); - - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_fillStyle.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_fillStyle.qml deleted file mode 100644 index 8f5a78cec0..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_fillStyle.qml +++ /dev/null @@ -1,113 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper - -Canvas { - id:canvas; width:1;height:1;renderTarget:Canvas.Image - TestCase { - name: "fillStyle"; when: windowShown - function test_default() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - verify(ctx.fillStyle, "#000000"); - ctx.clearRect(0, 0, 1, 1); - compare(ctx.fillStyle, "#000000"); - } - function test_get() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#fa0'; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = Qt.rgba(0,0,0,0); - compare(ctx.fillStyle, 'rgba(0, 0, 0, 0.0)'); - } - function test_hex() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - compare(ctx.fillStyle, '#ff0000'); - ctx.fillStyle = "#0f0"; - compare(ctx.fillStyle, '#00ff00'); - ctx.fillStyle = "#0fF"; - compare(ctx.fillStyle, '#00ffff'); - ctx.fillStyle = "#0aCCfb"; - compare(ctx.fillStyle, '#0accfb'); - - } - function test_invalid() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#fa0'; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "invalid"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "rgb (1, 2, 3)"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = '#fa0'; - - ctx.fillStyle = "rgba(3, 1, 2)"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "rgb((3,4,1)"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "rgb(1, 3, 4, 0.5)"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "hsl(2, 3, 4, 0.8)"; - compare(ctx.fillStyle, '#ffaa00'); - ctx.fillStyle = "hsl(2, 3, 4"; - compare(ctx.fillStyle, '#ffaa00'); - } - function test_saverestore() { - var ctx = canvas.getContext('2d'); - var old = ctx.fillStyle; - ctx.save(); - ctx.fillStyle = "#ffaaff"; - ctx.restore(); - compare(ctx.fillStyle, old); - - ctx.fillStyle = "#ffcc88"; - old = ctx.fillStyle; - ctx.save(); - compare(ctx.fillStyle, old); - ctx.restore(); - } - function test_namedColor() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = "red"; - ctx.fillRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,255,0,0,255)); - - ctx.fillStyle = "black"; - ctx.fillRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,0,0,0,255)); - - ctx.fillStyle = "white"; - ctx.fillRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,255,255,255,255)); - } - function test_rgba() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = "rgb(-100, 300, 255)"; - compare(ctx.fillStyle, "#00ffff"); - ctx.fillStyle = "rgba(-100, 300, 255, 0.0)"; - compare(ctx.fillStyle, "rgba(0, 255, 255, 0.0)"); - ctx.fillStyle = "rgb(-10%, 110%, 50%)"; - compare(ctx.fillStyle, "#00ff80"); - - ctx.clearRect(0, 0, 1, 1); - ctx.fillStyle = 'rgba(0%, 100%, 0%, 0.499)'; - ctx.fillRect(0, 0, 1, 1); - verify(Helper.comparePixel(ctx, 0,0, 0,255,0,127)); - } - - function test_hsla() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)"; - ctx.fillRect(0, 0, 1, 1); - verify(Helper.comparePixel(ctx,0,0,0,255,0,127)); - } - - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_fillrect.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_fillrect.qml deleted file mode 100644 index 2061647268..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_fillrect.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 - -Canvas { - id:canvas; width:1;height:1; renderTarget:Canvas.Image - onPaint: { - context.fillStyle = "red"; - context.fillRect(0, 0, canvas.width, canvas.height); - } - TestCase { - name: "FillRect"; when: windowShown - function test_fillRect() { - var ctx = canvas.getContext('2d'); - var imageData = ctx.getImageData(0, 0, 1, 1); - var d = imageData.data; - verify(d.length == 4); - verify(d[0] == 255); - verify(d[1] == 0); - verify(d[2] == 0); - verify(d[3] == 255); - } - } -} \ No newline at end of file diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_gradient.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_gradient.qml deleted file mode 100644 index d454c2efe1..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_gradient.qml +++ /dev/null @@ -1,981 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - name: "gradient"; when: windowShown - function test_basic() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - var g = ctx.createLinearGradient(0, 0, 0, 50); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - } - - function test_interpolate() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#ff0'; - ctx.fillRect(0, 0, 100, 50); - var g = ctx.createLinearGradient(0, 0, 100, 0); - g.addColorStop(0, 'rgba(0,0,255, 0)'); - g.addColorStop(1, 'rgba(0,0,255, 1)'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3)); - //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3)); - //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3)); - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 100, 0); - g.addColorStop(0, '#ff0'); - g.addColorStop(1, '#00f'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3)); - //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3)); - //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3)); - - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 100, 0); - g.addColorStop(0, 'rgba(255,255,0, 0)'); - g.addColorStop(1, 'rgba(0,0,255, 1)'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,63,3)); - //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,127,3)); - //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,191,3)); - - ctx.reset(); - canvas.width = 200; - var g = ctx.createLinearGradient(0, 0, 200, 0); - g.addColorStop(0, '#ff0'); - g.addColorStop(0.5, '#0ff'); - g.addColorStop(1, '#f0f'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 200, 50); - //verify(Helper.comparePixel(ctx, 50,25, 127,255,127,255,3)); - //verify(Helper.comparePixel(ctx, 100,25, 0,255,255,255,3)); - //verify(Helper.comparePixel(ctx, 150,25, 127,127,255,255,3)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - var g = ctx.createLinearGradient(25, 0, 75, 0); - g.addColorStop(0.4, '#0f0'); - g.addColorStop(0.6, '#0f0'); - - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 20,25, 0,255,0,255,2)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255,2)); - - - ctx.reset(); - ctx.canvas.width = 200; - var g = ctx.createLinearGradient(0, 0, 200, 0); - g.addColorStop(0, '#f00'); - g.addColorStop(0, '#ff0'); - g.addColorStop(0.25, '#00f'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.25, '#ff0'); - g.addColorStop(0.5, '#00f'); - g.addColorStop(0.5, '#0f0'); - g.addColorStop(0.75, '#00f'); - g.addColorStop(0.75, '#f00'); - g.addColorStop(0.75, '#ff0'); - g.addColorStop(0.5, '#0f0'); - g.addColorStop(0.5, '#0f0'); - g.addColorStop(0.5, '#ff0'); - g.addColorStop(1, '#00f'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 200, 50); - //verify(Helper.comparePixel(ctx, 49,25, 0,0,255,255,16)); - //verify(Helper.comparePixel(ctx, 51,25, 255,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 99,25, 0,0,255,255,16)); - //verify(Helper.comparePixel(ctx, 101,25, 255,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 149,25, 0,0,255,255,16)); - //verify(Helper.comparePixel(ctx, 151,25, 255,255,0,255,16)); - ctx.canvas.width = 100; - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 100, 0); - var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ]; - for (var p = 0; p < ps.length; ++p) - { - g.addColorStop(ps[p], '#0f0'); - for (var i = 0; i < 15; ++i) - g.addColorStop(ps[p], '#f00'); - g.addColorStop(ps[p], '#0f0'); - } - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 30,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 40,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 60,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255)); - - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 100, 0); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 0, 50); - g.addColorStop(0, '#ff0'); - g.addColorStop(1, '#00f'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,12, 191,191,63,255,10)); - //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,5)); - //verify(Helper.comparePixel(ctx, 50,37, 63,63,191,255,10)); - - - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 40,20, 0,255,0,255,2)); - - - - } - function test_radial() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - var tol = 1; // tolerance to avoid antialiasing artifacts - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(30+tol, 40); - ctx.lineTo(110, -20+tol); - ctx.lineTo(110, 100-tol); - ctx.fill(); - - g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - var tol = 1; // tolerance to avoid antialiasing artifacts - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.moveTo(30-tol, 40); - ctx.lineTo(110, -20-tol); - ctx.lineTo(110, 100+tol); - ctx.fill(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); - g.addColorStop(0, '#f00'); - g.addColorStop(0.993, '#f00'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - try { var err = false; - ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1)"); } - - - ctx.reset(); - - - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, NaN, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, NaN, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, NaN, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, NaN, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, NaN, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, NaN, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, NaN, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, 0, NaN); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, NaN)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity)"); } - try { var err = false; - ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity)"); } - - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#0f0'); - ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); - g.addColorStop(0, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); - g.addColorStop(0, '#0f0'); - g.addColorStop(0.001, '#f00'); - g.addColorStop(1, '#f00');ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150); - g.addColorStop(0, '#f00'); - g.addColorStop(0.01, '#0f0'); - g.addColorStop(0.99, '#0f0');g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); - g.addColorStop(0, '#0f0'); - g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.translate(50, 25);ctx.scale(10, 10); - ctx.fillRect(-5, -2.5, 10, 5); - //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - ctx.reset(); - ctx.translate(100, 0); - g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); - g.addColorStop(0, '#0f0');g.addColorStop(0.5, '#0f0'); - g.addColorStop(0.51, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g;ctx.translate(-50, 25); - ctx.scale(10, 10); - ctx.fillRect(-5, -2.5, 10, 5); - //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - - ctx.reset(); - g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); - g.addColorStop(0, '#0f0'); - g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50);ctx.translate(50, 25); - ctx.scale(10, 10); - ctx.fillRect(-5, -2.5, 10, 5); - //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - - } - function test_linear() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - try { var err = false; - ctx.createLinearGradient(Infinity, 0, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(-Infinity, 0, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(-Infinity, 0, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(NaN, 0, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(NaN, 0, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, Infinity, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, -Infinity, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, -Infinity, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, NaN, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, NaN, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, Infinity, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, -Infinity, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, -Infinity, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, NaN, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, NaN, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, 1, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, 1, -Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, -Infinity)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, 1, NaN); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, NaN)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, Infinity, 1, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, 0)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, Infinity, Infinity, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, 0)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, Infinity, 1, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, 0, Infinity, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, 0)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(Infinity, 0, 1, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(0, Infinity, Infinity, 0); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, 0)"); } - try { var err = false; - ctx.createLinearGradient(0, Infinity, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(0, Infinity, 1, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, Infinity)"); } - try { var err = false; - ctx.createLinearGradient(0, 0, Infinity, Infinity); - } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, Infinity)"); } - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 200, 0); - g.addColorStop(0, '#f00'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.75, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.translate(-50, 0); - ctx.fillRect(50, 0, 100, 50); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - ctx.reset(); - ctx.translate(100, 0); - g = ctx.createLinearGradient(0, 0, 200, 0); - g.addColorStop(0, '#f00'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.75, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.translate(-150, 0); - ctx.fillRect(50, 0, 100, 50); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - - ctx.reset(); - g = ctx.createLinearGradient(0, 0, 200, 0); - g.addColorStop(0, '#f00'); - g.addColorStop(0.25, '#0f0'); - g.addColorStop(0.75, '#0f0'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - ctx.translate(-50, 0); - ctx.fillRect(50, 0, 100, 50); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - - } - function test_object() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - var g1 = ctx.createLinearGradient(0, 0, 100, 0); - var g2 = ctx.createLinearGradient(0, 0, 100, 0); - ctx.fillStyle = g1; - - - ctx.reset(); - var g = ctx.createLinearGradient(0, 0, 100, 0); - try { var err = false; - g.addColorStop(0, ""); - } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, \"\")"); } - try { var err = false; - g.addColorStop(0, 'undefined'); - } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, 'undefined')"); } - - - ctx.reset(); - g = ctx.createLinearGradient(0, 0, 100, 0); - try { var err = false; - g.addColorStop(-1, '#000'); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-1, '#000')"); } - try { var err = false; - g.addColorStop(2, '#000'); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(2, '#000')"); } - try { var err = false; - g.addColorStop(Infinity, '#000'); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(Infinity, '#000')"); } - try { var err = false; - g.addColorStop(-Infinity, '#000'); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-Infinity, '#000')"); } - try { var err = false; - g.addColorStop(NaN, '#000'); - } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(NaN, '#000')"); } - - - ctx.reset(); - g = ctx.createLinearGradient(-100, 0, 200, 0); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - g.addColorStop(0.1, '#0f0'); - g.addColorStop(0.9, '#0f0'); - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100); - g.addColorStop(0, '#f00'); - g.addColorStop(1, '#f00'); - ctx.fillStyle = g; - ctx.fillRect(0, 0, 100, 50); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - - } - - function test_conical() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - var g = ctx.createConicalGradient(10, 10, 50); - //TODO - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_line.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_line.qml deleted file mode 100644 index baf9987ce3..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_line.qml +++ /dev/null @@ -1,831 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import"testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50;renderTarget: Canvas.Image - TestCase { - name: "line"; when: windowShown - function test_default() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - compare(ctx.lineWidth, 1); - compare(ctx.lineCap, 'butt'); - compare(ctx.lineJoin, 'miter'); - compare(ctx.miterLimit, 10); - } - - function test_cross() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 200; - ctx.lineJoin = 'bevel'; - - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(110, 50); - ctx.lineTo(110, 60); - ctx.lineTo(100, 60); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - } - - function test_join() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - var tol = 1; // tolerance to avoid antialiasing artifacts - - ctx.lineJoin = 'bevel'; - ctx.lineWidth = 20; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - - ctx.fillRect(10, 10, 20, 20); - ctx.fillRect(20, 20, 20, 20); - ctx.beginPath(); - ctx.moveTo(30, 20); - ctx.lineTo(40-tol, 20); - ctx.lineTo(30, 10+tol); - ctx.fill(); - - ctx.beginPath(); - ctx.moveTo(10, 20); - ctx.lineTo(30, 20); - ctx.lineTo(30, 40); - ctx.stroke(); - - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - - ctx.beginPath(); - ctx.moveTo(60, 20); - ctx.lineTo(80, 20); - ctx.lineTo(80, 40); - ctx.stroke(); - - ctx.fillRect(60, 10, 20, 20); - ctx.fillRect(70, 20, 20, 20); - ctx.beginPath(); - ctx.moveTo(80, 20); - ctx.lineTo(90+tol, 20); - ctx.lineTo(80, 10-tol); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 34,16, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 34,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 35,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 36,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 84,16, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 84,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 85,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 86,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255)); - - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineJoin = 'miter'; - ctx.lineWidth = 200; - - ctx.beginPath(); - ctx.moveTo(100, 50); - ctx.lineTo(100, 1000); - ctx.lineTo(1000, 1000); - ctx.lineTo(1000, 50); - ctx.closePath(); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - - ctx.reset(); - ctx.lineJoin = 'bevel' - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = 'invalid'; - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = 'ROUND'; - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = 'round\\0'; - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = 'round '; - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = ""; - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'bevel'; - ctx.lineJoin = 'butt'; - compare(ctx.lineJoin, 'bevel'); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineJoin = 'miter'; - ctx.lineWidth = 20; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - - ctx.fillRect(10, 10, 30, 20); - ctx.fillRect(20, 10, 20, 30); - - ctx.beginPath(); - ctx.moveTo(10, 20); - ctx.lineTo(30, 20); - ctx.lineTo(30, 40); - ctx.stroke(); - - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - - ctx.beginPath(); - ctx.moveTo(60, 20); - ctx.lineTo(80, 20); - ctx.lineTo(80, 40); - ctx.stroke(); - - ctx.fillRect(60, 10, 30, 20); - ctx.fillRect(70, 10, 20, 30); - - verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 39,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 40,10, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 41,9, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 42,8, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 89,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 91,9, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 92,8, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineJoin = 'miter'; - ctx.lineWidth = 200; - - ctx.beginPath(); - ctx.moveTo(100, 50); - ctx.lineTo(100, 1000); - ctx.lineTo(1000, 1000); - ctx.lineTo(1000, 50); - ctx.lineTo(100, 50); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 300; - ctx.lineJoin = 'round'; - ctx.beginPath(); - ctx.moveTo(-100, 25); - ctx.lineTo(0, 25); - ctx.lineTo(-100, 25); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - var tol = 1; // tolerance to avoid antialiasing artifacts - - ctx.lineJoin = 'round'; - ctx.lineWidth = 20; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - - ctx.fillRect(10, 10, 20, 20); - ctx.fillRect(20, 20, 20, 20); - ctx.beginPath(); - ctx.moveTo(30, 20); - ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true); - ctx.fill(); - - ctx.beginPath(); - ctx.moveTo(10, 20); - ctx.lineTo(30, 20); - ctx.lineTo(30, 40); - ctx.stroke(); - - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - - ctx.beginPath(); - ctx.moveTo(60, 20); - ctx.lineTo(80, 20); - ctx.lineTo(80, 40); - ctx.stroke(); - - ctx.fillRect(60, 10, 20, 20); - ctx.fillRect(70, 20, 20, 20); - ctx.beginPath(); - ctx.moveTo(80, 20); - ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 36,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 37,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 38,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 86,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 87,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 88,13, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255)); - - ctx.reset(); - ctx.lineJoin = 'bevel' - compare(ctx.lineJoin, 'bevel'); - - ctx.lineJoin = 'round'; - compare(ctx.lineJoin, 'round'); - - ctx.lineJoin = 'miter'; - compare(ctx.lineJoin, 'miter'); - - } - function test_miter() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 200; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#0f0'; - ctx.miterLimit = 2.614; - ctx.beginPath(); - ctx.moveTo(100, 1000); - ctx.lineTo(100, 100); - ctx.lineTo(1000, 1000); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.miterLimit = 2.613; - ctx.beginPath(); - ctx.moveTo(100, 1000); - ctx.lineTo(100, 100); - ctx.lineTo(1000, 1000); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 400; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#f00'; - ctx.miterLimit = 1.414; - ctx.beginPath(); - ctx.moveTo(200, 1000); - ctx.lineTo(200, 200); - ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.miterLimit = 1.5; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = 1.5; - ctx.miterLimit = 0; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = 1.5; - ctx.miterLimit = -1; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = 1.5; - ctx.miterLimit = Infinity; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = 1.5; - ctx.miterLimit = -Infinity; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = 1.5; - ctx.miterLimit = NaN; - compare(ctx.miterLimit, 1.5); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 200; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#f00'; - ctx.miterLimit = 1.414; - ctx.beginPath(); - ctx.strokeRect(100, 25, 200, 0); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 1600; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#0f0'; - ctx.miterLimit = 1.083; - ctx.beginPath(); - ctx.moveTo(800, 10000); - ctx.lineTo(800, 300); - ctx.lineTo(10000, -8900); - ctx.stroke(); - - ctx.strokeStyle = '#f00'; - ctx.miterLimit = 1.082; - ctx.beginPath(); - ctx.moveTo(800, 10000); - ctx.lineTo(800, 300); - ctx.lineTo(10000, -8900); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 400; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#f00'; - ctx.miterLimit = 1.414; - ctx.beginPath(); - ctx.moveTo(200, 1000); - ctx.lineTo(200, 200); - ctx.lineTo(1000, 200); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - ctx.reset(); - ctx.miterLimit = 1.5; - compare(ctx.miterLimit, 1.5); - - ctx.miterLimit = "1e1"; - compare(ctx.miterLimit, 10); - - ctx.miterLimit = 1/1024; - compare(ctx.miterLimit, 1/1024); - - ctx.miterLimit = 1000; - compare(ctx.miterLimit, 1000); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 400; - ctx.lineJoin = 'miter'; - - ctx.strokeStyle = '#0f0'; - ctx.miterLimit = 1.416; - ctx.beginPath(); - ctx.moveTo(200, 1000); - ctx.lineTo(200, 200); - ctx.lineTo(1000, 201); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - - - } - function test_width() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 20; - // Draw a green line over a red box, to check the line is not too small - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(15, 15, 20, 20); - ctx.beginPath(); - ctx.moveTo(25, 15); - ctx.lineTo(25, 35); - ctx.stroke(); - - // Draw a green box over a red line, to check the line is not too large - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(75, 15); - ctx.lineTo(75, 35); - ctx.stroke(); - ctx.fillRect(65, 15, 20, 20); - - verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255)); - - ctx.reset(); - ctx.lineWidth = 1.5; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = 1.5; - ctx.lineWidth = 0; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = 1.5; - ctx.lineWidth = -1; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = 1.5; - ctx.lineWidth = Infinity; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = 1.5; - ctx.lineWidth = -Infinity; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = 1.5; - ctx.lineWidth = NaN; - compare(ctx.lineWidth, 1.5); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.scale(50, 50); - ctx.strokeStyle = '#0f0'; - ctx.moveTo(0, 0.5); - ctx.lineTo(2, 0.5); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,5, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,45, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 4; - // Draw a green line over a red box, to check the line is not too small - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(15, 15, 20, 20); - ctx.save(); - ctx.scale(5, 1); - ctx.beginPath(); - ctx.moveTo(5, 15); - ctx.lineTo(5, 35); - ctx.stroke(); - ctx.restore(); - - // Draw a green box over a red line, to check the line is not too large - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.save(); - ctx.scale(-5, 1); - ctx.beginPath(); - ctx.moveTo(-15, 15); - ctx.lineTo(-15, 35); - ctx.stroke(); - ctx.restore(); - ctx.fillRect(65, 15, 20, 20); - - verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255)); - - //verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255)); - - ctx.reset(); - ctx.lineWidth = 1.5; - compare(ctx.lineWidth, 1.5); - - ctx.lineWidth = "1e1"; - compare(ctx.lineWidth, 10); - - ctx.lineWidth = 1/1024; - compare(ctx.lineWidth, 1/1024); - - ctx.lineWidth = 1000; - compare(ctx.lineWidth, 1000); - - } - function test_cap() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineCap = 'butt'; - ctx.lineWidth = 20; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(15, 15, 20, 20); - ctx.beginPath(); - ctx.moveTo(25, 15); - ctx.lineTo(25, 35); - ctx.stroke(); - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(75, 15); - ctx.lineTo(75, 35); - ctx.stroke(); - ctx.fillRect(65, 15, 20, 20); - - verify(Helper.comparePixel(ctx, 25,14, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,16, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,34, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,35, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,36, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 75,14, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,15, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,16, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,34, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,36, 0,255,0,255)); - - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineJoin = 'bevel'; - ctx.lineCap = 'square'; - ctx.lineWidth = 400; - - ctx.beginPath(); - ctx.moveTo(200, 200); - ctx.lineTo(200, 1000); - ctx.lineTo(1000, 1000); - ctx.lineTo(1000, 200); - ctx.closePath(); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - ctx.reset(); - - ctx.lineCap = 'butt' - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = 'invalid'; - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = 'ROUND'; - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = 'round\\0'; - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = 'round '; - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = ""; - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'butt'; - ctx.lineCap = 'bevel'; - compare(ctx.lineCap, 'butt'); - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineJoin = 'bevel'; - ctx.lineCap = 'square'; - ctx.lineWidth = 400; - - ctx.beginPath(); - ctx.moveTo(200, 200); - ctx.lineTo(200, 1000); - ctx.lineTo(1000, 1000); - ctx.lineTo(1000, 200); - ctx.lineTo(200, 200); - ctx.stroke(); - - //FIXME:!!! - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - var tol = 1; // tolerance to avoid antialiasing artifacts - - ctx.lineCap = 'round'; - ctx.lineWidth = 20; - - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - - ctx.beginPath(); - ctx.moveTo(35-tol, 15); - ctx.arc(25, 15, 10-tol, 0, Math.PI, true); - ctx.arc(25, 35, 10-tol, Math.PI, 0, true); - ctx.fill(); - - ctx.beginPath(); - ctx.moveTo(25, 15); - ctx.lineTo(25, 35); - ctx.stroke(); - - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - - ctx.beginPath(); - ctx.moveTo(75, 15); - ctx.lineTo(75, 35); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(85+tol, 15); - ctx.arc(75, 15, 10+tol, 0, Math.PI, true); - ctx.arc(75, 35, 10+tol, Math.PI, 0, true); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 17,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 32,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 17,43, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,43, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 32,43, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 67,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 82,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 67,43, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,43, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 82,43, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineCap = 'square'; - ctx.lineWidth = 20; - - ctx.fillStyle = '#f00'; - ctx.strokeStyle = '#0f0'; - ctx.fillRect(15, 5, 20, 40); - ctx.beginPath(); - ctx.moveTo(25, 15); - ctx.lineTo(25, 35); - ctx.stroke(); - - ctx.fillStyle = '#0f0'; - ctx.strokeStyle = '#f00'; - ctx.beginPath(); - ctx.moveTo(75, 15); - ctx.lineTo(75, 35); - ctx.stroke(); - ctx.fillRect(65, 5, 20, 40); - - verify(Helper.comparePixel(ctx, 25,4, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,5, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,44, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,45, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,46, 0,255,0,255)); - - verify(Helper.comparePixel(ctx, 75,4, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,5, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,44, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,45, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,46, 0,255,0,255)); - - ctx.reset(); - ctx.lineCap = 'butt' - compare(ctx.lineCap, 'butt'); - - ctx.lineCap = 'round'; - compare(ctx.lineCap, 'round'); - - ctx.lineCap = 'square'; - compare(ctx.lineCap, 'square'); - - } - } -} \ No newline at end of file diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_path.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_path.qml deleted file mode 100644 index b04ccf5458..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_path.qml +++ /dev/null @@ -1,1443 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper - -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - name: "path"; when: windowShown - - function test_basic() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.closePath(); - ctx.fillStyle = '#f00'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.save(); - ctx.rect(0, 0, 100, 50); - ctx.restore(); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - canvas.width = 100; - ctx.rect(0, 0, 100, 50); - canvas.width = 100; - ctx.fillStyle = '#f00'; - ctx.fill(); - //verify(Helper.comparePixel(ctx, 20,20, 0,0,0,0)); - } - function test_beginPath() { - var ctx = canvas.getContext('2d'); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.rect(0, 0, 100, 50); - ctx.beginPath(); - ctx.fillStyle = '#f00'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_closePath() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.closePath(); - ctx.fillStyle = '#f00'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.moveTo(-100, 25); - ctx.lineTo(-100, -100); - ctx.lineTo(200, -100); - ctx.lineTo(200, 25); - ctx.closePath(); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.moveTo(-100, 25); - ctx.lineTo(-100, -1000); - ctx.closePath(); - ctx.lineTo(1000, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_isPointInPath() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.arc(50, 25, 10, 0, Math.PI, false); - verify(!ctx.isPointInPath(50, 10)); - verify(!ctx.isPointInPath(50, 20)); - //verify(!ctx.isPointInPath(50, 30)); - verify(!ctx.isPointInPath(50, 40)); - verify(!ctx.isPointInPath(30, 20)); - verify(!ctx.isPointInPath(70, 20)); - verify(!ctx.isPointInPath(30, 30)); - verify(!ctx.isPointInPath(70, 30)); - - ctx.reset(); - ctx.rect(0, 0, 20, 20); - verify(ctx.isPointInPath(10, 10)); - verify(!ctx.isPointInPath(30, 10)); - - ctx.reset(); - ctx.rect(20, 0, 20, 20); - //verify(ctx.isPointInPath(10, 10)); - verify(ctx.isPointInPath(30, 10)); - - ctx.reset(); - ctx.bezierCurveTo(50, -50, 50, 100, 75, 25); - verify(!ctx.isPointInPath(25, 20)); - verify(!ctx.isPointInPath(25, 30)); - //verify(ctx.isPointInPath(30, 20)); - verify(!ctx.isPointInPath(30, 30)); - //verify(!ctx.isPointInPath(40, 2)); - //verify(ctx.isPointInPath(40, 20)); - verify(!ctx.isPointInPath(40, 30)); - verify(!ctx.isPointInPath(40, 47)); - //verify(ctx.isPointInPath(45, 20)); - //verify(!ctx.isPointInPath(45, 30)); - //verify(!ctx.isPointInPath(55, 20)); - //verify(ctx.isPointInPath(55, 30)); - verify(!ctx.isPointInPath(60, 2)); - //verify(!ctx.isPointInPath(60, 20)); - verify(ctx.isPointInPath(60, 30)); - verify(!ctx.isPointInPath(60, 47)); - verify(!ctx.isPointInPath(70, 20)); - verify(ctx.isPointInPath(70, 30)); - verify(!ctx.isPointInPath(75, 20)); - verify(!ctx.isPointInPath(75, 30)); - - ctx.reset(); - ctx.arc(50, 25, 10, 0, 7, false); - verify(!ctx.isPointInPath(50, 10)); - //verify(ctx.isPointInPath(50, 20)); - //verify(ctx.isPointInPath(50, 30)); - verify(!ctx.isPointInPath(50, 40)); - verify(!ctx.isPointInPath(30, 20)); - verify(!ctx.isPointInPath(70, 20)); - verify(!ctx.isPointInPath(30, 30)); - //verify(!ctx.isPointInPath(70, 30)); - - ctx.reset(); - ctx.rect(0, 0, 20, 20); - verify(ctx.isPointInPath(0, 0)); - verify(ctx.isPointInPath(10, 0)); - //verify(ctx.isPointInPath(20, 0)); - //verify(ctx.isPointInPath(20, 10)); - //verify(ctx.isPointInPath(20, 20)); - //verify(ctx.isPointInPath(10, 20)); - //verify(ctx.isPointInPath(0, 20)); - verify(ctx.isPointInPath(0, 10)); - verify(!ctx.isPointInPath(10, -0.01)); - verify(!ctx.isPointInPath(10, 20.01)); - verify(!ctx.isPointInPath(-0.01, 10)); - //verify(!ctx.isPointInPath(20.01, 10)); - - ctx.reset(); - verify(!ctx.isPointInPath(0, 0)); - - - ctx.reset(); - ctx.rect(-100, -50, 200, 100); - //verify(ctx.isPointInPath(Infinity, 0)); - //verify(ctx.isPointInPath(-Infinity, 0)); - //verify(ctx.isPointInPath(NaN, 0)); - //verify(ctx.isPointInPath(0, Infinity)); - //verify(ctx.isPointInPath(0, -Infinity)); - //verify(ctx.isPointInPath(0, NaN)); - //verify(ctx.isPointInPath(NaN, NaN)); - - ctx.reset(); - ctx.rect(0, -100, 20, 20); - ctx.rect(20, -10, 20, 20); - verify(!ctx.isPointInPath(10, -110)); - verify(ctx.isPointInPath(10, -90)); - verify(!ctx.isPointInPath(10, -70)); - //verify(!ctx.isPointInPath(30, -20)); - //verify(ctx.isPointInPath(30, 0)); - //verify(!ctx.isPointInPath(30, 20)); - - ctx.reset(); - ctx.rect(0, 0, 20, 20); - ctx.beginPath(); - ctx.rect(20, 0, 20, 20); - ctx.closePath(); - ctx.rect(40, 0, 20, 20); - verify(!ctx.isPointInPath(10, 10)); - verify(ctx.isPointInPath(30, 10)); - verify(ctx.isPointInPath(50, 10)); - - ctx.reset(); - ctx.translate(50, 0); - ctx.rect(0, 0, 20, 20); - verify(!ctx.isPointInPath(-40, 10)); - verify(!ctx.isPointInPath(10, 10)); - //verify(!ctx.isPointInPath(49, 10)); - verify(ctx.isPointInPath(51, 10)); - verify(ctx.isPointInPath(69, 10)); - verify(!ctx.isPointInPath(71, 10)); - - ctx.reset(); - ctx.rect(50, 0, 20, 20); - ctx.translate(50, 0); - verify(!ctx.isPointInPath(-40, 10)); - verify(!ctx.isPointInPath(10, 10)); - //verify(!ctx.isPointInPath(49, 10)); - verify(ctx.isPointInPath(51, 10)); - verify(ctx.isPointInPath(69, 10)); - verify(!ctx.isPointInPath(71, 10)); - - ctx.reset(); - ctx.scale(-1, 1); - ctx.rect(-70, 0, 20, 20); - verify(!ctx.isPointInPath(-40, 10)); - verify(!ctx.isPointInPath(10, 10)); - //verify(!ctx.isPointInPath(49, 10)); - verify(ctx.isPointInPath(51, 10)); - verify(ctx.isPointInPath(69, 10)); - verify(!ctx.isPointInPath(71, 10)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(20, 0); - ctx.lineTo(20, 20); - ctx.lineTo(0, 20); - verify(ctx.isPointInPath(10, 10)); - //verify(!ctx.isPointInPath(30, 10)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(50, 0); - ctx.lineTo(50, 50); - ctx.lineTo(0, 50); - ctx.lineTo(0, 0); - ctx.lineTo(10, 10); - ctx.lineTo(10, 40); - ctx.lineTo(40, 40); - ctx.lineTo(40, 10); - ctx.lineTo(10, 10); - - verify(ctx.isPointInPath(5, 5)); - verify(ctx.isPointInPath(25, 5)); - verify(ctx.isPointInPath(45, 5)); - verify(ctx.isPointInPath(5, 25)); - verify(!ctx.isPointInPath(25, 25)); - verify(ctx.isPointInPath(45, 25)); - verify(ctx.isPointInPath(5, 45)); - verify(ctx.isPointInPath(25, 45)); - verify(ctx.isPointInPath(45, 45)); - } - - - function test_fill() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - ctx.reset(); - ctx.fillStyle = '#00f'; - ctx.fillRect(0, 0, 100, 50); - - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.lineTo(100, 50); - ctx.fillStyle = '#f00'; - ctx.fill(); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - - //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 10,40, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#000'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.rect(0, 0, 100, 50); - ctx.closePath(); - ctx.rect(10, 10, 80, 30); - ctx.fill(); - - //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255, 1)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.lineTo(-10, -10); - ctx.lineTo(0, 0); - ctx.lineTo(100, 0); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fill(); - - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.lineTo(-10, -10); - ctx.lineTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.moveTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.lineTo(-10, -10); - ctx.lineTo(-20, -20); - ctx.lineTo(120, -20); - ctx.lineTo(120, 70); - ctx.lineTo(-20, 70); - ctx.lineTo(-20, -20); - ctx.lineTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - function test_stroke() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.moveTo(40, 25); - ctx.moveTo(60, 25); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#000'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; - ctx.lineWidth = 50; - ctx.moveTo(0, 20); - ctx.lineTo(100, 20); - ctx.moveTo(0, 30); - ctx.lineTo(100, 30); - ctx.stroke(); - - //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.arcTo(50, 25, 150, 25, 10); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.arc(50, 25, 10, 0, 0, false); - ctx.stroke(); - - // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.lineTo(50, 25); - ctx.closePath(); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 400; - ctx.lineJoin = 'miter'; - ctx.miterLimit = 1.4; - - ctx.beginPath(); - ctx.moveTo(-1000, 200, 0, 0); - ctx.lineTo(-100, 200); - ctx.lineTo(-100, 200); - ctx.lineTo(-100, 200); - ctx.lineTo(-100, 1000); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.quadraticCurveTo(50, 25, 50, 25); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.moveTo(50, 25); - ctx.lineTo(50, 25); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.lineCap = 'round'; - ctx.lineJoin = 'round'; - - ctx.beginPath(); - ctx.rect(50, 25, 0, 0); - ctx.stroke(); - - ctx.strokeRect(50, 25, 0, 0); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.rect(25, 12.5, 50, 25); - ctx.save(); - ctx.scale(50, 25); - ctx.strokeStyle = '#0f0'; - ctx.stroke(); - ctx.restore(); - - ctx.beginPath(); - ctx.rect(-25, -12.5, 150, 75); - ctx.save(); - ctx.scale(50, 25); - ctx.strokeStyle = '#f00'; - ctx.stroke(); - ctx.restore(); - - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.rect(25, 12.5, 50, 25); - ctx.save(); - ctx.rotate(Math.PI/2); - ctx.scale(25, 50); - ctx.strokeStyle = '#0f0'; - ctx.stroke(); - ctx.restore(); - - ctx.beginPath(); - ctx.rect(-25, -12.5, 150, 75); - ctx.save(); - ctx.rotate(Math.PI/2); - ctx.scale(25, 50); - ctx.strokeStyle = '#f00'; - ctx.stroke(); - ctx.restore(); - - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.save(); - ctx.beginPath(); - ctx.moveTo(49, -50); - ctx.lineTo(201, -50); - ctx.rotate(Math.PI/4); - ctx.scale(1, 283); - ctx.strokeStyle = '#0f0'; - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.beginPath(); - ctx.translate(-150, 0); - ctx.moveTo(49, -50); - ctx.lineTo(199, -50); - ctx.rotate(Math.PI/4); - ctx.scale(1, 142); - ctx.strokeStyle = '#f00'; - ctx.stroke(); - ctx.restore(); - - ctx.save(); - ctx.beginPath(); - ctx.translate(-150, 0); - ctx.moveTo(49, -50); - ctx.lineTo(199, -50); - ctx.rotate(Math.PI/4); - ctx.scale(1, 142); - ctx.strokeStyle = '#f00'; - ctx.stroke(); - ctx.restore(); - - //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.lineWidth = 50; - ctx.moveTo(-100, 25); - ctx.lineTo(-100, -100); - ctx.lineTo(200, -100); - ctx.lineTo(200, 25); - ctx.strokeStyle = '#f00'; - ctx.stroke(); - - ctx.closePath(); - ctx.strokeStyle = '#0f0'; - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 40; - ctx.moveTo(0, 10); - ctx.lineTo(100, 10); - ctx.moveTo(100, 40); - ctx.lineTo(0, 40); - ctx.stroke(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - function test_clip() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.rect(0, 0, 100, 50); - ctx.clip(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.rect(-100, 0, 100, 50); - ctx.clip(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.clip(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.rect(0, 0, 50, 50); - ctx.clip(); - ctx.beginPath(); - ctx.rect(50, 0, 50, 50) - ctx.clip(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#0f0'; - - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.clip(); - - ctx.lineTo(0, 0); - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.lineTo(-10, -10); - ctx.lineTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.clip(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.beginPath(); - ctx.moveTo(-10, -10); - ctx.lineTo(110, -10); - ctx.lineTo(110, 60); - ctx.lineTo(-10, 60); - ctx.lineTo(-10, -10); - ctx.clip(); - - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.lineTo(0, 50); - ctx.lineTo(100, 50); - ctx.lineTo(100, 0); - ctx.lineTo(0, 0); - ctx.clip(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_moveTo() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.rect(0, 0, 10, 50); - ctx.moveTo(100, 0); - ctx.lineTo(10, 0); - ctx.lineTo(10, 50); - ctx.lineTo(100, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 90,25, 0,255,0,255)); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.moveTo(0, 25); - ctx.moveTo(100, 25); - ctx.moveTo(0, 25); - ctx.lineTo(100, 25); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.beginPath(); - ctx.moveTo(0, 0); - ctx.moveTo(100, 0); - ctx.moveTo(100, 50); - ctx.moveTo(0, 50); - ctx.fillStyle = '#f00'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.moveTo(Infinity, 50); - ctx.moveTo(-Infinity, 50); - ctx.moveTo(NaN, 50); - ctx.moveTo(0, Infinity); - ctx.moveTo(0, -Infinity); - ctx.moveTo(0, NaN); - ctx.moveTo(Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_lineTo() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.lineTo(100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.lineTo(100, 50); - ctx.stroke(); - // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.lineTo(0, 25); - ctx.lineTo(100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(-100, -100); - ctx.lineTo(0, 25); - ctx.lineTo(100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.lineTo(Infinity, 50); - ctx.lineTo(-Infinity, 50); - ctx.lineTo(NaN, 50); - ctx.lineTo(0, Infinity); - ctx.lineTo(0, -Infinity); - ctx.lineTo(0, NaN); - ctx.lineTo(Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); - - } - function test_bezierCurveTo() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.bezierCurveTo(100, 25, 100, 25, 100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.bezierCurveTo(100, 50, 200, 50, 200, 50); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.bezierCurveTo(0, 25, 100, 25, 100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50); - ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50); - ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50); - ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50); - ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50); - ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50); - ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50); - ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50); - ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50); - ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50); - ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50); - ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50); - ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50); - ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50); - ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50); - ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity); - ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity); - ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN); - ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50); - ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity); - ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity); - ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50); - ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50); - ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50); - ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity); - ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50); - ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity); - ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity); - ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50); - ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50); - ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity); - ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50); - ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity); - ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity); - ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50); - ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50); - ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity); - ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50); - ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity); - ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity); - ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50); - ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity); - ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity); - ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.scale(1000, 1000); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 0.055; - ctx.beginPath(); - ctx.moveTo(-2, 3.1); - ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 55; - ctx.beginPath(); - ctx.moveTo(-2000, 3100); - ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - } - function test_quadraticCurveTo() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.moveTo(0, 25); - ctx.quadraticCurveTo(100, 25, 100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.quadraticCurveTo(100, 50, 200, 50); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.beginPath(); - ctx.quadraticCurveTo(0, 25, 100, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255)); - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.quadraticCurveTo(Infinity, 50, 0, 50); - ctx.quadraticCurveTo(-Infinity, 50, 0, 50); - ctx.quadraticCurveTo(NaN, 50, 0, 50); - ctx.quadraticCurveTo(0, Infinity, 0, 50); - ctx.quadraticCurveTo(0, -Infinity, 0, 50); - ctx.quadraticCurveTo(0, NaN, 0, 50); - ctx.quadraticCurveTo(0, 50, Infinity, 50); - ctx.quadraticCurveTo(0, 50, -Infinity, 50); - ctx.quadraticCurveTo(0, 50, NaN, 50); - ctx.quadraticCurveTo(0, 50, 0, Infinity); - ctx.quadraticCurveTo(0, 50, 0, -Infinity); - ctx.quadraticCurveTo(0, 50, 0, NaN); - ctx.quadraticCurveTo(Infinity, Infinity, 0, 50); - ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50); - ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity); - ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity); - ctx.quadraticCurveTo(Infinity, 50, Infinity, 50); - ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity); - ctx.quadraticCurveTo(Infinity, 50, 0, Infinity); - ctx.quadraticCurveTo(0, Infinity, Infinity, 50); - ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity); - ctx.quadraticCurveTo(0, Infinity, 0, Infinity); - ctx.quadraticCurveTo(0, 50, Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.scale(1000, 1000); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 0.055; - ctx.beginPath(); - ctx.moveTo(-1, 1.05); - ctx.quadraticCurveTo(0, -1, 1.2, 1.05); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 55; - ctx.beginPath(); - ctx.moveTo(-1000, 1050); - ctx.quadraticCurveTo(0, -1000, 1200, 1050); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - } - function test_rect() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#0f0'; - ctx.rect(0, 0, 100, 50); - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 200; - ctx.lineJoin = 'miter'; - ctx.rect(100, 50, 100, 100); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.rect(200, 100, 400, 1000); - ctx.lineTo(-2000, -1000); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 450; - ctx.lineCap = 'round'; - ctx.lineJoin = 'bevel'; - ctx.rect(150, 150, 2000, 2000); - ctx.lineTo(160, 160); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.beginPath(); - ctx.fillStyle = '#0f0'; - ctx.rect(0, 0, 50, 25); - ctx.rect(100, 0, -50, 25); - ctx.rect(0, 50, 50, -25); - ctx.rect(100, 50, -50, -25); - ctx.fill(); - verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.beginPath(); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.moveTo(-100, 25); - ctx.lineTo(-50, 25); - ctx.rect(200, 25, 1, 1); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - ctx.reset(); - ctx.moveTo(0, 0); - ctx.lineTo(100, 0); - ctx.rect(Infinity, 50, 1, 1); - ctx.rect(-Infinity, 50, 1, 1); - ctx.rect(NaN, 50, 1, 1); - ctx.rect(0, Infinity, 1, 1); - ctx.rect(0, -Infinity, 1, 1); - ctx.rect(0, NaN, 1, 1); - ctx.rect(0, 50, Infinity, 1); - ctx.rect(0, 50, -Infinity, 1); - ctx.rect(0, 50, NaN, 1); - ctx.rect(0, 50, 1, Infinity); - ctx.rect(0, 50, 1, -Infinity); - ctx.rect(0, 50, 1, NaN); - ctx.rect(Infinity, Infinity, 1, 1); - ctx.rect(Infinity, Infinity, Infinity, 1); - ctx.rect(Infinity, Infinity, Infinity, Infinity); - ctx.rect(Infinity, Infinity, 1, Infinity); - ctx.rect(Infinity, 50, Infinity, 1); - ctx.rect(Infinity, 50, Infinity, Infinity); - ctx.rect(Infinity, 50, 1, Infinity); - ctx.rect(0, Infinity, Infinity, 1); - ctx.rect(0, Infinity, Infinity, Infinity); - ctx.rect(0, Infinity, 1, Infinity); - ctx.rect(0, 50, Infinity, Infinity); - ctx.lineTo(100, 50); - ctx.lineTo(0, 50); - ctx.fillStyle = '#0f0'; - ctx.fill(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - //verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); - - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 90; - ctx.beginPath(); - ctx.rect(45, 20, 10, 10); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.beginPath(); - ctx.fillStyle = '#f00'; - ctx.rect(0, 0, 50, 50); - ctx.rect(100, 50, -50, -50); - ctx.rect(0, 25, 100, -25); - ctx.rect(100, 25, -100, 25); - ctx.fill(); - verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.rect(0, 50, 100, 0); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.rect(50, -100, 0, 250); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 100; - ctx.beginPath(); - ctx.rect(50, 25, 0, 0); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#0f0'; - ctx.lineWidth = 50; - ctx.rect(100, 25, 0, 0); - ctx.lineTo(0, 25); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.moveTo(0, 0); - ctx.rect(100, 25, 0, 0); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineJoin = 'miter'; - ctx.miterLimit = 1.5; - ctx.lineWidth = 200; - ctx.beginPath(); - ctx.rect(100, 25, 1000, 0); - ctx.stroke(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_clearRect() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.beginPath(); - ctx.rect(0, 0, 100, 50); - ctx.clearRect(0, 0, 16, 16); - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_fillRect() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.beginPath(); - ctx.rect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 16, 16); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - - function test_strokeRect() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.beginPath(); - ctx.rect(0, 0, 100, 50); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 5; - ctx.strokeRect(0, 0, 16, 16); - ctx.fillStyle = '#0f0'; - ctx.fill(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_transform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(-100, 0); - ctx.rect(100, 0, 100, 50); - ctx.translate(0, -100); - ctx.fillStyle = '#0f0'; - ctx.fill(); - - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#0f0'; - ctx.moveTo(0, 0); - ctx.translate(100, 0); - ctx.lineTo(0, 0); - ctx.translate(0, 50); - ctx.lineTo(0, 0); - ctx.translate(-100, 0); - ctx.lineTo(0, 0); - ctx.translate(1000, 1000); - ctx.rotate(Math.PI/2); - ctx.scale(0.1, 0.1); - ctx.fill(); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - ctx.reset(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.fillStyle = '#f00'; - ctx.translate(-100, 0); - ctx.rect(0, 0, 100, 50); - ctx.fill(); - ctx.translate(100, 0); - ctx.fill(); - - ctx.beginPath(); - ctx.strokeStyle = '#f00'; - ctx.lineWidth = 50; - ctx.translate(0, -50); - ctx.moveTo(0, 25); - ctx.lineTo(100, 25); - ctx.stroke(); - ctx.translate(0, 50); - ctx.stroke(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_pattern.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_pattern.qml deleted file mode 100644 index dd5b6628e8..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_pattern.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - //TODO - name: "pattern"; when: windowShown - function test_basic() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_animated() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_image() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_modified() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_paint() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_repeat() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_pixel.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_pixel.qml deleted file mode 100644 index 1a3793d7a3..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_pixel.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - //TODO - name: "pixel"; when: windowShown - function test_createImageData() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_getImageData() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_object() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_putImageData() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_filters() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_shadow.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_shadow.qml deleted file mode 100644 index 4405ca6c0e..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_shadow.qml +++ /dev/null @@ -1,59 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - //TODO - - name: "shadow"; when: windowShown - function test_basic() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_blur() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - - function test_clip() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - - function test_composite() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - - function test_enable() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - - function test_gradient() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_image() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_offset() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_pattern() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_stroke() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_tranform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_state.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_state.qml deleted file mode 100644 index 8042cf6a1d..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_state.qml +++ /dev/null @@ -1,390 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - id:testCase - name: "state"; when: windowShown - function test_bitmap() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.save(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.restore(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_clip() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.save(); - ctx.rect(0, 0, 1, 1); - ctx.clip(); - ctx.restore(); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - function test_fillStyle() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - // Test that restore() undoes any modifications - var old = ctx.fillStyle; - ctx.save(); - ctx.fillStyle = "#ff0000"; - ctx.restore(); - compare(ctx.fillStyle, old); - - // Also test that save() doesn't modify the values - ctx.fillStyle = "#ff0000"; - old = ctx.fillStyle; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "#ff0000" - ctx.save(); - compare(ctx.fillStyle, old); - ctx.restore(); - } - function test_font() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.font; - ctx.save(); - ctx.font = "25px serif"; - ctx.restore(); - compare(ctx.font, old); - - // Also test that save() doesn't modify the values - ctx.font = "25px serif"; - old = ctx.font; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "25px serif" - ctx.save(); - compare(ctx.font, old); - ctx.restore(); - } - function test_globalAlpha() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.globalAlpha; - ctx.save(); - ctx.globalAlpha = 0.5; - ctx.restore(); - compare(ctx.globalAlpha, old); - - // Also test that save() doesn't modify the values - ctx.globalAlpha = 0.5; - old = ctx.globalAlpha; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against 0.5 - ctx.save(); - compare(ctx.globalAlpha, old); - ctx.restore(); - } - function test_globalCompositeOperation() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.globalCompositeOperation; - ctx.save(); - ctx.globalCompositeOperation = "copy"; - ctx.restore(); - compare(ctx.globalCompositeOperation, old); - - // Also test that save() doesn't modify the values - ctx.globalCompositeOperation = "copy"; - old = ctx.globalCompositeOperation; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "copy" - ctx.save(); - compare(ctx.globalCompositeOperation, old); - ctx.restore(); - } - function test_lineCap() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.lineCap; - ctx.save(); - ctx.lineCap = "round"; - ctx.restore(); - compare(ctx.lineCap, old); - - // Also test that save() doesn't modify the values - ctx.lineCap = "round"; - old = ctx.lineCap; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "round" - ctx.save(); - compare(ctx.lineCap, old); - ctx.restore(); - } - function test_lineJoin() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.lineJoin; - ctx.save(); - ctx.lineJoin = "round"; - ctx.restore(); - compare(ctx.lineJoin, old); - - // Also test that save() doesn't modify the values - ctx.lineJoin = "round"; - old = ctx.lineJoin; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "round" - ctx.save(); - compare(ctx.lineJoin, old); - ctx.restore(); - } - function test_lineWidth() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.lineJoin; - ctx.save(); - ctx.lineJoin = "round"; - ctx.restore(); - compare(ctx.lineJoin, old, "ctx.lineJoin", "old"); - - // Also test that save() doesn't modify the values - ctx.lineJoin = "round"; - old = ctx.lineJoin; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "round" - ctx.save(); - compare(ctx.lineJoin, old); - ctx.restore(); - } - function test_miterLimit() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.miterLimit; - ctx.save(); - ctx.miterLimit = 0.5; - ctx.restore(); - compare(ctx.miterLimit, old); - - // Also test that save() doesn't modify the values - ctx.miterLimit = 0.5; - old = ctx.miterLimit; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against 0.5 - ctx.save(); - compare(ctx.miterLimit, old); - ctx.restore(); - } - function test_path() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.save(); - ctx.rect(0, 0, 100, 50); - ctx.restore(); - ctx.fillStyle = '#0f0'; - ctx.fill(); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_shadow() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.shadowBlur; - ctx.save(); - ctx.shadowBlur = 5; - ctx.restore(); - compare(ctx.shadowBlur, old); - - // Also test that save() doesn't modify the values - ctx.shadowBlur = 5; - old = ctx.shadowBlur; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against 5 - ctx.save(); - compare(ctx.shadowBlur, old); - ctx.restore(); - - // Test that restore() undoes any modifications - var old = ctx.shadowColor; - ctx.save(); - ctx.shadowColor = "#ff0000"; - ctx.restore(); - compare(ctx.shadowColor, old); - - // Also test that save() doesn't modify the values - ctx.shadowColor = "#ff0000"; - old = ctx.shadowColor; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "#ff0000" - ctx.save(); - compare(ctx.shadowColor, old); - ctx.restore(); - - // Test that restore() undoes any modifications - var old = ctx.shadowOffsetX; - ctx.save(); - ctx.shadowOffsetX = 5; - ctx.restore(); - compare(ctx.shadowOffsetX, old); - - // Also test that save() doesn't modify the values - ctx.shadowOffsetX = 5; - old = ctx.shadowOffsetX; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against 5 - ctx.save(); - compare(ctx.shadowOffsetX, old); - ctx.restore(); - - // Test that restore() undoes any modifications - var old = ctx.shadowOffsetY; - ctx.save(); - ctx.shadowOffsetY = 5; - ctx.restore(); - compare(ctx.shadowOffsetY, old); - - // Also test that save() doesn't modify the values - ctx.shadowOffsetY = 5; - old = ctx.shadowOffsetY; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against 5 - ctx.save(); - compare(ctx.shadowOffsetY, old); - ctx.restore(); - - } - function test_stack() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.lineWidth = 1; - ctx.save(); - ctx.lineWidth = 2; - ctx.save(); - ctx.lineWidth = 3; - compare(ctx.lineWidth, 3); - ctx.restore(); - compare(ctx.lineWidth, 2); - ctx.restore(); - compare(ctx.lineWidth, 1); - - var limit = 512; - for (var i = 1; i < limit; ++i) - { - ctx.save(); - ctx.lineWidth = i; - } - for (var i = limit-1; i > 0; --i) - { - testCase.compare(ctx.lineWidth, i); //strange javascript error here - ctx.restore(); - } - - for (var i = 0; i < 16; ++i) - ctx.restore(); - ctx.lineWidth = 0.5; - ctx.restore(); - compare(ctx.lineWidth, 0.5); - - } - function test_strokeStyle() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.strokeStyle; - ctx.save(); - ctx.strokeStyle = "#ff0000"; - ctx.restore(); - compare(ctx.strokeStyle, old); - - // Also test that save() doesn't modify the values - ctx.strokeStyle = "#ff0000"; - old = ctx.strokeStyle; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "#ff0000" - ctx.save(); - compare(ctx.strokeStyle, old); - ctx.restore(); - - - } - - function test_text() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - // Test that restore() undoes any modifications - var old = ctx.textAlign; - ctx.save(); - ctx.textAlign = "center"; - ctx.restore(); - compare(ctx.textAlign, old); - - // Also test that save() doesn't modify the values - ctx.textAlign = "center"; - old = ctx.textAlign; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "center" - ctx.save(); - compare(ctx.textAlign, old); - ctx.restore(); - - // Test that restore() undoes any modifications - var old = ctx.textBaseline; - ctx.save(); - ctx.textBaseline = "bottom"; - ctx.restore(); - compare(ctx.textBaseline, old); - - // Also test that save() doesn't modify the values - ctx.textBaseline = "bottom"; - old = ctx.textBaseline; - // we're not interested in failures caused by get(set(x)) != x (e.g. - // from rounding), so compare against 'old' instead of against "bottom" - ctx.save(); - compare(ctx.textBaseline, old); - ctx.restore(); - - - } - - function test_transform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.save(); - ctx.translate(200, 0); - ctx.restore(); - ctx.fillStyle = '#f00'; - ctx.fillRect(-200, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - } - - - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_strokeStyle.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_strokeStyle.qml deleted file mode 100644 index 6b42f8a770..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_strokeStyle.qml +++ /dev/null @@ -1,48 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper - -Canvas { - id:canvas; width:100;height:50; renderTarget:Canvas.Image - TestCase { - name: "strokeStyle"; when: windowShown - function test_default() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - compare(ctx.strokeStyle, "#000000") - ctx.clearRect(0, 0, 1, 1); - compare(ctx.strokeStyle, "#000000") - } - function test_saverestore() { - var ctx = canvas.getContext('2d'); - var old = ctx.strokeStyle; - ctx.save(); - ctx.strokeStyle = "#ffaaff"; - ctx.restore(); - compare(ctx.strokeStyle, old); - - ctx.strokeStyle = "#ffcc88"; - old = ctx.strokeStyle; - ctx.save(); - compare(ctx.strokeStyle, old); - ctx.restore(); - } - function test_namedColor() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.strokeStyle = "red"; - ctx.strokeRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,255,0,0,255)); - - ctx.strokeStyle = "black"; - ctx.strokeRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,0,0,0,255)); - - ctx.strokeStyle = "white"; - ctx.strokeRect(0,0,1,1); - verify(Helper.comparePixel(ctx,0,0,255,255,255,255)); - } - - - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_text.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_text.qml deleted file mode 100644 index baeb17c9fb..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_text.qml +++ /dev/null @@ -1,34 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - //TODO - name: "text"; when: windowShown - function test_baseLine() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_align() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_stroke() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_fill() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_font() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - function test_measure() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/tst_transform.qml b/tests/auto/declarative/qquickcanvasitem/data/tst_transform.qml deleted file mode 100644 index 834a22f549..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/data/tst_transform.qml +++ /dev/null @@ -1,487 +0,0 @@ -import QtQuick 2.0 -import QtTest 1.0 -import "testhelper.js" as Helper -Canvas { - id:canvas; width:100;height:50; renderTarget: Canvas.Image - TestCase { - name: "transform"; when: windowShown - function test_order() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.scale(2, 1); - ctx.rotate(Math.PI / 2); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, -50, 50, 50); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - } - function test_rotate() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.rotate(Math.PI / 2); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, -100, 50, 100); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 10); - ctx.rotate(Infinity); - ctx.rotate(-Infinity); - ctx.rotate(NaN); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -10, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi) - // We need about pi +/- 0.001 in order to get correct-looking results - // 32-bit floats can store pi*4097 with precision 2^-10, so that should - // be safe enough on reasonable implementations - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.rotate(-Math.PI * (1 + 4096)); - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -50, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.rotate(0); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - } - function test_scale() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.scale(2, 4); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 50, 12.5); - verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.scale(1e5, 1e5); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 1, 1); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.scale(Math.sqrt(2), Math.sqrt(2)); - ctx.scale(Math.sqrt(2), Math.sqrt(2)); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 50, 25); - verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.save(); - ctx.scale(-1, 1); - ctx.fillStyle = '#0f0'; - ctx.fillRect(-50, 0, 50, 50); - ctx.restore(); - - ctx.save(); - ctx.scale(1, -1); - ctx.fillStyle = '#0f0'; - ctx.fillRect(50, -50, 50, 50); - ctx.restore(); - verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 10); - ctx.scale(Infinity, 0.1); - ctx.scale(-Infinity, 0.1); - ctx.scale(NaN, 0.1); - ctx.scale(0.1, Infinity); - ctx.scale(0.1, -Infinity); - ctx.scale(0.1, NaN); - ctx.scale(Infinity, Infinity); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -10, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - - ctx.save(); - ctx.translate(50, 0); - ctx.scale(0, 1); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.restore(); - - ctx.save(); - ctx.translate(0, 25); - ctx.scale(1, 0); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - ctx.restore(); - - // Firefox has a bug where it renders the canvas as empty and toDataURL throws an exception - canvas.toDataURL(); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - } - function test_setTransform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.setTransform(1/2,0, 0,1/2, 0,0); - ctx.setTransform(2,0, 0,2, 0,0); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 50, 25); - verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 10); - ctx.setTransform(Infinity, 0, 0, 0, 0, 0); - ctx.setTransform(-Infinity, 0, 0, 0, 0, 0); - ctx.setTransform(NaN, 0, 0, 0, 0, 0); - ctx.setTransform(0, Infinity, 0, 0, 0, 0); - ctx.setTransform(0, -Infinity, 0, 0, 0, 0); - ctx.setTransform(0, NaN, 0, 0, 0, 0); - ctx.setTransform(0, 0, Infinity, 0, 0, 0); - ctx.setTransform(0, 0, -Infinity, 0, 0, 0); - ctx.setTransform(0, 0, NaN, 0, 0, 0); - ctx.setTransform(0, 0, 0, Infinity, 0, 0); - ctx.setTransform(0, 0, 0, -Infinity, 0, 0); - ctx.setTransform(0, 0, 0, NaN, 0, 0); - ctx.setTransform(0, 0, 0, 0, Infinity, 0); - ctx.setTransform(0, 0, 0, 0, -Infinity, 0); - ctx.setTransform(0, 0, 0, 0, NaN, 0); - ctx.setTransform(0, 0, 0, 0, 0, Infinity); - ctx.setTransform(0, 0, 0, 0, 0, -Infinity); - ctx.setTransform(0, 0, 0, 0, 0, NaN); - ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0); - ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0); - ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0); - ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0); - ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity); - ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0); - ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity); - ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0); - ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0); - ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity); - ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0); - ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity); - ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0); - ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0); - ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0); - ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity); - ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity); - ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0); - ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity); - ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity); - ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0); - ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0); - ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity); - ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity); - ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0); - ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity); - ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity); - ctx.setTransform(0, Infinity, Infinity, 0, 0, 0); - ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0); - ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0); - ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity); - ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0); - ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity); - ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity); - ctx.setTransform(0, Infinity, 0, Infinity, 0, 0); - ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0); - ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity); - ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity); - ctx.setTransform(0, Infinity, 0, 0, Infinity, 0); - ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity); - ctx.setTransform(0, Infinity, 0, 0, 0, Infinity); - ctx.setTransform(0, 0, Infinity, Infinity, 0, 0); - ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0); - ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity); - ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity); - ctx.setTransform(0, 0, Infinity, 0, Infinity, 0); - ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity); - ctx.setTransform(0, 0, Infinity, 0, 0, Infinity); - ctx.setTransform(0, 0, 0, Infinity, Infinity, 0); - ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity); - ctx.setTransform(0, 0, 0, Infinity, 0, Infinity); - ctx.setTransform(0, 0, 0, 0, Infinity, Infinity); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -10, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - // Create green with a red square ring inside it - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.fillRect(20, 10, 60, 30); - ctx.fillStyle = '#0f0'; - ctx.fillRect(40, 20, 20, 10); - - // Draw a skewed shape to fill that gap, to make sure it is aligned correctly - ctx.setTransform(1,4, 2,3, 5,6); - // Post-transform coordinates: - // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; - // Hence pre-transform coordinates: - var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], - [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], - [-7.4,11.2]]; - ctx.beginPath(); - ctx.moveTo(pts[0][0], pts[0][1]); - for (var i = 0; i < pts.length; ++i) - ctx.lineTo(pts[i][0], pts[i][1]); - ctx.fill(); - /* - //FIXME: - verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255)); - */ - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.transform(1,0, 0,1, 0,0); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - } - function test_transform() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.transform(1,2, 3,4, 5,6); - ctx.transform(-2,1, 3/2,-1/2, 1,-2); - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 10); - ctx.transform(Infinity, 0, 0, 0, 0, 0); - ctx.transform(-Infinity, 0, 0, 0, 0, 0); - ctx.transform(NaN, 0, 0, 0, 0, 0); - ctx.transform(0, Infinity, 0, 0, 0, 0); - ctx.transform(0, -Infinity, 0, 0, 0, 0); - ctx.transform(0, NaN, 0, 0, 0, 0); - ctx.transform(0, 0, Infinity, 0, 0, 0); - ctx.transform(0, 0, -Infinity, 0, 0, 0); - ctx.transform(0, 0, NaN, 0, 0, 0); - ctx.transform(0, 0, 0, Infinity, 0, 0); - ctx.transform(0, 0, 0, -Infinity, 0, 0); - ctx.transform(0, 0, 0, NaN, 0, 0); - ctx.transform(0, 0, 0, 0, Infinity, 0); - ctx.transform(0, 0, 0, 0, -Infinity, 0); - ctx.transform(0, 0, 0, 0, NaN, 0); - ctx.transform(0, 0, 0, 0, 0, Infinity); - ctx.transform(0, 0, 0, 0, 0, -Infinity); - ctx.transform(0, 0, 0, 0, 0, NaN); - ctx.transform(Infinity, Infinity, 0, 0, 0, 0); - ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0); - ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0); - ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0); - ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity); - ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0); - ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity); - ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity); - ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0); - ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0); - ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity); - ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity); - ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0); - ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity); - ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity); - ctx.transform(Infinity, 0, Infinity, 0, 0, 0); - ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0); - ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0); - ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity); - ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity); - ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0); - ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0); - ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity); - ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity); - ctx.transform(Infinity, 0, 0, Infinity, 0, 0); - ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0); - ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity); - ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity); - ctx.transform(Infinity, 0, 0, 0, Infinity, 0); - ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity); - ctx.transform(Infinity, 0, 0, 0, 0, Infinity); - ctx.transform(0, Infinity, Infinity, 0, 0, 0); - ctx.transform(0, Infinity, Infinity, Infinity, 0, 0); - ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0); - ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity); - ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity); - ctx.transform(0, Infinity, Infinity, 0, Infinity, 0); - ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity); - ctx.transform(0, Infinity, Infinity, 0, 0, Infinity); - ctx.transform(0, Infinity, 0, Infinity, 0, 0); - ctx.transform(0, Infinity, 0, Infinity, Infinity, 0); - ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity); - ctx.transform(0, Infinity, 0, Infinity, 0, Infinity); - ctx.transform(0, Infinity, 0, 0, Infinity, 0); - ctx.transform(0, Infinity, 0, 0, Infinity, Infinity); - ctx.transform(0, Infinity, 0, 0, 0, Infinity); - ctx.transform(0, 0, Infinity, Infinity, 0, 0); - ctx.transform(0, 0, Infinity, Infinity, Infinity, 0); - ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity); - ctx.transform(0, 0, Infinity, Infinity, 0, Infinity); - ctx.transform(0, 0, Infinity, 0, Infinity, 0); - ctx.transform(0, 0, Infinity, 0, Infinity, Infinity); - ctx.transform(0, 0, Infinity, 0, 0, Infinity); - ctx.transform(0, 0, 0, Infinity, Infinity, 0); - ctx.transform(0, 0, 0, Infinity, Infinity, Infinity); - ctx.transform(0, 0, 0, Infinity, 0, Infinity); - ctx.transform(0, 0, 0, 0, Infinity, Infinity); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -10, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - ctx.reset(); - - // Create green with a red square ring inside it - ctx.fillStyle = '#0f0'; - ctx.fillRect(0, 0, 100, 50); - ctx.fillStyle = '#f00'; - ctx.fillRect(20, 10, 60, 30); - ctx.fillStyle = '#0f0'; - ctx.fillRect(40, 20, 20, 10); - - // Draw a skewed shape to fill that gap, to make sure it is aligned correctly - ctx.transform(1,4, 2,3, 5,6); - // Post-transform coordinates: - // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; - // Hence pre-transform coordinates: - var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], - [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], - [-7.4,11.2]]; - ctx.beginPath(); - ctx.moveTo(pts[0][0], pts[0][1]); - for (var i = 0; i < pts.length; ++i) - ctx.lineTo(pts[i][0], pts[i][1]); - ctx.fill(); - /* - //FIXME: - verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255)); - verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255)); - */ - } - function test_translate() { - var ctx = canvas.getContext('2d'); - ctx.reset(); - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 50); - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -50, 100, 50); - verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); - ctx.reset(); - - ctx.fillStyle = '#f00'; - ctx.fillRect(0, 0, 100, 50); - - ctx.translate(100, 10); - ctx.translate(Infinity, 0.1); - ctx.translate(-Infinity, 0.1); - ctx.translate(NaN, 0.1); - ctx.translate(0.1, Infinity); - ctx.translate(0.1, -Infinity); - ctx.translate(0.1, NaN); - ctx.translate(Infinity, Infinity); - - ctx.fillStyle = '#0f0'; - ctx.fillRect(-100, -10, 100, 50); - - verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); - - - } - } -} diff --git a/tests/auto/declarative/qquickcanvasitem/data/yellow.png b/tests/auto/declarative/qquickcanvasitem/data/yellow.png deleted file mode 100644 index 51e8aaf38c..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/yellow.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/data/yellow75.png b/tests/auto/declarative/qquickcanvasitem/data/yellow75.png deleted file mode 100644 index 2bb82c9834..0000000000 Binary files a/tests/auto/declarative/qquickcanvasitem/data/yellow75.png and /dev/null differ diff --git a/tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro deleted file mode 100644 index 141e477416..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/qquickcanvasitem.pro +++ /dev/null @@ -1,33 +0,0 @@ -QT += core-private gui-private declarative-private widgets -TEMPLATE=app -TARGET=tst_qquickcanvasitem - -CONFIG += warn_on qmltestcase -SOURCES += tst_qquickcanvasitem.cpp - -importFiles.files = data -importFiles.path = . -DEPLOYMENT += importFiles - -OTHER_FILES += \ - data/testhelper.js \ - data/tst_transform.qml \ - data/tst_text.qml \ - data/tst_strokeStyle.qml \ - data/tst_state.qml \ - data/tst_shadow.qml \ - data/tst_pattern.qml \ - data/tst_path.qml \ - data/tst_line.qml \ - data/tst_fillStyle.qml \ - data/tst_fillrect.qml \ - data/tst_drawimage.qml \ - data/tst_composite.qml \ - data/tst_canvas.qml \ - data/tst_pixel.qml \ - data/tst_gradient.qml \ - data/tst_arcto.qml \ - data/tst_arc.qml - - - diff --git a/tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp b/tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp deleted file mode 100644 index 57195babb7..0000000000 --- a/tests/auto/declarative/qquickcanvasitem/tst_qquickcanvasitem.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -QUICK_TEST_MAIN(qquickcanvasitem) diff --git a/tests/auto/declarative/qquickdrag/qquickdrag.pro b/tests/auto/declarative/qquickdrag/qquickdrag.pro deleted file mode 100644 index 416ecdbe8e..0000000000 --- a/tests/auto/declarative/qquickdrag/qquickdrag.pro +++ /dev/null @@ -1,9 +0,0 @@ -TARGET = tst_qquickdrag -CONFIG += testcase -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickdrag.cpp - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp b/tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp deleted file mode 100644 index 6bc0866a6e..0000000000 --- a/tests/auto/declarative/qquickdrag/tst_qquickdrag.cpp +++ /dev/null @@ -1,827 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -template static T evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - QVariant result = expr.evaluate(); - if (expr.hasError()) - qWarning() << expr.error().toString(); - return result.value(); -} - -template <> void evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - expr.evaluate(); - if (expr.hasError()) - qWarning() << expr.error().toString(); -} - -Q_DECLARE_METATYPE(Qt::DropActions) - -class TestDropTarget : public QQuickItem -{ - Q_OBJECT -public: - TestDropTarget(QQuickItem *parent = 0) - : QQuickItem(parent) - , enterEvents(0) - , moveEvents(0) - , leaveEvents(0) - , dropEvents(0) - , acceptAction(Qt::MoveAction) - , defaultAction(Qt::IgnoreAction) - , proposedAction(Qt::IgnoreAction) - , accept(true) - { - setFlags(ItemAcceptsDrops); - } - - void reset() - { - enterEvents = 0; - moveEvents = 0; - leaveEvents = 0; - dropEvents = 0; - defaultAction = Qt::IgnoreAction; - proposedAction = Qt::IgnoreAction; - supportedActions = Qt::IgnoreAction; - } - - void dragEnterEvent(QDragEnterEvent *event) - { - ++enterEvents; - position = event->pos(); - defaultAction = event->dropAction(); - proposedAction = event->proposedAction(); - supportedActions = event->possibleActions(); - event->setAccepted(accept); - } - - void dragMoveEvent(QDragMoveEvent *event) - { - ++moveEvents; - position = event->pos(); - defaultAction = event->dropAction(); - proposedAction = event->proposedAction(); - supportedActions = event->possibleActions(); - event->setAccepted(accept); - } - - void dragLeaveEvent(QDragLeaveEvent *event) - { - ++leaveEvents; - event->setAccepted(accept); - } - - void dropEvent(QDropEvent *event) - { - ++dropEvents; - position = event->pos(); - defaultAction = event->dropAction(); - proposedAction = event->proposedAction(); - supportedActions = event->possibleActions(); - event->setDropAction(acceptAction); - event->setAccepted(accept); - } - - int enterEvents; - int moveEvents; - int leaveEvents; - int dropEvents; - Qt::DropAction acceptAction; - Qt::DropAction defaultAction; - Qt::DropAction proposedAction; - Qt::DropActions supportedActions; - QPointF position; - bool accept; -}; - -class tst_QQuickDrag: public QObject -{ - Q_OBJECT -private slots: - void initTestCase(); - void cleanupTestCase(); - - void active(); - void drop(); - void move(); - void hotSpot(); - void supportedActions(); - void proposedAction(); - void keys(); - void source(); - -private: - QDeclarativeEngine engine; -}; - -void tst_QQuickDrag::initTestCase() -{ - -} - -void tst_QQuickDrag::cleanupTestCase() -{ - -} - -void tst_QQuickDrag::active() -{ - QQuickCanvas canvas; - TestDropTarget dropTarget(canvas.rootItem()); - dropTarget.setSize(QSizeF(100, 100)); - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property bool dragActive: Drag.active\n" - "property Item dragTarget: Drag.target\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&dropTarget); - - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.reset(); - evaluate(item, "Drag.active = false"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); - - dropTarget.reset(); - evaluate(item, "Drag.cancel()"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.reset(); - evaluate(item, "Drag.start()"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); - - // Start while a drag is active, cancels the previous drag and starts a new one. - dropTarget.reset(); - evaluate(item, "Drag.start()"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 1); - - dropTarget.reset(); - evaluate(item, "Drag.cancel()"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); - - // Enter events aren't sent to items without the QQuickItem::ItemAcceptsDrops flag. - dropTarget.setFlags(QQuickItem::Flags()); - - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.reset(); - evaluate(item, "Drag.active = false"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.setFlags(QQuickItem::ItemAcceptsDrops); - - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.setFlags(QQuickItem::Flags()); - - dropTarget.reset(); - evaluate(item, "Drag.active = false"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); - - // Follow up events aren't sent to items if the enter event isn't accepted. - dropTarget.setFlags(QQuickItem::ItemAcceptsDrops); - dropTarget.accept = false; - - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.reset(); - evaluate(item, "Drag.active = false"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.accept = true; - - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); - QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); - - dropTarget.accept = false; - - dropTarget.reset(); - evaluate(item, "Drag.active = false"); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); - - // Events are sent to hidden or disabled items. - dropTarget.accept = true; - dropTarget.setVisible(false); - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - evaluate(item, "Drag.active = false"); - dropTarget.setVisible(true); - - dropTarget.setOpacity(0.0); - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); - - evaluate(item, "Drag.active = false"); - dropTarget.setOpacity(1.0); - - dropTarget.setEnabled(false); - dropTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); -} - -void tst_QQuickDrag::drop() -{ - QQuickCanvas canvas; - TestDropTarget outerTarget(canvas.rootItem()); - outerTarget.setSize(QSizeF(100, 100)); - outerTarget.acceptAction = Qt::CopyAction; - TestDropTarget innerTarget(&outerTarget); - innerTarget.setSize(QSizeF(100, 100)); - innerTarget.acceptAction = Qt::MoveAction; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property bool dragActive: Drag.active\n" - "property Item dragTarget: Drag.target\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&outerTarget); - - innerTarget.reset(); outerTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - innerTarget.reset(); outerTarget.reset(); - QCOMPARE(evaluate(item, "Drag.drop() == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); - - innerTarget.reset(); outerTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - // Inner target declines the drop so it is propagated to the outer target. - innerTarget.accept = false; - - innerTarget.reset(); outerTarget.reset(); - QCOMPARE(evaluate(item, "Drag.drop() == Qt.CopyAction"), true); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); - - - // Inner target doesn't accept enter so drop goes directly to outer. - innerTarget.accept = true; - innerTarget.setFlags(QQuickItem::Flags()); - - innerTarget.reset(); outerTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - innerTarget.reset(); outerTarget.reset(); - QCOMPARE(evaluate(item, "Drag.drop() == Qt.CopyAction"), true); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - // Neither target accepts drop so Qt::IgnoreAction is returned. - innerTarget.reset(); outerTarget.reset(); - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - outerTarget.accept = false; - - innerTarget.reset(); outerTarget.reset(); - QCOMPARE(evaluate(item, "Drag.drop() == Qt.IgnoreAction"), true); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); - - // drop doesn't send an event and returns Qt.IgnoreAction if not active. - innerTarget.accept = true; - outerTarget.accept = true; - innerTarget.reset(); outerTarget.reset(); - QCOMPARE(evaluate(item, "Drag.drop() == Qt.IgnoreAction"), true); - QCOMPARE(evaluate(item, "Drag.active"), false); - QCOMPARE(evaluate(item, "dragActive"), false); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); - QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); -} - -void tst_QQuickDrag::move() -{ - QQuickCanvas canvas; - TestDropTarget outerTarget(canvas.rootItem()); - outerTarget.setSize(QSizeF(100, 100)); - TestDropTarget leftTarget(&outerTarget); - leftTarget.setPos(QPointF(0, 35)); - leftTarget.setSize(QSizeF(30, 30)); - TestDropTarget rightTarget(&outerTarget); - rightTarget.setPos(QPointF(70, 35)); - rightTarget.setSize(QSizeF(30, 30)); - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property bool dragActive: Drag.active\n" - "property Item dragTarget: Drag.target\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&outerTarget); - - evaluate(item, "Drag.active = true"); - QCOMPARE(evaluate(item, "Drag.active"), true); - QCOMPARE(evaluate(item, "dragActive"), true); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(50)); QCOMPARE(outerTarget.position.y(), qreal(50)); - - // Move within the outer target. - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(60, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); - - // Move into the right target. - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(75, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&rightTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&rightTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(75)); QCOMPARE(outerTarget.position.y(), qreal(50)); - QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15)); - - // Move into the left target. - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(25, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&leftTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&leftTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 1); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 1); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); - QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(15)); - - // Move within the left target. - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(25, 40)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&leftTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&leftTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 1); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(40)); - QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5)); - - // Move out of all targets. - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(110, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 1); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - - // Stop the right target accepting drag events and move into it. - rightTarget.accept = false; - - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(80, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(80)); QCOMPARE(outerTarget.position.y(), qreal(50)); - - // Stop the outer target accepting drag events after it has accepted an enter event. - outerTarget.accept = false; - - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(60, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); - - // Clear the QQuickItem::ItemAcceptsDrops flag from the outer target after it accepted an enter event. - outerTarget.setFlags(QQuickItem::Flags()); - - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(40, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(40)); QCOMPARE(outerTarget.position.y(), qreal(50)); - - // Clear the QQuickItem::ItemAcceptsDrops flag from the left target before it accepts an enter event. - leftTarget.setFlags(QQuickItem::Flags()); - - outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); - item->setPos(QPointF(25, 50)); - QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); - QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); - QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); - QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); - QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); - QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); -} - - -void tst_QQuickDrag::hotSpot() -{ - QQuickCanvas canvas; - TestDropTarget dropTarget(canvas.rootItem()); - dropTarget.setSize(QSizeF(100, 100)); - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property real hotSpotX: Drag.hotSpot.x\n" - "property real hotSpotY: Drag.hotSpot.y\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&dropTarget); - - QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(0)); - QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(0)); - QCOMPARE(evaluate(item, "hotSpotX"), qreal(0)); - QCOMPARE(evaluate(item, "hotSpotY"), qreal(0)); - - evaluate(item, "{ Drag.start(); Drag.cancel() }"); - QCOMPARE(dropTarget.position.x(), qreal(50)); - QCOMPARE(dropTarget.position.y(), qreal(50)); - - evaluate(item, "{ Drag.hotSpot.x = 5, Drag.hotSpot.y = 5 }"); - QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(5)); - QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(5)); - QCOMPARE(evaluate(item, "hotSpotX"), qreal(5)); - QCOMPARE(evaluate(item, "hotSpotY"), qreal(5)); - - evaluate(item, "Drag.start()"); - QCOMPARE(dropTarget.position.x(), qreal(55)); - QCOMPARE(dropTarget.position.y(), qreal(55)); - - item->setPos(QPointF(30, 20)); - QCOMPARE(dropTarget.position.x(), qreal(35)); - QCOMPARE(dropTarget.position.y(), qreal(25)); - - evaluate(item, "{ Drag.hotSpot.x = 10; Drag.hotSpot.y = 10 }"); - QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(10)); - QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(10)); - QCOMPARE(evaluate(item, "hotSpotX"), qreal(10)); - QCOMPARE(evaluate(item, "hotSpotY"), qreal(10)); - // Changing the hotSpot won't generate a move event so the position is unchanged. Should it? - QCOMPARE(dropTarget.position.x(), qreal(35)); - QCOMPARE(dropTarget.position.y(), qreal(25)); - - item->setPos(QPointF(10, 20)); - QCOMPARE(dropTarget.position.x(), qreal(20)); - QCOMPARE(dropTarget.position.y(), qreal(30)); -} - -void tst_QQuickDrag::supportedActions() -{ - QQuickCanvas canvas; - TestDropTarget dropTarget(canvas.rootItem()); - dropTarget.setSize(QSizeF(100, 100)); - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property int supportedActions: Drag.supportedActions\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&dropTarget); - - QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); - QCOMPARE(evaluate(item, "supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); - evaluate(item, "{ Drag.start(); Drag.cancel() }"); - QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction | Qt::LinkAction); - - evaluate(item, "Drag.supportedActions = Qt.CopyAction | Qt.MoveAction"); - QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "supportedActions == Qt.CopyAction | Qt.MoveAction"), true); - evaluate(item, "Drag.start()"); - QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); - - // Once a drag is started the proposed actions are locked in for future events. - evaluate(item, "Drag.supportedActions = Qt.MoveAction"); - QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); - item->setPos(QPointF(60, 60)); - QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); - - // Calling start with proposed actions will override the current actions for the next sequence. - evaluate(item, "Drag.start(Qt.CopyAction)"); - QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); - QCOMPARE(dropTarget.supportedActions, Qt::CopyAction); - - evaluate(item, "Drag.start()"); - QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); - QCOMPARE(dropTarget.supportedActions, Qt::MoveAction); -} - -void tst_QQuickDrag::proposedAction() -{ - QQuickCanvas canvas; - TestDropTarget dropTarget(canvas.rootItem()); - dropTarget.setSize(QSizeF(100, 100)); - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property int proposedAction: Drag.proposedAction\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - item->setParentItem(&dropTarget); - - - QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "proposedAction == Qt.MoveAction"), true); - evaluate(item, "{ Drag.start(); Drag.cancel() }"); - QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); - QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); - - evaluate(item, "Drag.proposedAction = Qt.CopyAction"); - QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.CopyAction"), true); - QCOMPARE(evaluate(item, "proposedAction == Qt.CopyAction"), true); - evaluate(item, "Drag.start()"); - QCOMPARE(dropTarget.defaultAction, Qt::CopyAction); - QCOMPARE(dropTarget.proposedAction, Qt::CopyAction); - - // The proposed action can change during a drag. - evaluate(item, "Drag.proposedAction = Qt.MoveAction"); - QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.MoveAction"), true); - QCOMPARE(evaluate(item, "proposedAction == Qt.MoveAction"), true); - item->setPos(QPointF(60, 60)); - QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); - QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); - - evaluate(item, "Drag.proposedAction = Qt.LinkAction"); - QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.LinkAction"), true); - QCOMPARE(evaluate(item, "proposedAction == Qt.LinkAction"), true); - evaluate(item, "Drag.drop()"); - QCOMPARE(dropTarget.defaultAction, Qt::LinkAction); - QCOMPARE(dropTarget.proposedAction, Qt::LinkAction); -} - -void tst_QQuickDrag::keys() -{ - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property variant keys: Drag.keys\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - -// QCOMPARE(evaluate(item, "Drag.keys"), QStringList()); -// QCOMPARE(evaluate(item, "keys"), QStringList()); - QCOMPARE(item->property("keys").toStringList(), QStringList()); - - evaluate(item, "Drag.keys = [\"red\", \"blue\"]"); -// QCOMPARE(evaluate(item, "Drag.keys"), QStringList() << "red" << "blue"); -// QCOMPARE(evaluate(item, "keys"), QStringList() << "red" << "blue"); - QCOMPARE(item->property("keys").toStringList(), QStringList() << "red" << "blue"); -} - -void tst_QQuickDrag::source() -{ - - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "Item {\n" - "property Item source: Drag.source\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "Item { id: proxySource; objectName: \"proxySource\" }\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *item = qobject_cast(object.data()); - QVERIFY(item); - - QCOMPARE(evaluate(item, "Drag.source"), static_cast(item)); - QCOMPARE(evaluate(item, "source"), static_cast(item)); - - QQuickItem *proxySource = item->findChild("proxySource"); - QVERIFY(proxySource); - - evaluate(item, "Drag.source = proxySource"); - QCOMPARE(evaluate(item, "Drag.source"), static_cast(proxySource)); - QCOMPARE(evaluate(item, "source"), static_cast(proxySource)); - - evaluate(item, "Drag.source = undefined"); - QCOMPARE(evaluate(item, "Drag.source"), static_cast(item)); - QCOMPARE(evaluate(item, "source"), static_cast(item)); -} - -QTEST_MAIN(tst_QQuickDrag) - -#include "tst_qquickdrag.moc" diff --git a/tests/auto/declarative/qquickdroparea/qquickdroparea.pro b/tests/auto/declarative/qquickdroparea/qquickdroparea.pro deleted file mode 100644 index eff08a2e94..0000000000 --- a/tests/auto/declarative/qquickdroparea/qquickdroparea.pro +++ /dev/null @@ -1,9 +0,0 @@ -TARGET = tst_qquickdroparea -CONFIG += testcase -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickdroparea.cpp - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp deleted file mode 100644 index 0147536abf..0000000000 --- a/tests/auto/declarative/qquickdroparea/tst_qquickdroparea.cpp +++ /dev/null @@ -1,1117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -#include - -template static T evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - QVariant result = expr.evaluate(); - if (expr.hasError()) - qWarning() << expr.error().toString(); - return result.value(); -} - -template <> void evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - expr.evaluate(); - if (expr.hasError()) - qWarning() << expr.error().toString(); -} - -class tst_QQuickDropArea: public QObject -{ - Q_OBJECT -private slots: - void initTestCase(); - void cleanupTestCase(); - - void containsDrag_internal(); - void containsDrag_external(); - void keys_internal(); - void keys_external(); - void source_internal(); -// void source_external(); - void position_internal(); - void position_external(); - void drop_internal(); -// void drop_external(); - void simultaneousDrags(); - -private: - QDeclarativeEngine engine; -}; - -void tst_QQuickDropArea::initTestCase() -{ - -} - -void tst_QQuickDropArea::cleanupTestCase() -{ - -} - -void tst_QQuickDropArea::containsDrag_internal() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property bool hasDrag: containsDrag\n" - "property int enterEvents: 0\n" - "property int exitEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents}\n" - "onExited: {++exitEvents}\n" - "Item {\n" - "objectName: \"dragItem\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QQuickItem *dragItem = dropArea->findChild("dragItem"); - QVERIFY(dragItem); - - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "hasDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem, "Drag.active = false"); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 1); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - - dragItem->setPos(QPointF(150, 50)); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - dragItem->setPos(QPointF(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "hasDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - dragItem->setPos(QPointF(150, 50)); - - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 1); - - evaluate(dragItem, "Drag.active = false"); -} - -void tst_QQuickDropArea::containsDrag_external() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property bool hasDrag: containsDrag\n" - "property int enterEvents: 0\n" - "property int exitEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents}\n" - "onExited: {++exitEvents}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QMimeData data; - QQuickCanvas alternateCanvas; - - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "hasDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 1); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "hasDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "exitEvents"), 0); - - evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "hasDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "exitEvents"), 1); - - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50)); -} - -void tst_QQuickDropArea::keys_internal() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property variant dragKeys\n" - "property variant dropKeys: keys\n" - "property int enterEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents; dragKeys = drag.keys }\n" - "Item {\n" - "objectName: \"dragItem\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "Drag.keys: [\"red\", \"blue\"]\n" - "}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QQuickItem *dragItem = dropArea->findChild("dragItem"); - QVERIFY(dragItem); - - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = \"blue\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "blue"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "blue"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = \"red\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = \"green\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "green"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "green"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = [\"red\", \"green\"]"); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red" << "green"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red" << "green"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dragItem, "Drag.keys = []"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = []"); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dropArea, "keys = []"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); - - evaluate(dragItem, "Drag.active = false"); - evaluate(dragItem, "Drag.keys = [\"red\", \"blue\"]"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); -} - -void tst_QQuickDropArea::keys_external() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property variant dragKeys\n" - "property variant dropKeys: keys\n" - "property int enterEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents; dragKeys = drag.keys }\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - dropArea->setParentItem(canvas.rootItem()); - - QMimeData data; - QQuickCanvas alternateCanvas; - - data.setData("text/x-red", "red"); - data.setData("text/x-blue", "blue"); - - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - evaluate(dropArea, "keys = \"text/x-blue\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - evaluate(dropArea, "keys = \"text/x-red\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - evaluate(dropArea, "keys = \"text/x-green\""); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - evaluate(dropArea, "keys = [\"text/x-red\", \"text/x-green\"]"); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - data.removeFormat("text/x-red"); - data.removeFormat("text/x-blue"); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), false); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - evaluate(dropArea, "keys = []"); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - data.setData("text/x-red", "red"); - data.setData("text/x-blue", "blue"); - QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); - QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); - evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "containsDrag"), true); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); - - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50)); -} - -void tst_QQuickDropArea::source_internal() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property Item source: drag.source\n" - "property Item eventSource\n" - "width: 100; height: 100\n" - "onEntered: {eventSource = drag.source}\n" - "Item {\n" - "objectName: \"dragItem\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}\n" - "Item { id: dragSource; objectName: \"dragSource\" }\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QQuickItem *dragItem = dropArea->findChild("dragItem"); - QVERIFY(dragItem); - - QQuickItem *dragSource = dropArea->findChild("dragSource"); - QVERIFY(dragSource); - - QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); - QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "source"), static_cast(dragItem)); - QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(dragItem)); - QCOMPARE(evaluate(dropArea, "eventSource"), static_cast(dragItem)); - - evaluate(dragItem, "Drag.active = false"); - QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); - QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); - - - evaluate(dropArea, "{ eventSource = null }"); - evaluate(dragItem, "Drag.source = dragSource"); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "source"), static_cast(dragSource)); - QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(dragSource)); - QCOMPARE(evaluate(dropArea, "eventSource"), static_cast(dragSource)); - - evaluate(dragItem, "Drag.active = false"); - QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); - QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); -} - -// Setting a source can't be emulated using the QWindowSystemInterface API. - -//void tst_QQuickDropArea::source_external() -//{ -//} - -void tst_QQuickDropArea::position_internal() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property real dragX: drag.x\n" - "property real dragY: drag.y\n" - "property real eventX\n" - "property real eventY\n" - "property int enterEvents: 0\n" - "property int moveEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" - "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" - "Item {\n" - "objectName: \"dragItem\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QQuickItem *dragItem = dropArea->findChild("dragItem"); - QVERIFY(dragItem); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "moveEvents"), 0); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(50)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); - - evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - dragItem->setPos(QPointF(40, 50)); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "moveEvents"), 1); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(40)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(40)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(40)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); - - evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - dragItem->setPos(QPointF(75, 25)); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "moveEvents"), 1); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(75)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(25)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(75)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(25)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(75)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(25)); - - evaluate(dragItem, "Drag.active = false"); -} - -void tst_QQuickDropArea::position_external() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property real dragX: drag.x\n" - "property real dragY: drag.y\n" - "property real eventX\n" - "property real eventY\n" - "property int enterEvents: 0\n" - "property int moveEvents: 0\n" - "width: 100; height: 100\n" - "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" - "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QMimeData data; - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea, "moveEvents"), 1); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(50)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); - - evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50)); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "moveEvents"), 1); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(40)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(40)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(40)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); - - evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25)); - QCOMPARE(evaluate(dropArea, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea, "moveEvents"), 1); - QCOMPARE(evaluate(dropArea, "drag.x"), qreal(75)); - QCOMPARE(evaluate(dropArea, "drag.y"), qreal(25)); - QCOMPARE(evaluate(dropArea, "dragX"), qreal(75)); - QCOMPARE(evaluate(dropArea, "dragY"), qreal(25)); - QCOMPARE(evaluate(dropArea, "eventX"), qreal(75)); - QCOMPARE(evaluate(dropArea, "eventY"), qreal(25)); - - QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25)); -} - -void tst_QQuickDropArea::drop_internal() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property bool accept: false\n" - "property bool setAccepted: false\n" - "property bool acceptDropAction: false\n" - "property bool setDropAction: false\n" - "property int dropAction: Qt.IgnoreAction\n" - "property int proposedAction: Qt.IgnoreAction\n" - "property int supportedActions: Qt.IgnoreAction\n" - "property int dropEvents: 0\n" - "width: 100; height: 100\n" - "onDropped: {\n" - "++dropEvents\n" - "supportedActions = drop.supportedActions\n" - "proposedAction = drop.action\n" - "if (setDropAction)\n" - "drop.action = dropAction\n" - "if (acceptDropAction)\n" - "drop.accept(dropAction)\n" - "else if (setAccepted)\n" - "drop.accepted = accept\n" - "else if (accept)\n" - "drop.accept()\n" - "}\n" - "Item {\n" - "objectName: \"dragItem\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "}\n" - "}", QUrl()); - QScopedPointer object(component.create()); - QQuickItem *dropArea = qobject_cast(object.data()); - QVERIFY(dropArea); - dropArea->setParentItem(canvas.rootItem()); - - QQuickItem *dragItem = dropArea->findChild("dragItem"); - QVERIFY(dragItem); - - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ accept = true; setDropAction = true; dropAction = Qt.LinkAction }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = true; }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ accept = false; setAccepted = true; }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = false; setDropAction = false; acceptDropAction = true; }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ acceptDropAction = false; dropAction = Qt.IgnoreAction; accept = true }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = true }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = false }"); - evaluate(dragItem, "Drag.supportedActions = Qt.LinkAction"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = true }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = false }"); - evaluate(dragItem, "Drag.proposedAction = Qt.LinkAction"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::LinkAction)); - - evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); - evaluate(dropArea, "{ setAccepted = true }"); - evaluate(dragItem, "Drag.active = true"); - QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "dropEvents"), 1); - QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); - QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::LinkAction)); -} - -// Setting the supportedActions can't be emulated using the QWindowSystemInterface API. - -//void tst_QQuickDropArea::drop_external() -//{ -//} - -void tst_QQuickDropArea::simultaneousDrags() -{ - QQuickCanvas canvas; - QDeclarativeComponent component(&engine); - component.setData( - "import QtQuick 2.0\n" - "DropArea {\n" - "property int enterEvents: 0\n" - "property int exitEvents: 0\n" - "width: 100; height: 100\n" - "keys: [\"red\", \"text/x-red\"]\n" - "onEntered: {++enterEvents}\n" - "onExited: {++exitEvents}\n" - "DropArea {\n" - "objectName: \"dropArea2\"\n" - "property int enterEvents: 0\n" - "property int exitEvents: 0\n" - "width: 100; height: 100\n" - "keys: [\"blue\", \"text/x-blue\"]\n" - "onEntered: {++enterEvents}\n" - "onExited: {++exitEvents}\n" - "}\n" - "Item {\n" - "objectName: \"dragItem1\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "Drag.keys: [\"red\", \"blue\"]" - "}\n" - "Item {\n" - "objectName: \"dragItem2\"\n" - "x: 50; y: 50\n" - "width: 10; height: 10\n" - "Drag.keys: [\"red\", \"blue\"]" - "}\n" - "}", QUrl()); - - QScopedPointer object(component.create()); - QQuickItem *dropArea1 = qobject_cast(object.data()); - QVERIFY(dropArea1); - dropArea1->setParentItem(canvas.rootItem()); - - QQuickItem *dropArea2 = dropArea1->findChild("dropArea2"); - QVERIFY(dropArea2); - - QQuickItem *dragItem1 = dropArea1->findChild("dragItem1"); - QVERIFY(dragItem1); - - QQuickItem *dragItem2 = dropArea1->findChild("dragItem2"); - QVERIFY(dragItem2); - - QMimeData data; - data.setData("text/x-red", "red"); - data.setData("text/x-blue", "blue"); - - QQuickCanvas alternateCanvas; - - // Mixed internal drags. - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem1, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - // internal then external. - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem1, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - // external then internal. - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - // Different acceptance - evaluate(dragItem1, "Drag.keys = \"red\""); - evaluate(dragItem2, "Drag.keys = \"blue\""); - data.removeFormat("text/x-red"); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem2, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - // internal then external - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = true"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), true); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dragItem1, "Drag.active = false"); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); - QCOMPARE(evaluate(dropArea2, "containsDrag"), true); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); - - evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); - evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); - QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); - QCOMPARE(evaluate(dropArea1, "containsDrag"), false); - QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); - QCOMPARE(evaluate(dropArea2, "containsDrag"), false); - QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); - QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); - - QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50)); -} - -QTEST_MAIN(tst_QQuickDropArea) - -#include "tst_qquickdroparea.moc" diff --git a/tests/auto/declarative/qquickflickable/data/disabled.qml b/tests/auto/declarative/qquickflickable/data/disabled.qml deleted file mode 100644 index 9b679827c7..0000000000 --- a/tests/auto/declarative/qquickflickable/data/disabled.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 100; height: 100 - property bool clicked: false - - Flickable { - objectName: "flickable" - width: 100; height: 100 - contentWidth: column.width; contentHeight: column.height - enabled: false - - Column { - id: column - Repeater { - model: 4 - Rectangle { - width: 200; height: 300; color: "blue" - MouseArea { anchors.fill: parent; onClicked: { } } - } - } - } - } - - MouseArea { - width: 100; height: 30 - onClicked: root.clicked = true - } -} diff --git a/tests/auto/declarative/qquickflickable/data/flickable01.qml b/tests/auto/declarative/qquickflickable/data/flickable01.qml deleted file mode 100644 index cbec44bb4f..0000000000 --- a/tests/auto/declarative/qquickflickable/data/flickable01.qml +++ /dev/null @@ -1,4 +0,0 @@ -import QtQuick 2.0 - -Flickable { -} diff --git a/tests/auto/declarative/qquickflickable/data/flickable02.qml b/tests/auto/declarative/qquickflickable/data/flickable02.qml deleted file mode 100644 index 80caa32da5..0000000000 --- a/tests/auto/declarative/qquickflickable/data/flickable02.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Flickable { - width: 100; height: 100 - contentWidth: row.width; contentHeight: row.height - - Row { - id: row - Repeater { - model: 4 - Rectangle { width: 200; height: 300; color: "blue" } - } - } -} diff --git a/tests/auto/declarative/qquickflickable/data/flickable03.qml b/tests/auto/declarative/qquickflickable/data/flickable03.qml deleted file mode 100644 index ebc49ba90a..0000000000 --- a/tests/auto/declarative/qquickflickable/data/flickable03.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Flickable { - width: 100; height: 200 - contentWidth: column.width; contentHeight: column.height - - Column { - id: column - Repeater { - model: 4 - Rectangle { width: 200; height: 300; color: "blue" } - } - } -} diff --git a/tests/auto/declarative/qquickflickable/data/flickable04.qml b/tests/auto/declarative/qquickflickable/data/flickable04.qml deleted file mode 100644 index b2f30b84ec..0000000000 --- a/tests/auto/declarative/qquickflickable/data/flickable04.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Flickable { - property bool ok: false - function check() { - if (column.parent == contentItem) - ok = true; - } - - width: 100; height: 100 - contentWidth: column.width; contentHeight: column.height - pressDelay: 200; boundsBehavior: Flickable.StopAtBounds; interactive: false - maximumFlickVelocity: 2000 - - Column { - id: column - Repeater { - model: 4 - Rectangle { width: 200; height: 300; color: "blue" } - } - } -} diff --git a/tests/auto/declarative/qquickflickable/data/flickableqgraphicswidget.qml b/tests/auto/declarative/qquickflickable/data/flickableqgraphicswidget.qml deleted file mode 100644 index bb8f1eefc6..0000000000 --- a/tests/auto/declarative/qquickflickable/data/flickableqgraphicswidget.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Flickable { - width: 100; height: 100 - - QGraphicsWidget { objectName: "widget1"; width: 200; height: 300 } -} diff --git a/tests/auto/declarative/qquickflickable/data/margins.qml b/tests/auto/declarative/qquickflickable/data/margins.qml deleted file mode 100644 index 4866bd8301..0000000000 --- a/tests/auto/declarative/qquickflickable/data/margins.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Flickable { - width: 200; height: 200 - contentWidth: row.width; contentHeight: row.height - - topMargin: 20 - bottomMargin: 30 - leftMargin: 40 - rightMargin: 50 - - Row { - id: row - Repeater { - model: 4 - Rectangle { width: 400; height: 600; color: "blue" } - } - } -} diff --git a/tests/auto/declarative/qquickflickable/data/nestedPressDelay.qml b/tests/auto/declarative/qquickflickable/data/nestedPressDelay.qml deleted file mode 100644 index 60dadcc73c..0000000000 --- a/tests/auto/declarative/qquickflickable/data/nestedPressDelay.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.0 - -Flickable { - property bool pressed: ma.pressed - width: 240 - height: 320 - contentWidth: 480 - contentHeight: 320 - flickableDirection: Flickable.HorizontalFlick - pressDelay: 50 - Flickable { - objectName: "innerFlickable" - flickableDirection: Flickable.VerticalFlick - width: 480 - height: 320 - contentWidth: 480 - contentHeight: 400 - pressDelay: 10000 - Rectangle { - y: 100 - anchors.horizontalCenter: parent.horizontalCenter - width: 240 - height: 100 - color: ma.pressed ? 'blue' : 'green' - MouseArea { - id: ma - objectName: "mouseArea" - anchors.fill: parent - } - } - } -} - diff --git a/tests/auto/declarative/qquickflickable/data/resize.qml b/tests/auto/declarative/qquickflickable/data/resize.qml deleted file mode 100644 index 1a9ef54107..0000000000 --- a/tests/auto/declarative/qquickflickable/data/resize.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - function resizeContent() { - flick.resizeContent(600, 600, Qt.point(100, 100)) - } - function returnToBounds() { - flick.returnToBounds() - } - width: 400 - height: 360 - color: "gray" - - Flickable { - id: flick - objectName: "flick" - anchors.fill: parent - contentWidth: 300 - contentHeight: 300 - - Rectangle { - width: flick.contentWidth - height: flick.contentHeight - color: "red" - } - } -} diff --git a/tests/auto/declarative/qquickflickable/data/wheel.qml b/tests/auto/declarative/qquickflickable/data/wheel.qml deleted file mode 100644 index 2928bbcd72..0000000000 --- a/tests/auto/declarative/qquickflickable/data/wheel.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - color: "gray" - - Flickable { - id: flick - objectName: "flick" - anchors.fill: parent - contentWidth: 800 - contentHeight: 800 - - Rectangle { - width: flick.contentWidth - height: flick.contentHeight - color: "red" - Rectangle { - width: 50; height: 50; color: "blue" - anchors.centerIn: parent - } - } - } -} diff --git a/tests/auto/declarative/qquickflickable/qquickflickable.pro b/tests/auto/declarative/qquickflickable/qquickflickable.pro deleted file mode 100644 index ba951cc051..0000000000 --- a/tests/auto/declarative/qquickflickable/qquickflickable.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickflickable -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickflickable.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private testlib diff --git a/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp b/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp deleted file mode 100644 index a02db06616..0000000000 --- a/tests/auto/declarative/qquickflickable/tst_qquickflickable.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include - -class tst_qquickflickable : public QObject -{ - Q_OBJECT -public: - tst_qquickflickable(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void create(); - void horizontalViewportSize(); - void verticalViewportSize(); - void properties(); - void boundsBehavior(); - void maximumFlickVelocity(); - void flickDeceleration(); - void pressDelay(); - void nestedPressDelay(); - void flickableDirection(); - void resizeContent(); - void returnToBounds(); - void wheel(); - void movingAndDragging(); - void disabled(); - void flickVelocity(); - void margins(); - -private: - QDeclarativeEngine engine; - - void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); - template - T *findItem(QQuickItem *parent, const QString &objectName); -}; - -tst_qquickflickable::tst_qquickflickable() -{ -} - -void tst_qquickflickable::initTestCase() -{ - -} - -void tst_qquickflickable::cleanupTestCase() -{ - -} - -void tst_qquickflickable::create() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable01.qml"))); - QQuickFlickable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QCOMPARE(obj->isAtXBeginning(), true); - QCOMPARE(obj->isAtXEnd(), false); - QCOMPARE(obj->isAtYBeginning(), true); - QCOMPARE(obj->isAtYEnd(), false); - QCOMPARE(obj->contentX(), 0.); - QCOMPARE(obj->contentY(), 0.); - - QCOMPARE(obj->horizontalVelocity(), 0.); - QCOMPARE(obj->verticalVelocity(), 0.); - - QCOMPARE(obj->isInteractive(), true); - QCOMPARE(obj->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds); - QCOMPARE(obj->pressDelay(), 0); - QCOMPARE(obj->maximumFlickVelocity(), 2500.); - - delete obj; -} - -void tst_qquickflickable::horizontalViewportSize() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable02.qml"))); - QQuickFlickable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QCOMPARE(obj->contentWidth(), 800.); - QCOMPARE(obj->contentHeight(), 300.); - QCOMPARE(obj->isAtXBeginning(), true); - QCOMPARE(obj->isAtXEnd(), false); - QCOMPARE(obj->isAtYBeginning(), true); - QCOMPARE(obj->isAtYEnd(), false); - - delete obj; -} - -void tst_qquickflickable::verticalViewportSize() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); - QQuickFlickable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QCOMPARE(obj->contentWidth(), 200.); - QCOMPARE(obj->contentHeight(), 1200.); - QCOMPARE(obj->isAtXBeginning(), true); - QCOMPARE(obj->isAtXEnd(), false); - QCOMPARE(obj->isAtYBeginning(), true); - QCOMPARE(obj->isAtYEnd(), false); - - delete obj; -} - -void tst_qquickflickable::properties() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable04.qml"))); - QQuickFlickable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QCOMPARE(obj->isInteractive(), false); - QCOMPARE(obj->boundsBehavior(), QQuickFlickable::StopAtBounds); - QCOMPARE(obj->pressDelay(), 200); - QCOMPARE(obj->maximumFlickVelocity(), 2000.); - - QVERIFY(obj->property("ok").toBool() == false); - QMetaObject::invokeMethod(obj, "check"); - QVERIFY(obj->property("ok").toBool() == true); - - delete obj; -} - -void tst_qquickflickable::boundsBehavior() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile("")); - QQuickFlickable *flickable = qobject_cast(component.create()); - QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged())); - - QVERIFY(flickable); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); - - flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds); - QCOMPARE(spy.count(),1); - flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); - QCOMPARE(spy.count(),1); - - flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds); - QCOMPARE(spy.count(),2); - flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); - QCOMPARE(spy.count(),2); - - flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); - QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); - QCOMPARE(spy.count(),3); - flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); - QCOMPARE(spy.count(),3); -} - -void tst_qquickflickable::maximumFlickVelocity() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile("")); - QQuickFlickable *flickable = qobject_cast(component.create()); - QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged())); - - QVERIFY(flickable); - QCOMPARE(flickable->maximumFlickVelocity(), 1.0); - - flickable->setMaximumFlickVelocity(2.0); - QCOMPARE(flickable->maximumFlickVelocity(), 2.0); - QCOMPARE(spy.count(),1); - flickable->setMaximumFlickVelocity(2.0); - QCOMPARE(spy.count(),1); -} - -void tst_qquickflickable::flickDeceleration() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile("")); - QQuickFlickable *flickable = qobject_cast(component.create()); - QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged())); - - QVERIFY(flickable); - QCOMPARE(flickable->flickDeceleration(), 1.0); - - flickable->setFlickDeceleration(2.0); - QCOMPARE(flickable->flickDeceleration(), 2.0); - QCOMPARE(spy.count(),1); - flickable->setFlickDeceleration(2.0); - QCOMPARE(spy.count(),1); -} - -void tst_qquickflickable::pressDelay() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile("")); - QQuickFlickable *flickable = qobject_cast(component.create()); - QSignalSpy spy(flickable, SIGNAL(pressDelayChanged())); - - QVERIFY(flickable); - QCOMPARE(flickable->pressDelay(), 100); - - flickable->setPressDelay(200); - QCOMPARE(flickable->pressDelay(), 200); - QCOMPARE(spy.count(),1); - flickable->setPressDelay(200); - QCOMPARE(spy.count(),1); -} - -// QTBUG-17361 -void tst_qquickflickable::nestedPressDelay() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("nestedPressDelay.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *outer = qobject_cast(canvas->rootObject()); - QVERIFY(outer != 0); - - QQuickFlickable *inner = canvas->rootObject()->findChild("innerFlickable"); - QVERIFY(inner != 0); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(150, 150)); - // the MouseArea is not pressed immediately - QVERIFY(outer->property("pressed").toBool() == false); - - // The outer pressDelay will prevail (50ms, vs. 10sec) - // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec. - QTRY_VERIFY(outer->property("pressed").toBool() == true); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(150, 150)); - - delete canvas; -} - -void tst_qquickflickable::flickableDirection() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile("")); - QQuickFlickable *flickable = qobject_cast(component.create()); - QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged())); - - QVERIFY(flickable); - QCOMPARE(flickable->flickableDirection(), QQuickFlickable::VerticalFlick); - - flickable->setFlickableDirection(QQuickFlickable::HorizontalAndVerticalFlick); - QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalAndVerticalFlick); - QCOMPARE(spy.count(),1); - - flickable->setFlickableDirection(QQuickFlickable::AutoFlickDirection); - QCOMPARE(flickable->flickableDirection(), QQuickFlickable::AutoFlickDirection); - QCOMPARE(spy.count(),2); - - flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick); - QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick); - QCOMPARE(spy.count(),3); - - flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick); - QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick); - QCOMPARE(spy.count(),3); -} - -// QtQuick 1.1 -void tst_qquickflickable::resizeContent() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml"))); - QQuickItem *root = qobject_cast(c.create()); - QQuickFlickable *obj = findItem(root, "flick"); - - QVERIFY(obj != 0); - QCOMPARE(obj->contentX(), 0.); - QCOMPARE(obj->contentY(), 0.); - QCOMPARE(obj->contentWidth(), 300.); - QCOMPARE(obj->contentHeight(), 300.); - - QMetaObject::invokeMethod(root, "resizeContent"); - - QCOMPARE(obj->contentX(), 100.); - QCOMPARE(obj->contentY(), 100.); - QCOMPARE(obj->contentWidth(), 600.); - QCOMPARE(obj->contentHeight(), 600.); - - delete root; -} - -// QtQuick 1.1 -void tst_qquickflickable::returnToBounds() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml"))); - QQuickItem *root = qobject_cast(c.create()); - QQuickFlickable *obj = findItem(root, "flick"); - - QVERIFY(obj != 0); - QCOMPARE(obj->contentX(), 0.); - QCOMPARE(obj->contentY(), 0.); - QCOMPARE(obj->contentWidth(), 300.); - QCOMPARE(obj->contentHeight(), 300.); - - obj->setContentX(100); - obj->setContentY(400); - QTRY_COMPARE(obj->contentX(), 100.); - QTRY_COMPARE(obj->contentY(), 400.); - - QMetaObject::invokeMethod(root, "returnToBounds"); - - QTRY_COMPARE(obj->contentX(), 0.); - QTRY_COMPARE(obj->contentY(), 0.); - - delete root; -} - -void tst_qquickflickable::wheel() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("wheel.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flick = canvas->rootObject()->findChild("flick"); - QVERIFY(flick != 0); - - { - QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical); - event.setAccepted(false); - QApplication::sendEvent(canvas, &event); - } - - QTRY_VERIFY(flick->contentY() > 0); - QVERIFY(flick->contentX() == 0); - - flick->setContentY(0); - QVERIFY(flick->contentY() == 0); - - { - QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Horizontal); - event.setAccepted(false); - QApplication::sendEvent(canvas, &event); - } - - QTRY_VERIFY(flick->contentX() > 0); - QVERIFY(flick->contentY() == 0); - - delete canvas; -} - -void tst_qquickflickable::movingAndDragging() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); - QVERIFY(flickable != 0); - - QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged())); - QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged())); - QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged())); - QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged())); - QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged())); - QSignalSpy moveSpy(flickable, SIGNAL(movingChanged())); - QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted())); - QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded())); - - //Vertical - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90)); - - QTest::mouseMove(canvas, QPoint(50, 80)); - QTest::mouseMove(canvas, QPoint(50, 70)); - QTest::mouseMove(canvas, QPoint(50, 60)); - - QMouseEvent moveEvent(QEvent::MouseMove, QPoint(50, 80), Qt::LeftButton, Qt::LeftButton, 0); - - QVERIFY(!flickable->isDraggingHorizontally()); - QVERIFY(flickable->isDraggingVertically()); - QVERIFY(flickable->isDragging()); - QCOMPARE(vDragSpy.count(), 1); - QCOMPARE(dragSpy.count(), 1); - QCOMPARE(hDragSpy.count(), 0); - QCOMPARE(dragStartSpy.count(), 1); - QCOMPARE(dragEndSpy.count(), 0); - - QVERIFY(!flickable->isMovingHorizontally()); - QVERIFY(flickable->isMovingVertically()); - QVERIFY(flickable->isMoving()); - QCOMPARE(vMoveSpy.count(), 1); - QCOMPARE(moveSpy.count(), 1); - QCOMPARE(hMoveSpy.count(), 0); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60)); - - QTRY_VERIFY(!flickable->isDraggingVertically()); - QVERIFY(!flickable->isDragging()); - QCOMPARE(vDragSpy.count(), 2); - QCOMPARE(dragSpy.count(), 2); - QCOMPARE(hDragSpy.count(), 0); - QCOMPARE(dragStartSpy.count(), 1); - QCOMPARE(dragEndSpy.count(), 1); - - // wait for any motion to end - QTRY_VERIFY(flickable->isMoving() == false); - - //Horizontal - vDragSpy.clear(); - hDragSpy.clear(); - dragSpy.clear(); - vMoveSpy.clear(); - hMoveSpy.clear(); - moveSpy.clear(); - dragStartSpy.clear(); - dragEndSpy.clear(); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(90, 50)); - - QTest::mouseMove(canvas, QPoint(80, 50)); - QTest::mouseMove(canvas, QPoint(70, 50)); - QTest::mouseMove(canvas, QPoint(60, 50)); - - QVERIFY(flickable->isDraggingHorizontally()); - QVERIFY(flickable->isDragging()); - QCOMPARE(vDragSpy.count(), 0); - QCOMPARE(dragSpy.count(), 1); - QCOMPARE(hDragSpy.count(), 1); - QCOMPARE(dragStartSpy.count(), 1); - QCOMPARE(dragEndSpy.count(), 0); - - QVERIFY(!flickable->isMovingVertically()); - QVERIFY(flickable->isMovingHorizontally()); - QVERIFY(flickable->isMoving()); - QCOMPARE(vMoveSpy.count(), 0); - QCOMPARE(moveSpy.count(), 1); - QCOMPARE(hMoveSpy.count(), 1); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(60, 50)); - - QTRY_VERIFY(!flickable->isDraggingHorizontally()); - QVERIFY(!flickable->isDragging()); - QCOMPARE(vDragSpy.count(), 0); - QCOMPARE(dragSpy.count(), 2); - QCOMPARE(hDragSpy.count(), 2); - QCOMPARE(dragStartSpy.count(), 1); - QCOMPARE(dragEndSpy.count(), 1); - - // Don't test moving because a flick could occur - - delete canvas; -} - -void tst_qquickflickable::disabled() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("disabled.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flick = canvas->rootObject()->findChild("flickable"); - QVERIFY(flick != 0); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90)); - - QTest::mouseMove(canvas, QPoint(50, 80)); - QTest::mouseMove(canvas, QPoint(50, 70)); - QTest::mouseMove(canvas, QPoint(50, 60)); - - QVERIFY(flick->isMoving() == false); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60)); - - // verify that mouse clicks on other elements still work (QTBUG-20584) - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10)); - - QTRY_VERIFY(canvas->rootObject()->property("clicked").toBool() == true); -} - -void tst_qquickflickable::flickVelocity() -{ -#ifdef Q_OS_MAC - QSKIP("Producing flicks on Mac CI impossible due to timing problems"); -#endif - - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); - QVERIFY(flickable != 0); - - // flick up - flick(canvas, QPoint(20,190), QPoint(20, 50), 200); - QVERIFY(flickable->verticalVelocity() > 0.0); - QTRY_VERIFY(flickable->verticalVelocity() == 0.0); - - // flick down - flick(canvas, QPoint(20,10), QPoint(20, 140), 200); - QVERIFY(flickable->verticalVelocity() < 0.0); - QTRY_VERIFY(flickable->verticalVelocity() == 0.0); - - delete canvas; -} - -void tst_qquickflickable::margins() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("margins.qml"))); - QQuickItem *root = qobject_cast(c.create()); - QQuickFlickable *obj = qobject_cast(root); - QVERIFY(obj != 0); - - // starting state - QCOMPARE(obj->contentX(), -40.); - QCOMPARE(obj->contentY(), -20.); - QCOMPARE(obj->contentWidth(), 1600.); - QCOMPARE(obj->contentHeight(), 600.); - QCOMPARE(obj->xOrigin(), 0.); - QCOMPARE(obj->yOrigin(), 0.); - - // Reduce left margin - obj->setLeftMargin(30); - QTRY_COMPARE(obj->contentX(), -30.); - - // Reduce top margin - obj->setTopMargin(20); - QTRY_COMPARE(obj->contentY(), -20.); - - // position to the far right, including margin - obj->setContentX(1600 + 50 - obj->width()); - obj->returnToBounds(); - QTest::qWait(200); - QCOMPARE(obj->contentX(), 1600. + 50. - obj->width()); - - // position beyond the far right, including margin - obj->setContentX(1600 + 50 - obj->width() + 1.); - obj->returnToBounds(); - QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width()); - - // Reduce right margin - obj->setRightMargin(40); - QTRY_COMPARE(obj->contentX(), 1600. + 40. - obj->width()); - QCOMPARE(obj->contentWidth(), 1600.); - - // position to the far bottom, including margin - obj->setContentY(600 + 30 - obj->height()); - obj->returnToBounds(); - QTest::qWait(200); - QCOMPARE(obj->contentY(), 600. + 30. - obj->height()); - - // position beyond the far bottom, including margin - obj->setContentY(600 + 30 - obj->height() + 1.); - obj->returnToBounds(); - QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height()); - - // Reduce bottom margin - obj->setBottomMargin(20); - QTRY_COMPARE(obj->contentY(), 600. + 20. - obj->height()); - QCOMPARE(obj->contentHeight(), 600.); - - delete root; -} - -void tst_qquickflickable::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) -{ - const int pointCount = 5; - QPoint diff = to - from; - - // send press, five equally spaced moves, and release. - QTest::mousePress(canvas, Qt::LeftButton, 0, from); - - for (int i = 0; i < pointCount; ++i) { - QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - QTest::qWait(duration/pointCount); - QCoreApplication::processEvents(); - } - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); -} - -template -T *tst_qquickflickable::findItem(QQuickItem *parent, const QString &objectName) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - return static_cast(item); - } - item = findItem(item, objectName); - if (item) - return static_cast(item); - } - - return 0; -} - -QTEST_MAIN(tst_qquickflickable) - -#include "tst_qquickflickable.moc" diff --git a/tests/auto/declarative/qquickflipable/data/crash.qml b/tests/auto/declarative/qquickflipable/data/crash.qml deleted file mode 100644 index a0327918cb..0000000000 --- a/tests/auto/declarative/qquickflipable/data/crash.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Flipable { - transform: Rotation { - axis.y: 1 - axis.z: 0 - angle: 180 - } -} diff --git a/tests/auto/declarative/qquickflipable/data/flipable-abort.qml b/tests/auto/declarative/qquickflipable/data/flipable-abort.qml deleted file mode 100644 index 90fc03a5f9..0000000000 --- a/tests/auto/declarative/qquickflipable/data/flipable-abort.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - Flipable { - id: flipable - } - Rectangle { - visible: flipable.side == Flipable.Front - } -} diff --git a/tests/auto/declarative/qquickflipable/data/test-flipable.qml b/tests/auto/declarative/qquickflipable/data/test-flipable.qml deleted file mode 100644 index dff6d3fe39..0000000000 --- a/tests/auto/declarative/qquickflipable/data/test-flipable.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Flipable { - id: flipable - width: 640; height: 480 - - front: Rectangle { anchors.fill: flipable } - back: Rectangle { anchors.fill: flipable } -} diff --git a/tests/auto/declarative/qquickflipable/qquickflipable.pro b/tests/auto/declarative/qquickflipable/qquickflipable.pro deleted file mode 100644 index a36c468c1c..0000000000 --- a/tests/auto/declarative/qquickflipable/qquickflipable.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickflipable -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickflipable.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private testlib diff --git a/tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp b/tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp deleted file mode 100644 index 7243836031..0000000000 --- a/tests/auto/declarative/qquickflipable/tst_qquickflipable.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qquickflipable : public QObject -{ - Q_OBJECT -public: - tst_qquickflipable(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void create(); - void checkFrontAndBack(); - void setFrontAndBack(); - - // below here task issues - void QTBUG_9161_crash(); - void QTBUG_8474_qgv_abort(); - -private: - QDeclarativeEngine engine; -}; - -tst_qquickflipable::tst_qquickflipable() -{ -} -void tst_qquickflipable::initTestCase() -{ -} - -void tst_qquickflipable::cleanupTestCase() -{ - -} - -void tst_qquickflipable::create() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); - QQuickFlipable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - delete obj; -} - -void tst_qquickflipable::checkFrontAndBack() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); - QQuickFlipable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QVERIFY(obj->front() != 0); - QVERIFY(obj->back() != 0); - delete obj; -} - -void tst_qquickflipable::setFrontAndBack() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); - QQuickFlipable *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QVERIFY(obj->front() != 0); - QVERIFY(obj->back() != 0); - - QString message = c.url().toString() + ":3:1: QML Flipable: front is a write-once property"; - QTest::ignoreMessage(QtWarningMsg, qPrintable(message)); - obj->setFront(new QQuickRectangle()); - - message = c.url().toString() + ":3:1: QML Flipable: back is a write-once property"; - QTest::ignoreMessage(QtWarningMsg, qPrintable(message)); - obj->setBack(new QQuickRectangle()); - delete obj; -} - -void tst_qquickflipable::QTBUG_9161_crash() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("crash.qml"))); - QQuickItem *root = canvas->rootObject(); - QVERIFY(root != 0); - canvas->show(); - delete canvas; -} - -void tst_qquickflipable::QTBUG_8474_qgv_abort() -{ - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("flipable-abort.qml"))); - QQuickItem *root = canvas->rootObject(); - QVERIFY(root != 0); - canvas->show(); - delete canvas; -} - -QTEST_MAIN(tst_qquickflipable) - -#include "tst_qquickflipable.moc" diff --git a/tests/auto/declarative/qquickfocusscope/data/canvasFocus.qml b/tests/auto/declarative/qquickfocusscope/data/canvasFocus.qml deleted file mode 100644 index 7d8dac5a22..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/canvasFocus.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Column { - FocusScope { - objectName: "scope1" - width: 20 ;height: 20 - focus: true - Rectangle { - objectName: "item1" - anchors.fill: parent - focus: true - } - } - FocusScope { - objectName: "scope2" - width: 20 ;height: 20 - Rectangle { - objectName: "item2" - anchors.fill: parent - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/chain.qml b/tests/auto/declarative/qquickfocusscope/data/chain.qml deleted file mode 100644 index 4b96662318..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/chain.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width:300; height:400 - - property bool focus1: root.activeFocus - property bool focus2: item1.activeFocus - property bool focus3: fs1.activeFocus - property bool focus4: fs2.activeFocus - property bool focus5: theItem.activeFocus - - Item { - id: item1 - FocusScope { - id: fs1 - focus: true - FocusScope { - id: fs2 - focus: true - Item { - id: theItem - focus: true - } - } - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/forceActiveFocus.qml b/tests/auto/declarative/qquickfocusscope/data/forceActiveFocus.qml deleted file mode 100644 index 74d2106888..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/forceActiveFocus.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - objectName: "root" - FocusScope { - objectName: "scope" - Item { - objectName: "item-a1" - FocusScope { - objectName: "scope-a" - Item { - objectName: "item-a2" - } - } - } - Item { - objectName: "item-b1" - FocusScope { - objectName: "scope-b" - Item { - objectName: "item-b2" - } - } - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/forcefocus.qml b/tests/auto/declarative/qquickfocusscope/data/forcefocus.qml deleted file mode 100644 index f41582a951..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/forcefocus.qml +++ /dev/null @@ -1,81 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 800; height: 600 - - FocusScope { - focus: true - - FocusScope { - id: firstScope - objectName: "item0" - focus: true - - Rectangle { - height: 120; width: 420 - - color: "transparent" - border.width: 5; border.color: firstScope.activeFocus?"blue":"black" - - Rectangle { - id: item1; objectName: "item1" - x: 10; y: 10; width: 100; height: 100; color: "green" - border.width: 5; border.color: activeFocus?"blue":"black" - focus: true - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - - Rectangle { - id: item2; objectName: "item2" - x: 310; y: 10; width: 100; height: 100; color: "green" - border.width: 5; border.color: activeFocus?"blue":"black" - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - } - } - - FocusScope { - id: secondScope - objectName: "item3" - - Rectangle { - y: 160; height: 120; width: 420 - - color: "transparent" - border.width: 5; border.color: secondScope.activeFocus?"blue":"black" - - Rectangle { - id: item4; objectName: "item4" - x: 10; y: 10; width: 100; height: 100; color: "green" - border.width: 5; border.color: activeFocus?"blue":"black" - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - - Rectangle { - id: item5; objectName: "item5" - x: 310; y: 10; width: 100; height: 100; color: "green" - border.width: 5; border.color: activeFocus?"blue":"black" - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - } - } - } - Keys.onDigit4Pressed: item4.focus = true - Keys.onDigit5Pressed: item5.forceActiveFocus() -} diff --git a/tests/auto/declarative/qquickfocusscope/data/qtBug13380.qml b/tests/auto/declarative/qquickfocusscope/data/qtBug13380.qml deleted file mode 100644 index 29de046b38..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/qtBug13380.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - - property bool showRect: false - onShowRectChanged: if (showRect) rect.visible = true - property bool noFocus: !fs2.activeFocus - - FocusScope { - id: fs1 - focus: true - } - Rectangle { - id: rect - visible: false - FocusScope { - id: fs2 - Rectangle { - focus: true - } - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/signalEmission.qml b/tests/auto/declarative/qquickfocusscope/data/signalEmission.qml deleted file mode 100644 index 999a40c5ad..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/signalEmission.qml +++ /dev/null @@ -1,33 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 200 - - FocusScope { - focus: true - Rectangle { - objectName: "item1" - color: "blue" - onFocusChanged: focus ? color = "red" : color = "blue" - } - Rectangle { - objectName: "item2" - color: "blue" - onFocusChanged: focus ? color = "red" : color = "blue" - } - } - - FocusScope { - Rectangle { - objectName: "item3" - color: "blue" - onFocusChanged: focus ? color = "red" : color = "blue" - } - Rectangle { - objectName: "item4" - color: "blue" - onFocusChanged: focus ? color = "red" : color = "blue" - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/test.qml b/tests/auto/declarative/qquickfocusscope/data/test.qml deleted file mode 100644 index 67be29c3fb..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/test.qml +++ /dev/null @@ -1,77 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onDigit9Pressed: console.log("Error - Root") - - FocusScope { - id: myScope - objectName: "item0" - focus: true - - Keys.onDigit9Pressed: console.log("Error - FocusScope") - - Rectangle { - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.activeFocus?"blue":"black" - - Rectangle { - id: item1; objectName: "item1" - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - Keys.onDigit9Pressed: console.debug("Top Left"); - KeyNavigation.right: item2 - focus: true - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - - Rectangle { - id: item2; objectName: "item2" - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onDigit9Pressed: console.log("Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" } - - Rectangle { - id: item3; objectName: "item3" - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - - Keys.onDigit9Pressed: console.log("Bottom Left"); - KeyNavigation.up: myScope - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - -} diff --git a/tests/auto/declarative/qquickfocusscope/data/test2.qml b/tests/auto/declarative/qquickfocusscope/data/test2.qml deleted file mode 100644 index ad74f3e9f4..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/test2.qml +++ /dev/null @@ -1,39 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Text { text: "All five rectangles should be red" } - - FocusScope { - y: 100 - focus: true; objectName: "item1" - Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true; objectName: "item2" - Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true; objectName: "item3" - Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true; objectName: "item4" - Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } - - FocusScope { - y: 100 - focus: true; objectName: "item5" - Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } - } - } - } - } - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/test3.qml b/tests/auto/declarative/qquickfocusscope/data/test3.qml deleted file mode 100644 index 537c30816e..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/test3.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 800 - height: 600 - - ListModel { - id: model - ListElement { name: "1" } - ListElement { name: "2" } - ListElement { name: "3" } - ListElement { name: "4" } - ListElement { name: "5" } - ListElement { name: "6" } - ListElement { name: "7" } - ListElement { name: "8" } - ListElement { name: "9" } - } - - Component { - id: verticalDelegate - FocusScope { - id: root - width: 50; height: 50; - Keys.onDigit9Pressed: console.log("Error - " + name) - Rectangle { - focus: true - Keys.onDigit9Pressed: console.log(name) - width: 50; height: 50; - color: root.ListView.isCurrentItem?"red":"green" - Text { text: name; anchors.centerIn: parent } - } - } - } - - ListView { - width: 800; height: 50; orientation: "Horizontal" - focus: true - model: model - delegate: verticalDelegate - preferredHighlightBegin: 100 - preferredHighlightEnd: 100 - highlightRangeMode: "StrictlyEnforceRange" - } - - - Text { - y: 100; x: 50 - text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left." - } -} diff --git a/tests/auto/declarative/qquickfocusscope/data/test4.qml b/tests/auto/declarative/qquickfocusscope/data/test4.qml deleted file mode 100644 index 0eea649f5d..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/test4.qml +++ /dev/null @@ -1,76 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onDigit9Pressed: console.log("Error - Root") - - FocusScope { - id: myScope - - Keys.onDigit9Pressed: console.log("Error - FocusScope") - - Rectangle { - objectName: "item0" - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.activeFocus?"blue":"black" - - Rectangle { - id: item1; objectName: "item1" - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - Keys.onDigit9Pressed: console.log("Error - Top Left"); - KeyNavigation.right: item2 - focus: true - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - - Rectangle { - id: item2; objectName: "item2" - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onDigit9Pressed: console.log("Error - Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "There should be no blue borders, or red squares.\nPressing \"9\" should do nothing.\nArrow keys should have no effect." } - - Rectangle { - id: item3; objectName: "item3" - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - - Keys.onDigit9Pressed: console.log("Error - Bottom Left"); - KeyNavigation.up: myScope - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - -} diff --git a/tests/auto/declarative/qquickfocusscope/data/test5.qml b/tests/auto/declarative/qquickfocusscope/data/test5.qml deleted file mode 100644 index 9c37cd1303..0000000000 --- a/tests/auto/declarative/qquickfocusscope/data/test5.qml +++ /dev/null @@ -1,84 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "white" - width: 800 - height: 600 - - Keys.onReturnPressed: console.log("Error - Root") - - FocusScope { - id: myScope - objectName: "item0" - focus: true - - Keys.onReturnPressed: console.log("Error - FocusScope") - - Rectangle { - height: 120 - width: 420 - - color: "transparent" - border.width: 5 - border.color: myScope.activeFocus?"blue":"black" - - Rectangle { - x: 10; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: item1.activeFocus?"blue":"black" - } - - TextEdit { - id: item1; objectName: "item1" - x: 20; y: 20 - width: 90; height: 90 - color: "white" - font.pixelSize: 20 - Keys.onReturnPressed: console.log("Top Left"); - KeyNavigation.right: item2 - focus: true - wrapMode: TextEdit.WordWrap - text: "Box 1" - } - - Rectangle { - id: item2; objectName: "item2" - x: 310; y: 10 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: activeFocus?"blue":"black" - KeyNavigation.left: item1 - Keys.onReturnPressed: console.log("Top Right"); - - Rectangle { - width: 50; height: 50; anchors.centerIn: parent - color: parent.activeFocus?"red":"transparent" - } - } - } - KeyNavigation.down: item3 - } - - Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box or flashing cursor indicates active focus\nUse arrow keys to navigate\nPress Ctrl-Return to print currently focused item" } - - Rectangle { - x: 10; y: 300 - width: 100; height: 100; color: "green" - border.width: 5 - border.color: item3.activeFocus?"blue":"black" - } - - TextEdit { - id: item3; objectName: "item3" - x: 20; y: 310 - width: 90; height: 90 - color: "white" - font.pixelSize: 20 - text: "Box 3" - - Keys.onReturnPressed: console.log("Bottom Left"); - KeyNavigation.up: myScope - wrapMode: TextEdit.WordWrap - } -} diff --git a/tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro b/tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro deleted file mode 100644 index 79649ebb8a..0000000000 --- a/tests/auto/declarative/qquickfocusscope/qquickfocusscope.pro +++ /dev/null @@ -1,10 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickfocusscope -SOURCES += tst_qquickfocusscope.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -QT += core-private gui-private declarative-private testlib diff --git a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp deleted file mode 100644 index d0149ed1d6..0000000000 --- a/tests/auto/declarative/qquickfocusscope/tst_qquickfocusscope.cpp +++ /dev/null @@ -1,668 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qquickfocusscope : public QObject -{ - Q_OBJECT -public: - tst_qquickfocusscope() {} - - template - T *findItem(QQuickItem *parent, const QString &id); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void basic(); - void nested(); - void noFocus(); - void textEdit(); - void forceFocus(); - void noParentFocus(); - void signalEmission(); - void qtBug13380(); - void forceActiveFocus(); - void canvasFocus(); -}; -void tst_qquickfocusscope::initTestCase() -{ -} - -void tst_qquickfocusscope::cleanupTestCase() -{ - -} - -/* - Find an item with the specified id. -*/ -template -T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName) -{ - const QMetaObject &mo = T::staticMetaObject; - QList children = parent->childItems(); - for (int i = 0; i < children.count(); ++i) { - QQuickItem *item = children.at(i); - if (item) { - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - return static_cast(item); - } - item = findItem(item, objectName); - if (item) - return static_cast(item); - } - } - return 0; -} - -void tst_qquickfocusscope::basic() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml"))); - - QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); - QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QVERIFY(item0 != 0); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVERIFY(view->isTopLevel()); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Right); - QTest::qWait(50); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Down); - QTest::qWait(50); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); - - delete view; -} - -void tst_qquickfocusscope::nested() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml"))); - - QQuickFocusScope *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickFocusScope *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickFocusScope *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QQuickFocusScope *item4 = findItem(view->rootObject(), QLatin1String("item4")); - QQuickFocusScope *item5 = findItem(view->rootObject(), QLatin1String("item5")); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - QVERIFY(item4 != 0); - QVERIFY(item5 != 0); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == true); - QVERIFY(item4->hasActiveFocus() == true); - QVERIFY(item5->hasActiveFocus() == true); - delete view; -} - -void tst_qquickfocusscope::noFocus() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml"))); - - QQuickRectangle *item0 = findItem(view->rootObject(), QLatin1String("item0")); - QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QVERIFY(item0 != 0); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - - view->show(); - view->requestActivateWindow(); - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Down); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - delete view; -} - -void tst_qquickfocusscope::textEdit() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml"))); - - QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); - QQuickTextEdit *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickTextEdit *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QVERIFY(item0 != 0); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - - QTRY_VERIFY(view == qGuiApp->focusWindow()); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Right); - QTest::keyClick(view, Qt::Key_Right); - QTest::keyClick(view, Qt::Key_Right); - QTest::keyClick(view, Qt::Key_Right); - QTest::keyClick(view, Qt::Key_Right); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == true); - QVERIFY(item3->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_Down); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); - - delete view; -} - -void tst_qquickfocusscope::forceFocus() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml"))); - - QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); - QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickFocusScope *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QQuickRectangle *item4 = findItem(view->rootObject(), QLatin1String("item4")); - QQuickRectangle *item5 = findItem(view->rootObject(), QLatin1String("item5")); - QVERIFY(item0 != 0); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - QVERIFY(item4 != 0); - QVERIFY(item5 != 0); - - view->show(); - view->requestActivateWindow(); - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_4); - QVERIFY(item0->hasActiveFocus() == true); - QVERIFY(item1->hasActiveFocus() == true); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == false); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == false); - - QTest::keyClick(view, Qt::Key_5); - QVERIFY(item0->hasActiveFocus() == false); - QVERIFY(item1->hasActiveFocus() == false); - QVERIFY(item2->hasActiveFocus() == false); - QVERIFY(item3->hasActiveFocus() == true); - QVERIFY(item4->hasActiveFocus() == false); - QVERIFY(item5->hasActiveFocus() == true); - - delete view; -} - -void tst_qquickfocusscope::noParentFocus() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml"))); - QVERIFY(view->rootObject()); - - view->show(); - view->requestActivateWindow(); - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVERIFY(view->rootObject()->property("focus1") == false); - QVERIFY(view->rootObject()->property("focus2") == false); - QVERIFY(view->rootObject()->property("focus3") == true); - QVERIFY(view->rootObject()->property("focus4") == true); - QVERIFY(view->rootObject()->property("focus5") == true); - - delete view; -} - -void tst_qquickfocusscope::signalEmission() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml"))); - - QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); - QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); - QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); - QQuickRectangle *item4 = findItem(view->rootObject(), QLatin1String("item4")); - QVERIFY(item1 != 0); - QVERIFY(item2 != 0); - QVERIFY(item3 != 0); - QVERIFY(item4 != 0); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QVariant blue(QColor("blue")); - QVariant red(QColor("red")); - - item1->setFocus(true); - QCOMPARE(item1->property("color"), red); - QCOMPARE(item2->property("color"), blue); - QCOMPARE(item3->property("color"), blue); - QCOMPARE(item4->property("color"), blue); - - item2->setFocus(true); - QCOMPARE(item1->property("color"), blue); - QCOMPARE(item2->property("color"), red); - QCOMPARE(item3->property("color"), blue); - QCOMPARE(item4->property("color"), blue); - - item3->setFocus(true); - QCOMPARE(item1->property("color"), blue); - QCOMPARE(item2->property("color"), red); - QCOMPARE(item3->property("color"), red); - QCOMPARE(item4->property("color"), blue); - - item4->setFocus(true); - QCOMPARE(item1->property("color"), blue); - QCOMPARE(item2->property("color"), red); - QCOMPARE(item3->property("color"), blue); - QCOMPARE(item4->property("color"), red); - - item4->setFocus(false); - QCOMPARE(item1->property("color"), blue); - QCOMPARE(item2->property("color"), red); - QCOMPARE(item3->property("color"), blue); - QCOMPARE(item4->property("color"), blue); - - delete view; -} - -void tst_qquickfocusscope::qtBug13380() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml"))); - - view->show(); - QVERIFY(view->rootObject()); - view->requestActivateWindow(); - qApp->processEvents(); - - QTest::qWaitForWindowShown(view); - - QTRY_VERIFY(view == qGuiApp->focusWindow()); - QVERIFY(view->rootObject()->property("noFocus").toBool()); - - view->rootObject()->setProperty("showRect", true); - QVERIFY(view->rootObject()->property("noFocus").toBool()); - - delete view; -} - -void tst_qquickfocusscope::forceActiveFocus() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml"))); - - view->show(); - view->requestActivateWindow(); - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - QQuickItem *rootObject = view->rootObject(); - QVERIFY(rootObject); - - QQuickItem *scope = findItem(rootObject, QLatin1String("scope")); - QQuickItem *itemA1 = findItem(rootObject, QLatin1String("item-a1")); - QQuickItem *scopeA = findItem(rootObject, QLatin1String("scope-a")); - QQuickItem *itemA2 = findItem(rootObject, QLatin1String("item-a2")); - QQuickItem *itemB1 = findItem(rootObject, QLatin1String("item-b1")); - QQuickItem *scopeB = findItem(rootObject, QLatin1String("scope-b")); - QQuickItem *itemB2 = findItem(rootObject, QLatin1String("item-b2")); - - QVERIFY(scope); - QVERIFY(itemA1); - QVERIFY(scopeA); - QVERIFY(itemA2); - QVERIFY(itemB1); - QVERIFY(scopeB); - QVERIFY(itemB2); - - QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool))); - QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool))); - QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool))); - QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool))); - - // First, walk the focus from item-a1 down to item-a2 and back again - itemA1->forceActiveFocus(); - QVERIFY(itemA1->hasActiveFocus()); - QVERIFY(!rootObject->hasActiveFocus()); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - scopeA->forceActiveFocus(); - QVERIFY(!itemA1->hasActiveFocus()); - QVERIFY(scopeA->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - itemA2->forceActiveFocus(); - QVERIFY(!itemA1->hasActiveFocus()); - QVERIFY(itemA2->hasActiveFocus()); - QVERIFY(scopeA->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - scopeA->forceActiveFocus(); - QVERIFY(!itemA1->hasActiveFocus()); - QVERIFY(itemA2->hasActiveFocus()); - QVERIFY(scopeA->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - itemA1->forceActiveFocus(); - QVERIFY(itemA1->hasActiveFocus()); - QVERIFY(!scopeA->hasActiveFocus()); - QVERIFY(!itemA2->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 2); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - // Then jump back and forth between branch 'a' and 'b' - itemB1->forceActiveFocus(); - QVERIFY(itemB1->hasActiveFocus()); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - scopeA->forceActiveFocus(); - QVERIFY(!itemA1->hasActiveFocus()); - QVERIFY(!itemB1->hasActiveFocus()); - QVERIFY(scopeA->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 3); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - scopeB->forceActiveFocus(); - QVERIFY(!scopeA->hasActiveFocus()); - QVERIFY(!itemB1->hasActiveFocus()); - QVERIFY(scopeB->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 4); - QCOMPARE(scopeBSpy.count(), 1); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - itemA2->forceActiveFocus(); - QVERIFY(!scopeB->hasActiveFocus()); - QVERIFY(itemA2->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 5); - QCOMPARE(scopeBSpy.count(), 2); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - itemB2->forceActiveFocus(); - QVERIFY(!itemA2->hasActiveFocus()); - QVERIFY(itemB2->hasActiveFocus()); - QCOMPARE(scopeASpy.count(), 6); - QCOMPARE(scopeBSpy.count(), 3); - QCOMPARE(rootSpy.count(), 0); - QCOMPARE(scopeSpy.count(), 1); - - delete view; -} - -void tst_qquickfocusscope::canvasFocus() -{ - QQuickView *view = new QQuickView; - view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml"))); - - QQuickView alternateView; - - QQuickItem *rootObject = view->rootObject(); - QVERIFY(rootObject); - - QQuickItem *rootItem = view->rootItem(); - QQuickItem *scope1 = findItem(rootObject, QLatin1String("scope1")); - QQuickItem *item1 = findItem(rootObject, QLatin1String("item1")); - QQuickItem *scope2 = findItem(rootObject, QLatin1String("scope2")); - QQuickItem *item2 = findItem(rootObject, QLatin1String("item2")); - - QVERIFY(scope1); - QVERIFY(item1); - QVERIFY(scope2); - QVERIFY(item2); - - QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool))); - QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool))); - QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool))); - QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool))); - QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool))); - QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool))); - QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool))); - QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool))); - QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool))); - QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool))); - - QEXPECT_FAIL("", "QTBUG-22415", Abort); - QCOMPARE(rootItem->hasFocus(), false); - QCOMPARE(rootItem->hasActiveFocus(), false); - QCOMPARE(scope1->hasFocus(), true); - QCOMPARE(scope1->hasActiveFocus(), false); - QCOMPARE(item1->hasFocus(), true); - QCOMPARE(item1->hasActiveFocus(), false); - QCOMPARE(scope2->hasFocus(), false); - QCOMPARE(scope2->hasActiveFocus(), false); - QCOMPARE(item2->hasFocus(), false); - QCOMPARE(item2->hasActiveFocus(), false); - - view->show(); - view->requestActivateWindow(); - - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(view == qGuiApp->focusWindow()); - - // Now the canvas has focus, active focus given to item1 - QCOMPARE(rootItem->hasFocus(), true); - QCOMPARE(rootItem->hasActiveFocus(), true); - QCOMPARE(scope1->hasFocus(), true); - QCOMPARE(scope1->hasActiveFocus(), true); - QCOMPARE(item1->hasFocus(), true); - QCOMPARE(item1->hasActiveFocus(), true); - QCOMPARE(scope2->hasFocus(), false); - QCOMPARE(scope2->hasActiveFocus(), false); - QCOMPARE(item2->hasFocus(), false); - QCOMPARE(item2->hasActiveFocus(), false); - - QCOMPARE(rootFocusSpy.count(), 1); - QCOMPARE(rootActiveFocusSpy.count(), 1); - QCOMPARE(scope1FocusSpy.count(), 0); - QCOMPARE(scope1ActiveFocusSpy.count(), 1); - QCOMPARE(item1FocusSpy.count(), 0); - QCOMPARE(item1ActiveFocusSpy.count(), 1); - - - // view->hide(); // seemingly doesn't remove focus, so have an another view steal it. - alternateView.show(); - alternateView.requestActivateWindow(); - QTest::qWaitForWindowShown(&alternateView); - QTRY_VERIFY(QGuiApplication::focusWindow() == &alternateView); - - QCOMPARE(rootItem->hasFocus(), false); - QCOMPARE(rootItem->hasActiveFocus(), false); - QCOMPARE(scope1->hasFocus(), true); - QCOMPARE(scope1->hasActiveFocus(), false); - QCOMPARE(item1->hasFocus(), true); - QCOMPARE(item1->hasActiveFocus(), false); - - QCOMPARE(rootFocusSpy.count(), 2); - QCOMPARE(rootActiveFocusSpy.count(), 2); - QCOMPARE(scope1FocusSpy.count(), 0); - QCOMPARE(scope1ActiveFocusSpy.count(), 2); - QCOMPARE(item1FocusSpy.count(), 0); - QCOMPARE(item1ActiveFocusSpy.count(), 2); - - - // canvas does not have focus, so item2 will not get active focus - item2->forceActiveFocus(); - - QCOMPARE(rootItem->hasFocus(), false); - QCOMPARE(rootItem->hasActiveFocus(), false); - QCOMPARE(scope1->hasFocus(), false); - QCOMPARE(scope1->hasActiveFocus(), false); - QCOMPARE(item1->hasFocus(), true); - QCOMPARE(item1->hasActiveFocus(), false); - QCOMPARE(scope2->hasFocus(), true); - QCOMPARE(scope2->hasActiveFocus(), false); - QCOMPARE(item2->hasFocus(), true); - QCOMPARE(item2->hasActiveFocus(), false); - - QCOMPARE(rootFocusSpy.count(), 2); - QCOMPARE(rootActiveFocusSpy.count(), 2); - QCOMPARE(scope1FocusSpy.count(), 1); - QCOMPARE(scope1ActiveFocusSpy.count(), 2); - QCOMPARE(item1FocusSpy.count(), 0); - QCOMPARE(item1ActiveFocusSpy.count(), 2); - QCOMPARE(scope2FocusSpy.count(), 1); - QCOMPARE(scope2ActiveFocusSpy.count(), 0); - QCOMPARE(item2FocusSpy.count(), 1); - QCOMPARE(item2ActiveFocusSpy.count(), 0); - - // give the canvas focus, and item2 will get active focus - view->show(); - view->requestActivateWindow(); - QTest::qWaitForWindowShown(view); - QTRY_VERIFY(QGuiApplication::focusWindow() == view); - - QCOMPARE(rootItem->hasFocus(), true); - QCOMPARE(rootItem->hasActiveFocus(), true); - QCOMPARE(scope2->hasFocus(), true); - QCOMPARE(scope2->hasActiveFocus(), true); - QCOMPARE(item2->hasFocus(), true); - QCOMPARE(item2->hasActiveFocus(), true); - QCOMPARE(rootFocusSpy.count(), 3); - QCOMPARE(rootActiveFocusSpy.count(), 3); - QCOMPARE(scope2FocusSpy.count(), 1); - QCOMPARE(scope2ActiveFocusSpy.count(), 1); - QCOMPARE(item2FocusSpy.count(), 1); - QCOMPARE(item2ActiveFocusSpy.count(), 1); - - delete view; -} - -QTEST_MAIN(tst_qquickfocusscope) - -#include "tst_qquickfocusscope.moc" diff --git a/tests/auto/declarative/qquickgridview/data/ComponentView.qml b/tests/auto/declarative/qquickgridview/data/ComponentView.qml deleted file mode 100644 index 12ab6c92d1..0000000000 --- a/tests/auto/declarative/qquickgridview/data/ComponentView.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -GridView { - id: view - - property string title - - width: 100; height: 100; - - model: 1 - delegate: Text { objectName: "listItem"; text: view.title } - header: Text { objectName: "header"; text: view.title } - footer: Text { objectName: "footer"; text: view.title } -} diff --git a/tests/auto/declarative/qquickgridview/data/asyncloader.qml b/tests/auto/declarative/qquickgridview/data/asyncloader.qml deleted file mode 100644 index ab66f20a1e..0000000000 --- a/tests/auto/declarative/qquickgridview/data/asyncloader.qml +++ /dev/null @@ -1,36 +0,0 @@ - -import QtQuick 2.0 - -Rectangle { - id: root - width: 300; height: 400 - color: "#2200FF00" - - Loader { - asynchronous: true - sourceComponent: viewComp - anchors.fill: parent - } - - Component { - id: viewComp - GridView { - objectName: "view" - width: 300; height: 400 - model: 40 - delegate: aDelegate - - highlight: Rectangle { color: "lightsteelblue" } - } - } - // The delegate for each list - Component { - id: aDelegate - Item { - objectName: "wrapper" - width: 100 - height: 100 - Text { text: 'Index: ' + index } - } - } -} diff --git a/tests/auto/declarative/qquickgridview/data/attachedSignals.qml b/tests/auto/declarative/qquickgridview/data/attachedSignals.qml deleted file mode 100644 index 73c10d8caf..0000000000 --- a/tests/auto/declarative/qquickgridview/data/attachedSignals.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -GridView { - id: view - width: 240; height: 320 - - property variant addedDelegates: [] - property int removedDelegateCount - - model: testModel - - cellWidth: delegateWidth; cellHeight: delegateHeight - - delegate: Rectangle { - width: delegateWidth; height: delegateHeight - border.width: 1 - GridView.onAdd: { - var obj = GridView.view.addedDelegates - obj.push(model.name) - GridView.view.addedDelegates = obj - } - GridView.onRemove: { - view.removedDelegateCount += 1 - } - } -} - diff --git a/tests/auto/declarative/qquickgridview/data/creationContext.qml b/tests/auto/declarative/qquickgridview/data/creationContext.qml deleted file mode 100644 index 79a682788b..0000000000 --- a/tests/auto/declarative/qquickgridview/data/creationContext.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -ComponentView { - title: "Hello!" -} diff --git a/tests/auto/declarative/qquickgridview/data/displaygrid.qml b/tests/auto/declarative/qquickgridview/data/displaygrid.qml deleted file mode 100644 index 1da4fe50ac..0000000000 --- a/tests/auto/declarative/qquickgridview/data/displaygrid.qml +++ /dev/null @@ -1,39 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - Text { - y: 20 - id: displayText - objectName: "displayText" - text: display - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ] - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - cellWidth: 80 - cellHeight: 60 - model: testModel - delegate: myDelegate - } -} diff --git a/tests/auto/declarative/qquickgridview/data/footer.qml b/tests/auto/declarative/qquickgridview/data/footer.qml deleted file mode 100644 index 9083f9f57c..0000000000 --- a/tests/auto/declarative/qquickgridview/data/footer.qml +++ /dev/null @@ -1,48 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property bool showHeader: false - - function changeFooter() { - grid.footer = footer2 - } - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - Component { - id: headerComponent - Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } - } - - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - cellWidth: 80 - cellHeight: 60 - model: testModel - delegate: myDelegate - header: parent.showHeader ? headerComponent : null - footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 } - } - - Component { - id: footer2 - Text { objectName: "footer2"; text: "Footer 2" + x + "," + y; width: 50; height: 20 } - } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview-enforcerange.qml b/tests/auto/declarative/qquickgridview/data/gridview-enforcerange.qml deleted file mode 100644 index 2bfe7da78e..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview-enforcerange.qml +++ /dev/null @@ -1,58 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Item { - id: wrapper - objectName: "wrapper" - height: 100 - width: 100 - Text { - text: index - } - Text { - y: 25 - id: textName - objectName: "textName" - text: name - } - Text { - y: 50 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - y: 75 - text: wrapper.y - } - } - } - - Component { - id: myHighlight - Rectangle { - color: "lightsteelblue" - } - } - - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - model: testModel - delegate: myDelegate - highlight: myHighlight - flow: (testTopToBottom == true) ? GridView.TopToBottom : GridView.LeftToRight - layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight - preferredHighlightBegin: 100 - preferredHighlightEnd: 100 - highlightRangeMode: "StrictlyEnforceRange" - focus: true - } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview-initCurrent.qml b/tests/auto/declarative/qquickgridview/data/gridview-initCurrent.qml deleted file mode 100644 index 624f639962..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview-initCurrent.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - - property int current: grid.currentIndex - property bool showHeader: false - property bool showFooter: false - - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - Text { - x: 40 - text: wrapper.x + ", " + wrapper.y - } - Text { - y: 20 - id: textName - objectName: "textName" - text: name - } - Text { - y: 40 - id: textNumber - objectName: "textNumber" - text: number - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ] - - Component { - id: headerFooter - Rectangle { height: 30; width: 240; color: "blue" } - } - - GridView { - id: grid - objectName: "grid" - focus: true - width: 240 - height: 320 - currentIndex: 35 - cellWidth: 80 - cellHeight: 60 - delegate: myDelegate - highlightMoveDuration: 400 - model: testModel - header: root.showHeader ? headerFooter : null - footer: root.showFooter ? headerFooter : null - } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview-noCurrent.qml b/tests/auto/declarative/qquickgridview/data/gridview-noCurrent.qml deleted file mode 100644 index 600716e2d4..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview-noCurrent.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property int current: grid.currentIndex - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - Text { - x: 40 - text: wrapper.x + ", " + wrapper.y - } - Text { - y: 20 - id: textName - objectName: "textName" - text: name - } - Text { - y: 40 - id: textNumber - objectName: "textNumber" - text: number - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ] - GridView { - id: grid - objectName: "grid" - focus: true - width: 240 - height: 320 - currentIndex: -1 - cellWidth: 80 - cellHeight: 60 - delegate: myDelegate - model: testModel - } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview1.qml b/tests/auto/declarative/qquickgridview/data/gridview1.qml deleted file mode 100644 index 4bf6f0b952..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview1.qml +++ /dev/null @@ -1,69 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - property int count: grid.count - property bool showHeader: false - property bool showFooter: false - property real cacheBuffer: 0 - property int added: -1 - property variant removed - - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - property string name: model.name - Text { - text: index - } - Text { - x: 40 - text: wrapper.x + ", " + wrapper.y - } - Text { - y: 20 - id: textName - objectName: "textName" - text: name - } - Text { - y: 40 - id: textNumber - objectName: "textNumber" - text: number - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - GridView.onAdd: root.added = index - GridView.onRemove: root.removed = name - } - }, - Component { - id: headerFooter - Rectangle { width: 30; height: 320; color: "blue" } - } - ] - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - cellWidth: 80 - cellHeight: 60 - flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom - layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight - model: testModel - delegate: myDelegate - header: root.showHeader ? headerFooter : null - footer: root.showFooter ? headerFooter : null - cacheBuffer: root.cacheBuffer - } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview2.qml b/tests/auto/declarative/qquickgridview/data/gridview2.qml deleted file mode 100644 index 5fb45a1613..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview2.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -GridView { - anchors.fill: parent - width: 320; height: 200 - cellWidth: 100; cellHeight: 100; cacheBuffer: 200; focus: true - keyNavigationWraps: true; highlightFollowsCurrentItem: false - - model: ListModel { - id: appModel - ListElement { lColor: "red" } - ListElement { lColor: "yellow" } - ListElement { lColor: "green" } - ListElement { lColor: "blue" } - } - - delegate: Item { - width: 100; height: 100 - Rectangle { - color: lColor; x: 4; y: 4 - width: 92; height: 92 - } - } - - highlight: Rectangle { width: 100; height: 100; color: "black" } -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview3.qml b/tests/auto/declarative/qquickgridview/data/gridview3.qml deleted file mode 100644 index a8c1c5a0f7..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview3.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -GridView { - anchors.fill: parent - width: 320; height: 200 -} diff --git a/tests/auto/declarative/qquickgridview/data/gridview4.qml b/tests/auto/declarative/qquickgridview/data/gridview4.qml deleted file mode 100644 index eed3a2bdb1..0000000000 --- a/tests/auto/declarative/qquickgridview/data/gridview4.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -GridView { - width: 405 - height: 200 - cellWidth: width/9 - cellHeight: height/2 - - model: 18 - delegate: Rectangle { objectName: "delegate"; width: 10; height: 10; color: "green" } -} diff --git a/tests/auto/declarative/qquickgridview/data/header.qml b/tests/auto/declarative/qquickgridview/data/header.qml deleted file mode 100644 index 648e2a2298..0000000000 --- a/tests/auto/declarative/qquickgridview/data/header.qml +++ /dev/null @@ -1,40 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - function changeHeader() { - grid.header = header2 - } - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 80 - height: 60 - border.color: "blue" - Text { - text: index - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - GridView { - id: grid - objectName: "grid" - width: initialViewWidth - height: initialViewHeight - cellWidth: 80 - cellHeight: 60 - model: testModel - delegate: myDelegate - header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } - } - - Component { - id: header2 - Text { objectName: "header2"; text: "Header 2 " + x + "," + y; width: 50; height: 20 } - } -} diff --git a/tests/auto/declarative/qquickgridview/data/manual-highlight.qml b/tests/auto/declarative/qquickgridview/data/manual-highlight.qml deleted file mode 100644 index c2f1d20fb1..0000000000 --- a/tests/auto/declarative/qquickgridview/data/manual-highlight.qml +++ /dev/null @@ -1,48 +0,0 @@ -import QtQuick 2.0 - -Item { - - ListModel { - id: model - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - ListElement { - name: "Bob Brown" - number: "555 5845" - } - } - - Component { - id: highlight - Rectangle { - objectName: "highlight" - width: 80; height: 80 - color: "lightsteelblue"; radius: 5 - y: grid.currentItem.y+5 - x: grid.currentItem.x+5 - } - } - - GridView { - id: grid - objectName: "grid" - anchors.fill: parent - model: model - delegate: Text { objectName: "wrapper"; text: name; width: 80; height: 80 } - - highlight: highlight - highlightFollowsCurrentItem: false - focus: true - } - -} diff --git a/tests/auto/declarative/qquickgridview/data/margins.qml b/tests/auto/declarative/qquickgridview/data/margins.qml deleted file mode 100644 index d369658a91..0000000000 --- a/tests/auto/declarative/qquickgridview/data/margins.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - width: 100 - height: 80 - border.color: "blue" - property string name: model.name - Text { - text: index - } - Text { - x: 40 - text: wrapper.x + ", " + wrapper.y - } - Text { - y: 20 - id: textName - objectName: "textName" - text: name - } - Text { - y: 40 - id: textNumber - objectName: "textNumber" - text: number - } - color: GridView.isCurrentItem ? "lightsteelblue" : "white" - } - } - GridView { - id: grid - objectName: "grid" - width: 240 - height: 320 - cellWidth: 100 - cellHeight: 80 - leftMargin: 30 - rightMargin: 50 - flow: GridView.TopToBottom - layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight - model: testModel - delegate: myDelegate - } - Text { anchors.bottom: parent.bottom; text: grid.contentX } -} diff --git a/tests/auto/declarative/qquickgridview/data/mirroring.qml b/tests/auto/declarative/qquickgridview/data/mirroring.qml deleted file mode 100644 index b9aff501c1..0000000000 --- a/tests/auto/declarative/qquickgridview/data/mirroring.qml +++ /dev/null @@ -1,43 +0,0 @@ -// This example demonstrates how item positioning -// changes in right-to-left layout direction - -import QtQuick 2.0 - -Rectangle { - color: "lightgray" - width: 340 - height: 370 - - VisualItemModel { - id: itemModel - objectName: "itemModel" - Rectangle { - objectName: "item1" - height: 110; width: 120; color: "#FFFEF0" - Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item2" - height: 130; width: 150; color: "#F0FFF7" - Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item3" - height: 170; width: 190; color: "#F4F0FF" - Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - } - - GridView { - id: view - objectName: "view" - cellWidth: 190 - cellHeight: 170 - anchors.fill: parent - anchors.bottomMargin: 30 - model: itemModel - highlightRangeMode: "StrictlyEnforceRange" - flow: GridView.TopToBottom - flickDeceleration: 2000 - } -} diff --git a/tests/auto/declarative/qquickgridview/data/propertychangestest.qml b/tests/auto/declarative/qquickgridview/data/propertychangestest.qml deleted file mode 100644 index 97efbe78f5..0000000000 --- a/tests/auto/declarative/qquickgridview/data/propertychangestest.qml +++ /dev/null @@ -1,69 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 360; height: 120; color: "white" - Component { - id: delegate - Item { - id: wrapper - width: 180; height: 40; - Column { - x: 5; y: 5 - Text { text: 'Name: ' + name } - Text { text: 'Number: ' + number } - } - } - } - Component { - id: highlightRed - Rectangle { - color: "red" - radius: 10 - opacity: 0.5 - } - } - GridView { - cellWidth:180 - cellHeight:40 - objectName: "gridView" - anchors.fill: parent - model: listModel - delegate: delegate - highlight: highlightRed - focus: true - keyNavigationWraps: true - cacheBuffer: 10 - flow: GridView.LeftToRight - } - - data:[ - ListModel { - id: listModel - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - }, - ListModel { - objectName: "alternateModel" - ListElement { - name: "Jack" - number: "555 8426" - } - ListElement { - name: "Mary" - number: "555 3264" - } - } - ] -} - - diff --git a/tests/auto/declarative/qquickgridview/data/resizeview.qml b/tests/auto/declarative/qquickgridview/data/resizeview.qml deleted file mode 100644 index 1f730a4a8a..0000000000 --- a/tests/auto/declarative/qquickgridview/data/resizeview.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - - property real initialHeight - - GridView { - id: grid - objectName: "grid" - width: 240 - height: initialHeight - cellWidth: 80 - cellHeight: 60 - model: testModel - delegate: Rectangle { - objectName: "wrapper" - width: 80 - height: 60 - border.width: 1 - } - } -} - diff --git a/tests/auto/declarative/qquickgridview/data/setindex.qml b/tests/auto/declarative/qquickgridview/data/setindex.qml deleted file mode 100644 index ef80f3a2fb..0000000000 --- a/tests/auto/declarative/qquickgridview/data/setindex.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 200 - Component { - id: appDelegate - - Item { - id : wrapper - function startupFunction() { - if (index == 5) view.currentIndex = index; - } - Component.onCompleted: startupFunction(); - width: 30; height: 30 - Text { text: index } - } - } - - GridView { - id: view - objectName: "grid" - anchors.fill: parent - cellWidth: 30; cellHeight: 30 - model: 35 - delegate: appDelegate - focus: true - } -} diff --git a/tests/auto/declarative/qquickgridview/data/snapToRow.qml b/tests/auto/declarative/qquickgridview/data/snapToRow.qml deleted file mode 100644 index f079a048f0..0000000000 --- a/tests/auto/declarative/qquickgridview/data/snapToRow.qml +++ /dev/null @@ -1,49 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 240 - height: 240 - color: "#ffffff" - - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 80 - width: 80 - Column { - Text { - text: index - } - Text { - text: wrapper.x + ", " + wrapper.y - } - } - color: GridView.isCurrentItem ? "lightsteelblue" : "transparent" - } - } - GridView { - id: grid - objectName: "grid" - anchors.fill: parent - cellWidth: 80 - cellHeight: 80 - preferredHighlightBegin: 20 - preferredHighlightEnd: 100 - snapMode: GridView.SnapToRow - layoutDirection: Qt.RightToLeft - flow: GridView.TopToBottom - highlightRangeMode: GridView.StrictlyEnforceRange - highlight: Rectangle { width: 80; height: 80; color: "yellow" } - model: 54 - delegate: myDelegate - } - - Text { - anchors.right: parent.right - anchors.bottom: parent.bottom - text: grid.contentX + ", " + grid.contentY - } -} diff --git a/tests/auto/declarative/qquickgridview/data/unaligned.qml b/tests/auto/declarative/qquickgridview/data/unaligned.qml deleted file mode 100644 index 445400e8b4..0000000000 --- a/tests/auto/declarative/qquickgridview/data/unaligned.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -GridView { - width: 400 - height: 200 - cellWidth: width/9 - cellHeight: height/2 - - model: testModel - delegate: Rectangle { - objectName: "wrapper"; width: 10; height: 10; color: "green" - Text { text: index } - } -} - diff --git a/tests/auto/declarative/qquickgridview/qquickgridview.pro b/tests/auto/declarative/qquickgridview/qquickgridview.pro deleted file mode 100644 index c88b63a68e..0000000000 --- a/tests/auto/declarative/qquickgridview/qquickgridview.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickgridview -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickgridview.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -CONFIG += insignificant_test #QTBUG-22807 -QT += core-private gui-private v8-private declarative-private opengl-private testlib widgets diff --git a/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp b/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp deleted file mode 100644 index 503379ae42..0000000000 --- a/tests/auto/declarative/qquickgridview/tst_qquickgridview.cpp +++ /dev/null @@ -1,3705 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include - -Q_DECLARE_METATYPE(Qt::LayoutDirection) -Q_DECLARE_METATYPE(QQuickGridView::Flow) - -class tst_QQuickGridView : public QObject -{ - Q_OBJECT -public: - tst_QQuickGridView(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void items(); - void changed(); - void inserted(); - void inserted_more(); - void inserted_more_data(); - void insertBeforeVisible(); - void insertBeforeVisible_data(); - void removed(); - void addOrRemoveBeforeVisible(); - void addOrRemoveBeforeVisible_data(); - void clear(); - void moved(); - void moved_data(); - void multipleChanges(); - void multipleChanges_data(); - void swapWithFirstItem(); - void changeFlow(); - void currentIndex(); - void noCurrentIndex(); - void defaultValues(); - void properties(); - void propertyChanges(); - void componentChanges(); - void modelChanges(); - void positionViewAtIndex(); - void positionViewAtIndex_rightToLeft(); - void mirroring(); - void snapping(); - void resetModel(); - void enforceRange(); - void enforceRange_rightToLeft(); - void QTBUG_8456(); - void manualHighlight(); - void footer(); - void footer_data(); - void header(); - void header_data(); - void resizeViewAndRepaint(); - void indexAt(); - void onAdd(); - void onAdd_data(); - void onRemove(); - void onRemove_data(); - void columnCount(); - void margins(); - void creationContext(); - void snapToRow_data(); - void snapToRow(); - void unaligned(); - void cacheBuffer(); - void asynchronous(); - -private: - QQuickView *createView(); - void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); - template - T *findItem(QQuickItem *parent, const QString &id, int index=-1); - template - QList findItems(QQuickItem *parent, const QString &objectName); - void dumpTree(QQuickItem *parent, int depth = 0); -}; - -template -void tst_qquickgridview_move(int from, int to, int n, T *items) -{ - if (n == 1) { - items->move(from, to); - } else { - T replaced; - int i=0; - typename T::ConstIterator it=items->begin(); it += from+n; - for (; ibegin(); it += from; - for (; ibegin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } -} - -void tst_QQuickGridView::initTestCase() -{ -} - -void tst_QQuickGridView::cleanupTestCase() -{ - -} - - -class TestModel : public QAbstractListModel -{ -public: - enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; - - TestModel(QObject *parent=0) : QAbstractListModel(parent) { - QHash roles; - roles[Name] = "name"; - roles[Number] = "number"; - setRoleNames(roles); - } - - int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } - QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { - QVariant rv; - if (role == Name) - rv = list.at(index.row()).first; - else if (role == Number) - rv = list.at(index.row()).second; - - return rv; - } - - int count() const { return rowCount(); } - QString name(int index) const { return list.at(index).first; } - QString number(int index) const { return list.at(index).second; } - - void addItem(const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), list.count(), list.count()); - list.append(QPair(name, number)); - emit endInsertRows(); - } - - void addItems(const QList > &items) { - emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); - for (int i=0; i(items[i].first, items[i].second)); - emit endInsertRows(); - } - - void insertItem(int index, const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), index, index); - list.insert(index, QPair(name, number)); - emit endInsertRows(); - } - - void insertItems(int index, const QList > &items) { - emit beginInsertRows(QModelIndex(), index, index + items.count() - 1); - for (int i=0; i(items[i].first, items[i].second)); - emit endInsertRows(); - } - - void removeItem(int index) { - emit beginRemoveRows(QModelIndex(), index, index); - list.removeAt(index); - emit endRemoveRows(); - } - - void removeItems(int index, int count) { - emit beginRemoveRows(QModelIndex(), index, index+count-1); - while (count--) - list.removeAt(index); - emit endRemoveRows(); - } - - void moveItem(int from, int to) { - emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); - list.move(from, to); - emit endMoveRows(); - } - - void moveItems(int from, int to, int count) { - emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); - tst_qquickgridview_move(from, to, count, &list); - emit endMoveRows(); - } - - void modifyItem(int idx, const QString &name, const QString &number) { - list[idx] = QPair(name, number); - emit dataChanged(index(idx,0), index(idx,0)); - } - - void clear() { - int count = list.count(); - emit beginRemoveRows(QModelIndex(), 0, count-1); - list.clear(); - emit endRemoveRows(); - } - - -private: - QList > list; -}; - -tst_QQuickGridView::tst_QQuickGridView() -{ -} - -void tst_QQuickGridView::items() -{ - QQuickView *canvas = createView(); - - TestModel model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Billy", "22345"); - model.addItem("Sam", "2945"); - model.addItem("Ben", "04321"); - model.addItem("Jim", "0780"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(gridview->count(), model.count()); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - for (int i = 0; i < model.count(); ++i) { - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - // set an empty model and confirm that items are destroyed - TestModel model2; - ctxt->setContextProperty("testModel", &model2); - - int itemCount = findItems(contentItem, "wrapper").count(); - QTRY_VERIFY(itemCount == 0); - - delete canvas; -} - -void tst_QQuickGridView::changed() -{ - QQuickView *canvas = createView(); - - TestModel model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Billy", "22345"); - model.addItem("Sam", "2945"); - model.addItem("Ben", "04321"); - model.addItem("Jim", "0780"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickFlickable *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.modifyItem(1, "Will", "9876"); - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - delete canvas; -} - -void tst_QQuickGridView::inserted() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.insertItem(1, "Will", "9876"); - - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - // Checks that onAdd is called - int added = canvas->rootObject()->property("added").toInt(); - QTRY_COMPARE(added, 1); - - // Confirm items positioned correctly - for (int i = 0; i < model.count(); ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0); - } - - model.insertItem(0, "Foo", "1111"); // zero index, and current item - - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - QTRY_COMPARE(gridview->currentIndex(), 1); - - // Confirm items positioned correctly - for (int i = 0; i < model.count(); ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - for (int i = model.count(); i < 30; ++i) - model.insertItem(i, "Hello", QString::number(i)); - - gridview->setContentY(120); - - // Insert item outside visible area - model.insertItem(1, "Hello", "1324"); - - QTRY_VERIFY(gridview->contentY() == 120); - - delete canvas; -} - -void tst_QQuickGridView::inserted_more() -{ - QFETCH(qreal, contentY); - QFETCH(int, insertIndex); - QFETCH(int, insertCount); - QFETCH(qreal, itemsOffsetAfterMove); - - QQuickText *name; - QQuickText *number; - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - gridview->setContentY(contentY); - - QList > newData; - for (int i=0; iproperty("count").toInt(), model.count()); - - // check visibleItems.first() is in correct position - QQuickItem *item0 = findItem(contentItem, "wrapper", 0); - QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); - - QList items = findItems(contentItem, "wrapper"); - int firstVisibleIndex = -1; - for (int i=0; iy() >= contentY) { - QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - break; - } - } - QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - - QCOMPARE(item->x(), (i%3)*80.0); - QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); - - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QCOMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QCOMPARE(number->text(), model.number(i)); - } - - delete canvas; -} - -void tst_QQuickGridView::inserted_more_data() -{ - QTest::addColumn("contentY"); - QTest::addColumn("insertIndex"); - QTest::addColumn("insertCount"); - QTest::addColumn("itemsOffsetAfterMove"); - - QTest::newRow("add 1, before visible items") - << 120.0 // show 6-23 - << 5 << 1 - << 0.0; // insert 1 above first visible, grid is rearranged; first visible moves forward within its row - // new 1st visible item is at 0 - - QTest::newRow("add 2, before visible items") - << 120.0 // show 6-23 - << 5 << 2 - << 0.0; // insert 2 above first visible, grid is rearranged; first visible moves forward within its row - - QTest::newRow("add 3, before visible items") - << 120.0 // show 6-23 - << 5 << 3 - << -60.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move - - QTest::newRow("add 5, before visible items") - << 120.0 // show 6-23 - << 5 << 5 - << -60.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos, - // grid is rearranged and first visible moves forward within its row - - QTest::newRow("add 6, before visible items") - << 120.0 // show 6-23 - << 5 << 6 - << -60.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move - - - - QTest::newRow("add 1, at start of visible, content at start") - << 0.0 - << 0 << 1 - << 0.0; - - QTest::newRow("add multiple, at start of visible, content at start") - << 0.0 - << 0 << 3 - << 0.0; - - QTest::newRow("add 1, at start of visible, content not at start") - << 120.0 // show 6-23 - << 6 << 1 - << 0.0; - - QTest::newRow("add multiple, at start of visible, content not at start") - << 120.0 // show 6-23 - << 6 << 3 - << 0.0; - - - QTest::newRow("add 1, at end of visible, content at start") - << 0.0 - << 17 << 1 - << 0.0; - - QTest::newRow("add 1, at end of visible, content at start") - << 0.0 - << 17 << 3 - << 0.0; - - QTest::newRow("add 1, at end of visible, content not at start") - << 120.0 // show 6-23 - << 23 << 1 - << 0.0; - - QTest::newRow("add multiple, at end of visible, content not at start") - << 120.0 // show 6-23 - << 23 << 3 - << 0.0; - - - QTest::newRow("add 1, after visible, content at start") - << 0.0 - << 20 << 1 - << 0.0; - - QTest::newRow("add 1, after visible, content at start") - << 0.0 - << 20 << 3 - << 0.0; - - QTest::newRow("add 1, after visible, content not at start") - << 120.0 // show 6-23 - << 24 << 1 - << 0.0; - - QTest::newRow("add multiple, after visible, content not at start") - << 120.0 // show 6-23 - << 24 << 3 - << 0.0; -} - -void tst_QQuickGridView::insertBeforeVisible() -{ - QFETCH(int, insertIndex); - QFETCH(int, insertCount); - QFETCH(int, cacheBuffer); - - QQuickText *name; - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - gridview->setCacheBuffer(cacheBuffer); - - // trigger a refill (not just setting contentY) so that the visibleItems grid is updated - int firstVisibleIndex = 20; // move to an index where the top item is not visible - gridview->setContentY(firstVisibleIndex * 20.0); - gridview->setCurrentIndex(firstVisibleIndex); - qApp->processEvents(); - QTRY_COMPARE(gridview->currentIndex(), firstVisibleIndex); - QQuickItem *item = findItem(contentItem, "wrapper", firstVisibleIndex); - QVERIFY(item); - QCOMPARE(item->y(), gridview->contentY()); - - QList > newData; - for (int i=0; iproperty("count").toInt(), model.count()); - - // now, moving to the top of the view should position the inserted items correctly - int itemsOffsetAfterMove = (insertCount / 3) * -60.0; - gridview->setCurrentIndex(0); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentY(), 0.0 + itemsOffsetAfterMove); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QCOMPARE(item->x(), (i%3)*80.0); - QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - } - - delete canvas; -} - -void tst_QQuickGridView::insertBeforeVisible_data() -{ - QTest::addColumn("insertIndex"); - QTest::addColumn("insertCount"); - QTest::addColumn("cacheBuffer"); - - QTest::newRow("insert 1 at 0, 0 buffer") << 0 << 1 << 0; - QTest::newRow("insert 1 at 0, 100 buffer") << 0 << 1 << 100; - QTest::newRow("insert 1 at 0, 500 buffer") << 0 << 1 << 500; - - QTest::newRow("insert 1 at 1, 0 buffer") << 1 << 1 << 0; - QTest::newRow("insert 1 at 1, 100 buffer") << 1 << 1 << 100; - QTest::newRow("insert 1 at 1, 500 buffer") << 1 << 1 << 500; - - QTest::newRow("insert multiple at 0, 0 buffer") << 0 << 6 << 0; - QTest::newRow("insert multiple at 0, 100 buffer") << 0 << 6 << 100; - QTest::newRow("insert multiple at 0, 500 buffer") << 0 << 6 << 500; - - QTest::newRow("insert multiple at 1, 0 buffer") << 1 << 6 << 0; - QTest::newRow("insert multiple at 1, 100 buffer") << 1 << 6 << 100; - QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 6 << 500; -} - -void tst_QQuickGridView::removed() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.removeItem(1); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - - // Checks that onRemove is called - QString removed = canvas->rootObject()->property("removed").toString(); - QTRY_COMPARE(removed, QString("Item1")); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - // Remove first item (which is the current item); - model.removeItem(0); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - // Remove items not visible - model.removeItem(25); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - // Remove items before visible - gridview->setContentY(120); - gridview->setCurrentIndex(10); - - // Setting currentIndex above shouldn't cause view to scroll - QTRY_COMPARE(gridview->contentY(), 120.0); - - model.removeItem(1); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - // Confirm items positioned correctly - for (int i = 6; i < 18; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - // Remove currentIndex - QQuickItem *oldCurrent = gridview->currentItem(); - model.removeItem(9); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - QTRY_COMPARE(gridview->currentIndex(), 9); - QTRY_VERIFY(gridview->currentItem() != oldCurrent); - - gridview->setContentY(0); - // let transitions settle. - QTest::qWait(300); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60); - } - - // remove item outside current view. - gridview->setCurrentIndex(32); - gridview->setContentY(240); - - model.removeItem(30); - QTRY_VERIFY(gridview->currentIndex() == 31); - - // remove current item beyond visible items. - gridview->setCurrentIndex(20); - gridview->setContentY(0); - model.removeItem(20); - - QTRY_COMPARE(gridview->currentIndex(), 20); - QTRY_VERIFY(gridview->currentItem() != 0); - - // remove item before current, but visible - gridview->setCurrentIndex(8); - gridview->setContentY(240); - oldCurrent = gridview->currentItem(); - model.removeItem(6); - - QTRY_COMPARE(gridview->currentIndex(), 7); - QTRY_VERIFY(gridview->currentItem() == oldCurrent); - - delete canvas; -} - -void tst_QQuickGridView::addOrRemoveBeforeVisible() -{ - // QTBUG-21588: ensure re-layout is done on grid after adding or removing - // items from before the visible area - - QFETCH(bool, doAdd); - QFETCH(qreal, newTopContentY); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "textName", 0); - QTRY_COMPARE(name->text(), QString("Item0")); - - gridview->setCurrentIndex(0); - qApp->processEvents(); - - // scroll down until item 0 is no longer drawn - // (bug not triggered if we just move using content y, since that doesn't - // refill and change the visible items) - gridview->setCurrentIndex(24); - qApp->processEvents(); - - QTRY_COMPARE(gridview->currentIndex(), 24); - QTRY_COMPARE(gridview->contentY(), 220.0); - - QTest::qWait(100); // wait for refill to complete - QTRY_VERIFY(!findItem(contentItem, "wrapper", 0)); // 0 shouldn't be visible - - if (doAdd) { - model.insertItem(0, "New Item", "New Item number"); - QTRY_COMPARE(gridview->count(), 31); - } else { - model.removeItem(0); - QTRY_COMPARE(gridview->count(), 29); - } - - // scroll back up and item 0 should be gone - gridview->setCurrentIndex(0); - qApp->processEvents(); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentY(), newTopContentY); - - name = findItem(contentItem, "textName", 0); - if (doAdd) - QCOMPARE(name->text(), QString("New Item")); - else - QCOMPARE(name->text(), QString("Item1")); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QTRY_VERIFY(findItem(contentItem, "wrapper", i)); - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_VERIFY(item->x() == (i%3)*80); - QTRY_VERIFY(item->y() == (i/3)*60 + newTopContentY); - } - - delete canvas; -} - -void tst_QQuickGridView::addOrRemoveBeforeVisible_data() -{ - QTest::addColumn("doAdd"); - QTest::addColumn("newTopContentY"); - - QTest::newRow("add") << true << -60.0; - QTest::newRow("remove") << false << 0.0; -} - -void tst_QQuickGridView::clear() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QVERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - - model.clear(); - - QVERIFY(gridview->count() == 0); - QVERIFY(gridview->currentItem() == 0); - QVERIFY(gridview->contentY() == 0); - QVERIFY(gridview->currentIndex() == -1); - - // confirm sanity when adding an item to cleared list - model.addItem("New", "1"); - QTRY_COMPARE(gridview->count(), 1); - QVERIFY(gridview->currentItem() != 0); - QVERIFY(gridview->currentIndex() == 0); - - delete canvas; -} - -void tst_QQuickGridView::moved() -{ - QFETCH(qreal, contentY); - QFETCH(int, from); - QFETCH(int, to); - QFETCH(int, count); - QFETCH(qreal, itemsOffsetAfterMove); - - QQuickText *name; - QQuickText *number; - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *currentItem = gridview->currentItem(); - QTRY_VERIFY(currentItem != 0); - - gridview->setContentY(contentY); - model.moveItems(from, to, count); - - // wait for items to move - QTest::qWait(300); - - // Confirm items positioned correctly and indexes correct - int firstVisibleIndex = qCeil(contentY / 60.0) * 3; - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - if (i >= firstVisibleIndex + 18) // index has moved out of view - continue; - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); - - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - - // current index should have been updated - if (item == currentItem) - QTRY_COMPARE(gridview->currentIndex(), i); - } - - delete canvas; -} - -void tst_QQuickGridView::moved_data() -{ - QTest::addColumn("contentY"); - QTest::addColumn("from"); - QTest::addColumn("to"); - QTest::addColumn("count"); - QTest::addColumn("itemsOffsetAfterMove"); - - // model starts with 30 items, each 80x60, in area 240x320 - // 18 items should be visible at a time - - QTest::newRow("move 1 forwards, within visible items") - << 0.0 - << 1 << 8 << 1 - << 0.0; - - QTest::newRow("move 1 forwards, from non-visible -> visible") - << 120.0 // show 6-23 - << 1 << 23 << 1 - << 0.0; // only 1 item was removed from the 1st row, so it doesn't move down - - QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") - << 120.0 // // show 6-23 - << 0 << 6 << 1 - << 0.0; // only 1 item was removed from the 1st row, so it doesn't move down - - QTest::newRow("move 1 forwards, from visible -> non-visible") - << 0.0 - << 1 << 20 << 1 - << 0.0; - - QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)") - << 0.0 - << 0 << 20 << 1 - << 0.0; - - - QTest::newRow("move 1 backwards, within visible items") - << 0.0 - << 10 << 5 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, within visible items (to first index)") - << 0.0 - << 10 << 0 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from non-visible -> visible") - << 0.0 - << 28 << 8 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)") - << 0.0 - << 29 << 14 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from visible -> non-visible") - << 120.0 // show 6-23 - << 7 << 1 << 1 - << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move - - QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)") - << 120.0 // show 6-23 - << 7 << 0 << 1 - << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move - - - QTest::newRow("move multiple forwards, within visible items") - << 0.0 - << 0 << 5 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, within visible items (move first item)") - << 0.0 - << 10 << 0 << 3 - << 0.0; - - QTest::newRow("move multiple forwards, before visible items") - << 120.0 // show 6-23 - << 3 << 4 << 3 // 3, 4, 5 move to after 6 - << 60.0; // row of 3,4,5 has moved down - - QTest::newRow("move multiple forwards, from non-visible -> visible") - << 120.0 // show 6-23 - << 1 << 6 << 3 - << 60.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is - - QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)") - << 120.0 // show 6-23 - << 0 << 6 << 3 - << 60.0; // top row moved and shifted to below 3rd row, all items should shift down by 1 row - - QTest::newRow("move multiple forwards, from visible -> non-visible") - << 0.0 - << 1 << 16 << 3 - << 0.0; - - QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)") - << 0.0 - << 0 << 16 << 3 - << 0.0; - - - QTest::newRow("move multiple backwards, within visible items") - << 0.0 - << 4 << 1 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from non-visible -> visible") - << 0.0 - << 20 << 4 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)") - << 0.0 - << 27 << 10 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from visible -> non-visible") - << 120.0 // show 6-23 - << 16 << 1 << 3 - << -60.0; // to minimize movement, items are added above visible area, all items move up by 1 row - - QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)") - << 120.0 // show 6-23 - << 16 << 0 << 3 - << -60.0; // 16,17,18 move to above item 0, all items move up by 1 row -} - -struct ListChange { - enum { Inserted, Removed, Moved, SetCurrent } type; - int index; - int count; - int to; // Move - - static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; } - static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; } - static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; } - static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; } -}; -Q_DECLARE_METATYPE(QList) - -void tst_QQuickGridView::multipleChanges() -{ - QFETCH(int, startCount); - QFETCH(QList, changes); - QFETCH(int, newCount); - QFETCH(int, newCurrentIndex); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < startCount; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - for (int i=0; i > items; - for (int j=changes[i].index; jsetCurrentIndex(changes[i].index); - break; - } - } - - QTRY_COMPARE(gridview->count(), newCount); - QCOMPARE(gridview->count(), model.count()); - QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex); - - QQuickText *name; - QQuickText *number; - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i=0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - delete canvas; -} - -void tst_QQuickGridView::multipleChanges_data() -{ - QTest::addColumn("startCount"); - QTest::addColumn >("changes"); - QTest::addColumn("newCount"); - QTest::addColumn("newCurrentIndex"); - - QList changes; - - for (int i=1; i<30; i++) - changes << ListChange::remove(0); - QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0; - - changes << ListChange::remove(0); - QTest::newRow("remove all") << 30 << changes << 0 << -1; - - changes.clear(); - changes << ListChange::setCurrent(29); - for (int i=29; i>0; i--) - changes << ListChange::remove(i); - QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0; - - QTest::newRow("remove then insert at 0") << 10 << (QList() - << ListChange::remove(0, 1) - << ListChange::insert(0, 1) - ) << 10 << 1; - - QTest::newRow("remove then insert at non-zero index") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::remove(2, 1) - << ListChange::insert(2, 1) - ) << 10 << 3; - - QTest::newRow("remove current then insert below it") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::remove(1, 3) - << ListChange::insert(2, 2) - ) << 9 << 1; - - QTest::newRow("remove current index then move it down") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::remove(1, 3) - << ListChange::move(1, 5, 1) - ) << 7 << 5; - - QTest::newRow("remove current index then move it up") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::remove(4, 3) - << ListChange::move(4, 1, 1) - ) << 7 << 1; - - - QTest::newRow("insert multiple times") << 0 << (QList() - << ListChange::insert(0, 2) - << ListChange::insert(0, 4) - << ListChange::insert(0, 6) - ) << 12 << 10; - - QTest::newRow("insert multiple times with current index changes") << 0 << (QList() - << ListChange::insert(0, 2) - << ListChange::insert(0, 4) - << ListChange::insert(0, 6) - << ListChange::setCurrent(3) - << ListChange::insert(3, 2) - ) << 14 << 5; - - QTest::newRow("insert and remove all") << 0 << (QList() - << ListChange::insert(0, 30) - << ListChange::remove(0, 30) - ) << 0 << -1; - - QTest::newRow("insert and remove current") << 30 << (QList() - << ListChange::insert(1) - << ListChange::setCurrent(1) - << ListChange::remove(1) - ) << 30 << 1; - - QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList() - << ListChange::insert(0, 10) - << ListChange::remove(5, 10) - ) << 10 << 5; - - QTest::newRow("insert multiple, then move new items to end") << 10 << (QList() - << ListChange::insert(0, 3) - << ListChange::move(0, 10, 3) - ) << 13 << 0; - - QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList() - << ListChange::insert(0, 3) - << ListChange::move(0, 8, 5) - ) << 13 << 11; - - QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList() - << ListChange::setCurrent(9) - << ListChange::insert(10, 3) - << ListChange::move(8, 0, 5) - ) << 13 << 1; - - - QTest::newRow("move back and forth to same index") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::move(1, 2, 2) - << ListChange::move(2, 1, 2) - ) << 10 << 1; - - QTest::newRow("move forwards then back") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::move(1, 2, 3) - << ListChange::move(3, 0, 5) - ) << 10 << 0; - - QTest::newRow("move current, then remove it") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 0, 1) - << ListChange::remove(0) - ) << 9 << 0; - - QTest::newRow("move current, then insert before it") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 0, 1) - << ListChange::insert(0) - ) << 11 << 1; - - QTest::newRow("move multiple, then remove them") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::move(5, 1, 3) - << ListChange::remove(1, 3) - ) << 7 << 1; - - QTest::newRow("move multiple, then insert before them") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 1, 3) - << ListChange::insert(1, 5) - ) << 15 << 6; - - QTest::newRow("move multiple, then insert after them") << 10 << (QList() - << ListChange::setCurrent(3) - << ListChange::move(0, 1, 2) - << ListChange::insert(3, 5) - ) << 15 << 8; - - - QTest::newRow("clear current") << 0 << (QList() - << ListChange::insert(0, 5) - << ListChange::setCurrent(-1) - << ListChange::remove(0, 5) - << ListChange::insert(0, 5) - ) << 5 << -1; -} - - -void tst_QQuickGridView::swapWithFirstItem() -{ - // QTBUG_9697 - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - // ensure content position is stable - gridview->setContentY(0); - model.moveItem(10, 0); - QTRY_VERIFY(gridview->contentY() == 0); - - delete canvas; -} - -void tst_QQuickGridView::currentIndex() -{ - TestModel model; - for (int i = 0; i < 60; i++) - model.addItem("Item" + QString::number(i), QString::number(i)); - - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - canvas->show(); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - QString filename(TESTDATA("gridview-initCurrent.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QVERIFY(gridview != 0); - QTRY_VERIFY(!QQuickItemPrivate::get(gridview)->polishScheduled); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - - // current item should be third item - QCOMPARE(gridview->currentIndex(), 35); - QCOMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 35)); - QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y()); - QCOMPARE(gridview->contentY(), 400.0); - - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), 36); - gridview->moveCurrentIndexDown(); - QCOMPARE(gridview->currentIndex(), 39); - gridview->moveCurrentIndexUp(); - QCOMPARE(gridview->currentIndex(), 36); - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), 35); - - // wait until motion stops - QTRY_VERIFY(gridview->verticalVelocity() == 0.0); - - // no wrap - gridview->setCurrentIndex(0); - QCOMPARE(gridview->currentIndex(), 0); - // confirm that the velocity is updated - QTRY_VERIFY(gridview->verticalVelocity() != 0.0); - - gridview->moveCurrentIndexUp(); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->setCurrentIndex(model.count()-1); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - gridview->moveCurrentIndexDown(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - // with wrap - gridview->setWrapEnabled(true); - - gridview->setCurrentIndex(0); - QCOMPARE(gridview->currentIndex(), 0); - - gridview->moveCurrentIndexLeft(); - QCOMPARE(gridview->currentIndex(), model.count()-1); - - qApp->processEvents(); - QTRY_COMPARE(gridview->contentY(), 880.0); - - gridview->moveCurrentIndexRight(); - QCOMPARE(gridview->currentIndex(), 0); - - QTRY_COMPARE(gridview->contentY(), 0.0); - - - // footer should become visible if it is out of view, and then current index moves to the first row - canvas->rootObject()->setProperty("showFooter", true); - QTRY_VERIFY(gridview->footerItem()); - gridview->setCurrentIndex(model.count()-3); - QTRY_VERIFY(gridview->footerItem()->y() > gridview->contentY() + gridview->height()); - gridview->setCurrentIndex(model.count()-2); - QTRY_COMPARE(gridview->contentY() + gridview->height(), (60.0 * model.count()/3) + gridview->footerItem()->height()); - canvas->rootObject()->setProperty("showFooter", false); - - // header should become visible if it is out of view, and then current index moves to the last row - canvas->rootObject()->setProperty("showHeader", true); - QTRY_VERIFY(gridview->headerItem()); - gridview->setCurrentIndex(3); - QTRY_VERIFY(gridview->headerItem()->y() + gridview->headerItem()->height() < gridview->contentY()); - gridview->setCurrentIndex(1); - QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height()); - canvas->rootObject()->setProperty("showHeader", false); - - - // Test keys - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - - gridview->setCurrentIndex(0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 3); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 0); - - // hold down Key_Down - for (int i=0; i<(model.count() / 3) - 1; i++) { - QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*3 + 3); - } - QTest::keyRelease(canvas, Qt::Key_Down); - QTRY_COMPARE(gridview->currentIndex(), 57); - QTRY_COMPARE(gridview->contentY(), 880.0); - - // hold down Key_Up - for (int i=(model.count() / 3) - 1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*3 - 3); - } - QTest::keyRelease(canvas, Qt::Key_Up); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentY(), 0.0); - - - gridview->setFlow(QQuickGridView::TopToBottom); - - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(qGuiApp->focusWindow() == canvas); - qApp->processEvents(); - - QTest::keyClick(canvas, Qt::Key_Right); - QCOMPARE(gridview->currentIndex(), 5); - - QTest::keyClick(canvas, Qt::Key_Left); - QCOMPARE(gridview->currentIndex(), 0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 1); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 0); - - // hold down Key_Right - for (int i=0; i<(model.count() / 5) - 1; i++) { - QTest::simulateEvent(canvas, true, Qt::Key_Right, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*5 + 5); - } - - QTest::keyRelease(canvas, Qt::Key_Right); - QTRY_COMPARE(gridview->currentIndex(), 55); - QTRY_COMPARE(gridview->contentX(), 720.0); - - // hold down Key_Left - for (int i=(model.count() / 5) - 1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Left, Qt::NoModifier, "", true); - QTRY_COMPARE(gridview->currentIndex(), i*5 - 5); - } - QTest::keyRelease(canvas, Qt::Key_Left); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->contentX(), 0.0); - - - // turn off auto highlight - gridview->setHighlightFollowsCurrentItem(false); - QVERIFY(gridview->highlightFollowsCurrentItem() == false); - QVERIFY(gridview->highlightItem()); - qreal hlPosX = gridview->highlightItem()->x(); - qreal hlPosY = gridview->highlightItem()->y(); - - gridview->setCurrentIndex(5); - QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX); - QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); - - // insert item before currentIndex - gridview->setCurrentIndex(28); - model.insertItem(0, "Foo", "1111"); - QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); - - // check removing highlight by setting currentIndex to -1; - gridview->setCurrentIndex(-1); - - QCOMPARE(gridview->currentIndex(), -1); - QVERIFY(!gridview->highlightItem()); - QVERIFY(!gridview->currentItem()); - - gridview->setHighlightFollowsCurrentItem(true); - - gridview->setFlow(QQuickGridView::LeftToRight); - gridview->setLayoutDirection(Qt::RightToLeft); - - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - qApp->processEvents(); - - gridview->setCurrentIndex(35); - - QTest::keyClick(canvas, Qt::Key_Right); - QCOMPARE(gridview->currentIndex(), 34); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(gridview->currentIndex(), 37); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(gridview->currentIndex(), 34); - - QTest::keyClick(canvas, Qt::Key_Left); - QCOMPARE(gridview->currentIndex(), 35); - - - // turn off auto highlight - gridview->setHighlightFollowsCurrentItem(false); - QVERIFY(gridview->highlightFollowsCurrentItem() == false); - QVERIFY(gridview->highlightItem()); - hlPosX = gridview->highlightItem()->x(); - hlPosY = gridview->highlightItem()->y(); - - gridview->setCurrentIndex(5); - QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX); - QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); - - // insert item before currentIndex - gridview->setCurrentIndex(28); - model.insertItem(0, "Foo", "1111"); - QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); - - // check removing highlight by setting currentIndex to -1; - gridview->setCurrentIndex(-1); - - QCOMPARE(gridview->currentIndex(), -1); - QVERIFY(!gridview->highlightItem()); - QVERIFY(!gridview->currentItem()); - - delete canvas; -} - -void tst_QQuickGridView::noCurrentIndex() -{ - TestModel model; - for (int i = 0; i < 60; i++) - model.addItem("Item" + QString::number(i), QString::number(i)); - - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - QString filename(TESTDATA("gridview-noCurrent.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QVERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - - // current index should be -1 - QCOMPARE(gridview->currentIndex(), -1); - QVERIFY(!gridview->currentItem()); - QVERIFY(!gridview->highlightItem()); - QCOMPARE(gridview->contentY(), 0.0); - - gridview->setCurrentIndex(5); - QCOMPARE(gridview->currentIndex(), 5); - QVERIFY(gridview->currentItem()); - QVERIFY(gridview->highlightItem()); - - delete canvas; -} - -void tst_QQuickGridView::changeFlow() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i)); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal((i%3)*80)); - QTRY_COMPARE(item->y(), qreal((i/3)*60)); - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - ctxt->setContextProperty("testTopToBottom", QVariant(true)); - - // Confirm items positioned correctly and indexes correct - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal((i/5)*80)); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - ctxt->setContextProperty("testRightToLeft", QVariant(true)); - - // Confirm items positioned correctly and indexes correct - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - gridview->setContentX(100); - QTRY_COMPARE(gridview->contentX(), 100.); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - QTRY_COMPARE(gridview->contentX(), 0.); - - // Confirm items positioned correctly and indexes correct - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80)); - QTRY_COMPARE(item->y(), qreal((i/3)*60)); - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - delete canvas; -} - -void tst_QQuickGridView::defaultValues() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview3.qml"))); - QQuickGridView *obj = qobject_cast(c.create()); - - QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->model() == QVariant()); - QTRY_VERIFY(obj->delegate() == 0); - QTRY_COMPARE(obj->currentIndex(), -1); - QTRY_VERIFY(obj->currentItem() == 0); - QTRY_COMPARE(obj->count(), 0); - QTRY_VERIFY(obj->highlight() == 0); - QTRY_VERIFY(obj->highlightItem() == 0); - QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true); - QTRY_VERIFY(obj->flow() == 0); - QTRY_COMPARE(obj->isWrapEnabled(), false); - QTRY_COMPARE(obj->cacheBuffer(), 0); - QTRY_COMPARE(obj->cellWidth(), qreal(100)); //### Should 100 be the default? - QTRY_COMPARE(obj->cellHeight(), qreal(100)); - delete obj; -} - -void tst_QQuickGridView::properties() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview2.qml"))); - QQuickGridView *obj = qobject_cast(c.create()); - - QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->model() != QVariant()); - QTRY_VERIFY(obj->delegate() != 0); - QTRY_COMPARE(obj->currentIndex(), 0); - QTRY_VERIFY(obj->currentItem() != 0); - QTRY_COMPARE(obj->count(), 4); - QTRY_VERIFY(obj->highlight() != 0); - QTRY_VERIFY(obj->highlightItem() != 0); - QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false); - QTRY_VERIFY(obj->flow() == 0); - QTRY_COMPARE(obj->isWrapEnabled(), true); - QTRY_COMPARE(obj->cacheBuffer(), 200); - QTRY_COMPARE(obj->cellWidth(), qreal(100)); - QTRY_COMPARE(obj->cellHeight(), qreal(100)); - delete obj; -} - -void tst_QQuickGridView::propertyChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); - QTRY_VERIFY(gridView); - - QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged())); - QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged())); - QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged())); - QSignalSpy flowSpy(gridView, SIGNAL(flowChanged())); - - QTRY_COMPARE(gridView->isWrapEnabled(), true); - QTRY_COMPARE(gridView->cacheBuffer(), 10); - QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); - - gridView->setWrapEnabled(false); - gridView->setCacheBuffer(3); - gridView->setFlow(QQuickGridView::TopToBottom); - - QTRY_COMPARE(gridView->isWrapEnabled(), false); - QTRY_COMPARE(gridView->cacheBuffer(), 3); - QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); - - QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); - QTRY_COMPARE(cacheBufferSpy.count(),1); - QTRY_COMPARE(flowSpy.count(),1); - - gridView->setWrapEnabled(false); - gridView->setCacheBuffer(3); - gridView->setFlow(QQuickGridView::TopToBottom); - - QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); - QTRY_COMPARE(cacheBufferSpy.count(),1); - QTRY_COMPARE(flowSpy.count(),1); - - gridView->setFlow(QQuickGridView::LeftToRight); - QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); - - gridView->setWrapEnabled(true); - gridView->setCacheBuffer(5); - gridView->setLayoutDirection(Qt::RightToLeft); - - QTRY_COMPARE(gridView->isWrapEnabled(), true); - QTRY_COMPARE(gridView->cacheBuffer(), 5); - QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft); - - QTRY_COMPARE(keyNavigationWrapsSpy.count(),2); - QTRY_COMPARE(cacheBufferSpy.count(),2); - QTRY_COMPARE(layoutSpy.count(),1); - QTRY_COMPARE(flowSpy.count(),2); - - gridView->setWrapEnabled(true); - gridView->setCacheBuffer(5); - gridView->setLayoutDirection(Qt::RightToLeft); - - QTRY_COMPARE(keyNavigationWrapsSpy.count(),2); - QTRY_COMPARE(cacheBufferSpy.count(),2); - QTRY_COMPARE(layoutSpy.count(),1); - QTRY_COMPARE(flowSpy.count(),2); - - gridView->setFlow(QQuickGridView::TopToBottom); - QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); - QTRY_COMPARE(flowSpy.count(),3); - - gridView->setFlow(QQuickGridView::TopToBottom); - QTRY_COMPARE(flowSpy.count(),3); - - delete canvas; -} - -void tst_QQuickGridView::componentChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); - QTRY_VERIFY(gridView); - - QDeclarativeComponent component(canvas->engine()); - component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); - - QDeclarativeComponent delegateComponent(canvas->engine()); - delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); - - QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged())); - QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged())); - QSignalSpy headerSpy(gridView, SIGNAL(headerChanged())); - QSignalSpy footerSpy(gridView, SIGNAL(footerChanged())); - - gridView->setHighlight(&component); - gridView->setDelegate(&delegateComponent); - gridView->setHeader(&component); - gridView->setFooter(&component); - - QTRY_COMPARE(gridView->highlight(), &component); - QTRY_COMPARE(gridView->delegate(), &delegateComponent); - QTRY_COMPARE(gridView->header(), &component); - QTRY_COMPARE(gridView->footer(), &component); - - QTRY_COMPARE(highlightSpy.count(),1); - QTRY_COMPARE(delegateSpy.count(),1); - QTRY_COMPARE(headerSpy.count(),1); - QTRY_COMPARE(footerSpy.count(),1); - - gridView->setHighlight(&component); - gridView->setDelegate(&delegateComponent); - gridView->setHeader(&component); - gridView->setFooter(&component); - - QTRY_COMPARE(highlightSpy.count(),1); - QTRY_COMPARE(delegateSpy.count(),1); - QTRY_COMPARE(headerSpy.count(),1); - QTRY_COMPARE(footerSpy.count(),1); - - delete canvas; -} - -void tst_QQuickGridView::modelChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); - QTRY_VERIFY(gridView); - - QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); - QTRY_VERIFY(alternateModel); - QVariant modelVariant = QVariant::fromValue(alternateModel); - QSignalSpy modelSpy(gridView, SIGNAL(modelChanged())); - - gridView->setModel(modelVariant); - QTRY_COMPARE(gridView->model(), modelVariant); - QTRY_COMPARE(modelSpy.count(),1); - - gridView->setModel(modelVariant); - QTRY_COMPARE(modelSpy.count(),1); - - gridView->setModel(QVariant()); - QTRY_COMPARE(modelSpy.count(),2); - delete canvas; -} - -void tst_QQuickGridView::positionViewAtIndex() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.); - QTRY_COMPARE(item->y(), (i/3)*60.); - } - - // Position on a currently visible item - gridview->positionViewAtIndex(4, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->indexAt(120, 90), 4); - QTRY_COMPARE(gridview->contentY(), 60.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.); - QTRY_COMPARE(item->y(), (i/3)*60.); - } - - // Position on an item beyond the visible items - gridview->positionViewAtIndex(21, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->indexAt(40, 450), 21); - QTRY_COMPARE(gridview->contentY(), 420.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.); - QTRY_COMPARE(item->y(), (i/3)*60.); - } - - // Position on an item that would leave empty space if positioned at the top - gridview->positionViewAtIndex(31, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->indexAt(120, 630), 31); - QTRY_COMPARE(gridview->contentY(), 520.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.); - QTRY_COMPARE(item->y(), (i/3)*60.); - } - - // Position at the beginning again - gridview->positionViewAtIndex(0, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->indexAt(0, 0), 0); - QTRY_COMPARE(gridview->indexAt(40, 30), 0); - QTRY_COMPARE(gridview->indexAt(80, 60), 4); - QTRY_COMPARE(gridview->contentY(), 0.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.); - QTRY_COMPARE(item->y(), (i/3)*60.); - } - - // Position at End - gridview->positionViewAtIndex(30, QQuickGridView::End); - QTRY_COMPARE(gridview->contentY(), 340.); - - // Position in Center - gridview->positionViewAtIndex(15, QQuickGridView::Center); - QTRY_COMPARE(gridview->contentY(), 170.); - - // Ensure at least partially visible - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentY(), 170.); - - gridview->setContentY(302); - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentY(), 302.); - - gridview->setContentY(360); - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentY(), 300.); - - gridview->setContentY(60); - gridview->positionViewAtIndex(20, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentY(), 60.); - - gridview->setContentY(20); - gridview->positionViewAtIndex(20, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentY(), 100.); - - // Ensure completely visible - gridview->setContentY(120); - gridview->positionViewAtIndex(20, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentY(), 120.); - - gridview->setContentY(302); - gridview->positionViewAtIndex(15, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentY(), 300.); - - gridview->setContentY(60); - gridview->positionViewAtIndex(20, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentY(), 100.); - - // Test for Top To Bottom layout - ctxt->setContextProperty("testTopToBottom", QVariant(true)); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), (i/5)*80.); - QTRY_COMPARE(item->y(), (i%5)*60.); - } - - // Position at End - gridview->positionViewAtIndex(30, QQuickGridView::End); - QTRY_COMPARE(gridview->contentX(), 320.); - QTRY_COMPARE(gridview->contentY(), 0.); - - // Position in Center - gridview->positionViewAtIndex(15, QQuickGridView::Center); - QTRY_COMPARE(gridview->contentX(), 160.); - - // Ensure at least partially visible - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), 160.); - - gridview->setContentX(170); - gridview->positionViewAtIndex(25, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), 170.); - - gridview->positionViewAtIndex(30, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), 320.); - - gridview->setContentX(170); - gridview->positionViewAtIndex(25, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentX(), 240.); - - // positionViewAtBeginning - gridview->positionViewAtBeginning(); - QTRY_COMPARE(gridview->contentX(), 0.); - - gridview->setContentX(80); - canvas->rootObject()->setProperty("showHeader", true); - gridview->positionViewAtBeginning(); - QTRY_COMPARE(gridview->contentX(), -30.); - - // positionViewAtEnd - gridview->positionViewAtEnd(); - QTRY_COMPARE(gridview->contentX(), 400.); // 8*80 - 240 (8 columns) - - gridview->setContentX(80); - canvas->rootObject()->setProperty("showFooter", true); - gridview->positionViewAtEnd(); - QTRY_COMPARE(gridview->contentX(), 430.); - - // set current item to outside visible view, position at beginning - // and ensure highlight moves to current item - gridview->setCurrentIndex(6); - gridview->positionViewAtBeginning(); - QTRY_COMPARE(gridview->contentX(), -30.); - QVERIFY(gridview->highlightItem()); - QCOMPARE(gridview->highlightItem()->x(), 80.); - - delete canvas; -} - -void tst_QQuickGridView::snapping() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - gridview->setHeight(220); - QCOMPARE(gridview->height(), 220.); - - gridview->positionViewAtIndex(12, QQuickGridView::Visible); - QCOMPARE(gridview->contentY(), 80.); - - gridview->setContentY(0); - QCOMPARE(gridview->contentY(), 0.); - - gridview->setSnapMode(QQuickGridView::SnapToRow); - QCOMPARE(gridview->snapMode(), QQuickGridView::SnapToRow); - - gridview->positionViewAtIndex(12, QQuickGridView::Visible); - QCOMPARE(gridview->contentY(), 60.); - - gridview->positionViewAtIndex(15, QQuickGridView::End); - QCOMPARE(gridview->contentY(), 120.); - - delete canvas; - -} - -void tst_QQuickGridView::mirroring() -{ - QQuickView *canvasA = createView(); - canvasA->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml"))); - QQuickGridView *gridviewA = findItem(canvasA->rootObject(), "view"); - QTRY_VERIFY(gridviewA != 0); - - QQuickView *canvasB = createView(); - canvasB->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml"))); - QQuickGridView *gridviewB = findItem(canvasB->rootObject(), "view"); - QTRY_VERIFY(gridviewA != 0); - qApp->processEvents(); - - QList objectNames; - objectNames << "item1" << "item2"; // << "item3" - - gridviewA->setProperty("layoutDirection", Qt::LeftToRight); - gridviewB->setProperty("layoutDirection", Qt::RightToLeft); - QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection()); - - // LTR != RTL - foreach (const QString objectName, objectNames) - QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); - - gridviewA->setProperty("layoutDirection", Qt::LeftToRight); - gridviewB->setProperty("layoutDirection", Qt::LeftToRight); - - // LTR == LTR - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); - - QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection()); - QQuickItemPrivate::get(gridviewB)->setLayoutMirror(true); - QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection()); - - // LTR != LTR+mirror - foreach (const QString objectName, objectNames) - QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); - - gridviewA->setProperty("layoutDirection", Qt::RightToLeft); - - // RTL == LTR+mirror - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); - - gridviewB->setProperty("layoutDirection", Qt::RightToLeft); - - // RTL != RTL+mirror - foreach (const QString objectName, objectNames) - QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); - - gridviewA->setProperty("layoutDirection", Qt::LeftToRight); - - // LTR == RTL+mirror - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); - - delete canvasA; - delete canvasB; -} - -void tst_QQuickGridView::positionViewAtIndex_rightToLeft() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testTopToBottom", QVariant(true)); - ctxt->setContextProperty("testRightToLeft", QVariant(true)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - } - - // Position on a currently visible item - gridview->positionViewAtIndex(6, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->contentX(), -320.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - } - - // Position on an item beyond the visible items - gridview->positionViewAtIndex(21, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->contentX(), -560.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - } - - // Position on an item that would leave empty space if positioned at the top - gridview->positionViewAtIndex(31, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->contentX(), -640.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - } - - // Position at the beginning again - gridview->positionViewAtIndex(0, QQuickGridView::Beginning); - QTRY_COMPARE(gridview->contentX(), -240.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); - QTRY_COMPARE(item->y(), qreal((i%5)*60)); - } - - // Position at End - gridview->positionViewAtIndex(30, QQuickGridView::End); - QTRY_COMPARE(gridview->contentX(), -560.); - - // Position in Center - gridview->positionViewAtIndex(15, QQuickGridView::Center); - QTRY_COMPARE(gridview->contentX(), -400.); - - // Ensure at least partially visible - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), -400.); - - gridview->setContentX(-555.); - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), -555.); - - gridview->setContentX(-239); - gridview->positionViewAtIndex(15, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), -320.); - - gridview->setContentX(-239); - gridview->positionViewAtIndex(20, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), -400.); - - gridview->setContentX(-640); - gridview->positionViewAtIndex(20, QQuickGridView::Visible); - QTRY_COMPARE(gridview->contentX(), -560.); - - // Ensure completely visible - gridview->setContentX(-400); - gridview->positionViewAtIndex(20, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentX(), -400.); - - gridview->setContentX(-315); - gridview->positionViewAtIndex(15, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentX(), -320.); - - gridview->setContentX(-640); - gridview->positionViewAtIndex(20, QQuickGridView::Contain); - QTRY_COMPARE(gridview->contentX(), -560.); - - delete canvas; -} - -void tst_QQuickGridView::resetModel() -{ - QQuickView *canvas = createView(); - - QStringList strings; - strings << "one" << "two" << "three"; - QStringListModel model(strings); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaygrid.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(gridview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(contentItem, "displayText", i); - QTRY_VERIFY(display != 0); - QTRY_COMPARE(display->text(), strings.at(i)); - } - - strings.clear(); - strings << "four" << "five" << "six" << "seven"; - model.setStringList(strings); - - QTRY_COMPARE(gridview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(contentItem, "displayText", i); - QTRY_VERIFY(display != 0); - QTRY_COMPARE(display->text(), strings.at(i)); - } - - delete canvas; -} - -void tst_QQuickGridView::enforceRange() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml"))); - qApp->processEvents(); - QVERIFY(canvas->rootObject() != 0); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0); - QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0); - QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // view should be positioned at the top of the range. - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QTRY_VERIFY(item); - QTRY_COMPARE(gridview->contentY(), -100.0); - - QQuickText *name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - QQuickText *number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - // Check currentIndex is updated when contentItem moves - gridview->setContentY(0); - QTRY_COMPARE(gridview->currentIndex(), 2); - - gridview->setCurrentIndex(5); - QTRY_COMPARE(gridview->contentY(), 100.); - - TestModel model2; - for (int i = 0; i < 5; i++) - model2.addItem("Item" + QString::number(i), ""); - - ctxt->setContextProperty("testModel", &model2); - QCOMPARE(gridview->count(), 5); - - delete canvas; -} - -void tst_QQuickGridView::enforceRange_rightToLeft() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(true)); - ctxt->setContextProperty("testTopToBottom", QVariant(true)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml"))); - qApp->processEvents(); - QVERIFY(canvas->rootObject() != 0); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QCOMPARE(gridview->preferredHighlightBegin(), 100.0); - QCOMPARE(gridview->preferredHighlightEnd(), 100.0); - QCOMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - - // view should be positioned at the top of the range. - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QTRY_COMPARE(gridview->contentX(), -140.); - QTRY_COMPARE(gridview->contentY(), 0.0); - - QQuickText *name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - QQuickText *number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - // Check currentIndex is updated when contentItem moves - gridview->setContentX(-240); - QTRY_COMPARE(gridview->currentIndex(), 3); - - gridview->setCurrentIndex(7); - QTRY_COMPARE(gridview->contentX(), -340.); - QTRY_COMPARE(gridview->contentY(), 0.0); - - TestModel model2; - for (int i = 0; i < 5; i++) - model2.addItem("Item" + QString::number(i), ""); - - ctxt->setContextProperty("testModel", &model2); - QCOMPARE(gridview->count(), 5); - - delete canvas; -} - -void tst_QQuickGridView::QTBUG_8456() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("setindex.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QTRY_COMPARE(gridview->currentIndex(), 0); - - delete canvas; -} - -void tst_QQuickGridView::manualHighlight() -{ - QQuickView *canvas = createView(); - - QString filename(TESTDATA("manual-highlight.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 0)); - QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); - - gridview->setCurrentIndex(2); - - QTRY_COMPARE(gridview->currentIndex(), 2); - QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); - - gridview->positionViewAtIndex(8, QQuickGridView::Contain); - - QTRY_COMPARE(gridview->currentIndex(), 2); - QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); - - gridview->setFlow(QQuickGridView::TopToBottom); - QTRY_COMPARE(gridview->flow(), QQuickGridView::TopToBottom); - - gridview->setCurrentIndex(0); - QTRY_COMPARE(gridview->currentIndex(), 0); - QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 0)); - QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); - QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); - - delete canvas; -} - - -void tst_QQuickGridView::footer() -{ - QFETCH(QQuickGridView::Flow, flow); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(QPointF, initialFooterPos); - QFETCH(QPointF, changedFooterPos); - QFETCH(QPointF, initialContentPos); - QFETCH(QPointF, changedContentPos); - QFETCH(QPointF, firstDelegatePos); - QFETCH(QPointF, resizeContentPos); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 7; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - gridview->setFlow(flow); - gridview->setLayoutDirection(layoutDirection); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - - QVERIFY(footer == gridview->footerItem()); - - QCOMPARE(footer->pos(), initialFooterPos); - QCOMPARE(footer->width(), 100.); - QCOMPARE(footer->height(), 30.); - QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); - - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - if (flow == QQuickGridView::LeftToRight) { - // shrink by one row - model.removeItem(2); - QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight()); - } else { - // shrink by one column - model.removeItem(2); - model.removeItem(3); - if (layoutDirection == Qt::LeftToRight) - QTRY_COMPARE(footer->x(), initialFooterPos.x() - gridview->cellWidth()); - else - QTRY_COMPARE(footer->x(), initialFooterPos.x() + gridview->cellWidth()); - } - - // remove all items - model.clear(); - - QPointF posWhenNoItems(0, 0); - if (layoutDirection == Qt::RightToLeft) - posWhenNoItems.setX(flow == QQuickGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width()); - QTRY_COMPARE(footer->pos(), posWhenNoItems); - - // if header is present, it's at a negative pos, so the footer should not move - canvas->rootObject()->setProperty("showHeader", true); - QVERIFY(findItem(contentItem, "header") != 0); - QTRY_COMPARE(footer->pos(), posWhenNoItems); - canvas->rootObject()->setProperty("showHeader", false); - - // add 30 items - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QSignalSpy footerItemSpy(gridview, SIGNAL(footerItemChanged())); - QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); - - QCOMPARE(footerItemSpy.count(), 1); - - footer = findItem(contentItem, "footer"); - QVERIFY(!footer); - footer = findItem(contentItem, "footer2"); - QVERIFY(footer); - - QVERIFY(footer == gridview->footerItem()); - - QCOMPARE(footer->pos(), changedFooterPos); - QCOMPARE(footer->width(), 50.); - QCOMPARE(footer->height(), 20.); - QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos); - - item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - gridview->positionViewAtEnd(); - footer->setHeight(10); - footer->setWidth(40); - QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos); - - delete canvas; -} - -void tst_QQuickGridView::footer_data() -{ - QTest::addColumn("flow"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("initialFooterPos"); - QTest::addColumn("changedFooterPos"); - QTest::addColumn("initialContentPos"); - QTest::addColumn("changedContentPos"); - QTest::addColumn("firstDelegatePos"); - QTest::addColumn("resizeContentPos"); - - // footer1 = 100 x 30 - // footer2 = 50 x 20 - // cells = 80 * 60 - // view width = 240 - // view height = 320 - - // footer below items, bottom left - QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight - << QPointF(0, 3 * 60) // 180 = height of 3 rows (cell height is 60) - << QPointF(0, 10 * 60) // 30 items = 10 rows - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 10 * 60 - 320 + 10); - - // footer below items, bottom right - QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft - << QPointF(240 - 100, 3 * 60) - << QPointF((240 - 100) + 50, 10 * 60) // 50 = width diff between old and new footers - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(240 - 80, 0) - << QPointF(0, 10 * 60 - 320 + 10); - - // footer to right of items - QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight - << QPointF(2 * 80, 0) // 2 columns, cell width 80 - << QPointF(6 * 80, 0) // 30 items = 6 columns - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(6 * 80 - 240 + 40, 0); - - // footer to left of items - QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft - << QPointF(-(2 * 80) - 100, 0) - << QPointF(-(6 * 80) - 50, 0) // 50 = new footer width - << QPointF(-240, 0) - << QPointF(-240, 0) // unchanged, footer change doesn't change content pos - << QPointF(-80, 0) - << QPointF(-(6 * 80) - 40, 0); -} - -void tst_QQuickGridView::header() -{ - QFETCH(QQuickGridView::Flow, flow); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(QPointF, initialHeaderPos); - QFETCH(QPointF, changedHeaderPos); - QFETCH(QPointF, initialContentPos); - QFETCH(QPointF, changedContentPos); - QFETCH(QPointF, firstDelegatePos); - QFETCH(QPointF, resizeContentPos); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QQuickView *canvas = createView(); - canvas->rootContext()->setContextProperty("testModel", &model); - canvas->rootContext()->setContextProperty("initialViewWidth", 240); - canvas->rootContext()->setContextProperty("initialViewHeight", 320); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - gridview->setFlow(flow); - gridview->setLayoutDirection(layoutDirection); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *header = findItem(contentItem, "header"); - QVERIFY(header); - - QVERIFY(header == gridview->headerItem()); - - QCOMPARE(header->pos(), initialHeaderPos); - QCOMPARE(header->width(), 100.); - QCOMPARE(header->height(), 30.); - QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); - - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - model.clear(); - QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is - - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QSignalSpy headerItemSpy(gridview, SIGNAL(headerItemChanged())); - QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); - - QCOMPARE(headerItemSpy.count(), 1); - - header = findItem(contentItem, "header"); - QVERIFY(!header); - header = findItem(contentItem, "header2"); - QVERIFY(header); - - QVERIFY(header == gridview->headerItem()); - - QCOMPARE(header->pos(), changedHeaderPos); - QCOMPARE(header->width(), 50.); - QCOMPARE(header->height(), 20.); - QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos); - - item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - header->setHeight(10); - header->setWidth(40); - QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos); - - delete canvas; - - - // QTBUG-21207 header should become visible if view resizes from initial empty size - - canvas = createView(); - canvas->rootContext()->setContextProperty("testModel", &model); - canvas->rootContext()->setContextProperty("initialViewWidth", 240); - canvas->rootContext()->setContextProperty("initialViewHeight", 320); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); - - gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - gridview->setFlow(flow); - gridview->setLayoutDirection(layoutDirection); - - gridview->setWidth(240); - gridview->setHeight(320); - QTRY_COMPARE(gridview->headerItem()->pos(), initialHeaderPos); - QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); - - delete canvas; -} - -void tst_QQuickGridView::header_data() -{ - QTest::addColumn("flow"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("initialHeaderPos"); - QTest::addColumn("changedHeaderPos"); - QTest::addColumn("initialContentPos"); - QTest::addColumn("changedContentPos"); - QTest::addColumn("firstDelegatePos"); - QTest::addColumn("resizeContentPos"); - - // header1 = 100 x 30 - // header2 = 50 x 20 - // cells = 80 x 60 - // view width = 240 - - // header above items, top left - QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, 0) - << QPointF(0, -10); - - // header above items, top right - QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft - << QPointF(240 - 100, -30) - << QPointF((240 - 100) + 50, -20) // 50 = width diff between old and new headers - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(160, 0) - << QPointF(0, -10); - - // header to left of items - QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight - << QPointF(-100, 0) - << QPointF(-50, 0) - << QPointF(-100, 0) - << QPointF(-50, 0) - << QPointF(0, 0) - << QPointF(-40, 0); - - // header to right of items - QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(-(240 - 100), 0) - << QPointF(-(240 - 50), 0) - << QPointF(-80, 0) - << QPointF(-(240 - 40), 0); -} - -void tst_QQuickGridView::resizeViewAndRepaint() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("initialHeight", 100); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // item at index 10 should not be currently visible - QVERIFY(!findItem(contentItem, "wrapper", 10)); - - gridview->setHeight(320); - QTRY_VERIFY(findItem(contentItem, "wrapper", 10)); - - gridview->setHeight(100); - QTRY_VERIFY(!findItem(contentItem, "wrapper", 10)); - - delete canvas; -} - -void tst_QQuickGridView::indexAt() -{ - QQuickView *canvas = createView(); - - TestModel model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Billy", "22345"); - model.addItem("Sam", "2945"); - model.addItem("Ben", "04321"); - model.addItem("Jim", "0780"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(gridview->count(), model.count()); - - QCOMPARE(gridview->indexAt(0, 0), 0); - QCOMPARE(gridview->indexAt(79, 59), 0); - QCOMPARE(gridview->indexAt(80, 0), 1); - QCOMPARE(gridview->indexAt(0, 60), 3); - QCOMPARE(gridview->indexAt(240, 0), -1); - - delete canvas; -} - -void tst_QQuickGridView::onAdd() -{ - QFETCH(int, initialItemCount); - QFETCH(int, itemsToAdd); - - const int delegateWidth = 50; - const int delegateHeight = 100; - TestModel model; - QQuickView *canvas = createView(); - canvas->setGeometry(0,0,5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit - - // these initial items should not trigger GridView.onAdd - for (int i=0; irootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("delegateWidth", delegateWidth); - ctxt->setContextProperty("delegateHeight", delegateHeight); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); - - QObject *object = canvas->rootObject(); - object->setProperty("width", canvas->width()); - object->setProperty("height", canvas->height()); - qApp->processEvents(); - - QList > items; - for (int i=0; i(canvas->rootObject())->count()); - qApp->processEvents(); - - QVariantList result = object->property("addedDelegates").toList(); - QTRY_COMPARE(result.count(), items.count()); - for (int i=0; i("initialItemCount"); - QTest::addColumn("itemsToAdd"); - - QTest::newRow("0, add 1") << 0 << 1; - QTest::newRow("0, add 2") << 0 << 2; - QTest::newRow("0, add 10") << 0 << 10; - - QTest::newRow("1, add 1") << 1 << 1; - QTest::newRow("1, add 2") << 1 << 2; - QTest::newRow("1, add 10") << 1 << 10; - - QTest::newRow("5, add 1") << 5 << 1; - QTest::newRow("5, add 2") << 5 << 2; - QTest::newRow("5, add 10") << 5 << 10; -} - -void tst_QQuickGridView::onRemove() -{ - QFETCH(int, initialItemCount); - QFETCH(int, indexToRemove); - QFETCH(int, removeCount); - - const int delegateWidth = 50; - const int delegateHeight = 100; - TestModel model; - for (int i=0; irootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("delegateWidth", delegateWidth); - ctxt->setContextProperty("delegateHeight", delegateHeight); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); - QObject *object = canvas->rootObject(); - - model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(model.count(), qobject_cast(canvas->rootObject())->count()); - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); - - delete canvas; -} - -void tst_QQuickGridView::onRemove_data() -{ - QTest::addColumn("initialItemCount"); - QTest::addColumn("indexToRemove"); - QTest::addColumn("removeCount"); - - QTest::newRow("remove first") << 1 << 0 << 1; - QTest::newRow("two items, remove first") << 2 << 0 << 1; - QTest::newRow("two items, remove last") << 2 << 1 << 1; - QTest::newRow("two items, remove all") << 2 << 0 << 2; - - QTest::newRow("four items, remove first") << 4 << 0 << 1; - QTest::newRow("four items, remove 0-2") << 4 << 0 << 2; - QTest::newRow("four items, remove 1-3") << 4 << 1 << 2; - QTest::newRow("four items, remove 2-4") << 4 << 2 << 2; - QTest::newRow("four items, remove last") << 4 << 3 << 1; - QTest::newRow("four items, remove all") << 4 << 0 << 4; - - QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8; - QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5; - QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6; -} - -void tst_QQuickGridView::columnCount() -{ - QQuickView canvas; - canvas.setSource(QUrl::fromLocalFile(TESTDATA("gridview4.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - QQuickGridView *view = qobject_cast(canvas.rootObject()); - - QCOMPARE(view->cellWidth(), qreal(405)/qreal(9)); - QCOMPARE(view->cellHeight(), qreal(100)); - - QList items = findItems(view, "delegate"); - QCOMPARE(items.size(), 18); - QCOMPARE(items.at(8)->y(), qreal(0)); - QCOMPARE(items.at(9)->y(), qreal(100)); -} - -void tst_QQuickGridView::margins() -{ - { - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QCOMPARE(gridview->contentX(), -30.); - QCOMPARE(gridview->xOrigin(), 0.); - - // check end bound - gridview->positionViewAtEnd(); - qreal pos = gridview->contentX(); - gridview->setContentX(pos + 80); - gridview->returnToBounds(); - QTRY_COMPARE(gridview->contentX(), pos + 50); - - // remove item before visible and check that left margin is maintained - // and xOrigin is updated - gridview->setContentX(200); - model.removeItems(0, 4); - QTest::qWait(100); - gridview->setContentX(-50); - gridview->returnToBounds(); - QCOMPARE(gridview->xOrigin(), 100.); - QTRY_COMPARE(gridview->contentX(), 70.); - - // reduce left margin - gridview->setLeftMargin(20); - QCOMPARE(gridview->xOrigin(), 100.); - QTRY_COMPARE(gridview->contentX(), 80.); - - // check end bound - gridview->positionViewAtEnd(); - QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin - pos = gridview->contentX(); - gridview->setContentX(pos + 80); - gridview->returnToBounds(); - QTRY_COMPARE(gridview->contentX(), pos + 50); - - // reduce right margin - pos = gridview->contentX(); - gridview->setRightMargin(40); - QCOMPARE(gridview->xOrigin(), 0.); - QTRY_COMPARE(gridview->contentX(), pos-10); - - delete canvas; - } - { - //RTL - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(true)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QCOMPARE(gridview->contentX(), -240+30.); - QCOMPARE(gridview->xOrigin(), 0.); - - // check end bound - gridview->positionViewAtEnd(); - qreal pos = gridview->contentX(); - gridview->setContentX(pos - 80); - gridview->returnToBounds(); - QTRY_COMPARE(gridview->contentX(), pos - 50); - - // remove item before visible and check that left margin is maintained - // and xOrigin is updated - gridview->setContentX(-400); - model.removeItems(0, 4); - QTest::qWait(100); - gridview->setContentX(-240+50); - gridview->returnToBounds(); - QCOMPARE(gridview->xOrigin(), -100.); - QTRY_COMPARE(gridview->contentX(), -240-70.); - - // reduce left margin (i.e. right side due to RTL) - pos = gridview->contentX(); - gridview->setLeftMargin(20); - QCOMPARE(gridview->xOrigin(), -100.); - QTRY_COMPARE(gridview->contentX(), -240-80.); - - // check end bound - gridview->positionViewAtEnd(); - QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin - pos = gridview->contentX(); - gridview->setContentX(pos - 80); - gridview->returnToBounds(); - QTRY_COMPARE(gridview->contentX(), pos - 50); - - // reduce right margin (i.e. left side due to RTL) - pos = gridview->contentX(); - gridview->setRightMargin(40); - QCOMPARE(gridview->xOrigin(), 0.); - QTRY_COMPARE(gridview->contentX(), pos+10); - - delete canvas; - } -} - -void tst_QQuickGridView::creationContext() -{ - QQuickView canvas; - canvas.setGeometry(0,0,240,320); - canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); - qApp->processEvents(); - - QQuickItem *rootItem = qobject_cast(canvas.rootObject()); - QVERIFY(rootItem); - QVERIFY(rootItem->property("count").toInt() > 0); - - QQuickItem *item; - QVERIFY(item = rootItem->findChild("listItem")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); - QVERIFY(item = rootItem->findChild("header")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); - QVERIFY(item = rootItem->findChild("footer")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); -} - -void tst_QQuickGridView::snapToRow_data() -{ - QTest::addColumn("flow"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("highlightRangeMode"); - QTest::addColumn("flickStart"); - QTest::addColumn("flickEnd"); - QTest::addColumn("snapAlignment"); - QTest::addColumn("endExtent"); - QTest::addColumn("startExtent"); - - QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) - << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; - - QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) - << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; - - QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) - << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0; - - QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; - - QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; - - QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0; -} - -void tst_QQuickGridView::snapToRow() -{ - QFETCH(QQuickGridView::Flow, flow); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(int, highlightRangeMode); - QFETCH(QPoint, flickStart); - QFETCH(QPoint, flickEnd); - QFETCH(qreal, snapAlignment); - QFETCH(qreal, endExtent); - QFETCH(qreal, startExtent); - - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToRow.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QTRY_VERIFY(gridview != 0); - - gridview->setFlow(flow); - gridview->setLayoutDirection(layoutDirection); - gridview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - - QQuickItem *contentItem = gridview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // confirm that a flick hits an item boundary - flick(canvas, flickStart, flickEnd, 180); - QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - if (flow == QQuickGridView::LeftToRight) - QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment); - else - QCOMPARE(qreal(fmod(gridview->contentX(),80.0)), snapAlignment); - - // flick to end - do { - flick(canvas, flickStart, flickEnd, 180); - QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight - ? !gridview->isAtYEnd() - : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning()); - - if (flow == QQuickGridView::LeftToRight) - QCOMPARE(gridview->contentY(), endExtent); - else - QCOMPARE(gridview->contentX(), endExtent); - - // flick to start - do { - flick(canvas, flickEnd, flickStart, 180); - QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops - } while (flow == QQuickGridView::LeftToRight - ? !gridview->isAtYBeginning() - : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd()); - - if (flow == QQuickGridView::LeftToRight) - QCOMPARE(gridview->contentY(), startExtent); - else - QCOMPARE(gridview->contentX(), startExtent); - - delete canvas; -} - -void tst_QQuickGridView::unaligned() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 10; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("unaligned.qml"))); - qApp->processEvents(); - - QQuickGridView *gridview = qobject_cast(canvas->rootObject()); - QVERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - - for (int i = 0; i < 10; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QVERIFY(item); - QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); - QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); - } - - // appending - for (int i = 10; i < 18; ++i) { - model.addItem("Item" + QString::number(i), ""); - QQuickItem *item = 0; - QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); - QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); - QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); - } - - // inserting - for (int i = 0; i < 10; ++i) { - model.insertItem(i, "Item" + QString::number(i), ""); - QQuickItem *item = 0; - QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); - QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); - QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); - } - - // removing - model.removeItems(7, 10); - QTRY_COMPARE(model.count(), gridview->count()); - for (int i = 0; i < 18; ++i) { - QQuickItem *item = 0; - QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); - QCOMPARE(item->x(), qreal(i%9)*gridview->cellWidth()); - QCOMPARE(item->y(), qreal(i/9)*gridview->cellHeight()); - } - - delete canvas; -} - -QQuickView *tst_QQuickGridView::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - return canvas; -} - -void tst_QQuickGridView::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) -{ - const int pointCount = 5; - QPoint diff = to - from; - - // send press, five equally spaced moves, and release. - QTest::mousePress(canvas, Qt::LeftButton, 0, from); - - for (int i = 0; i < pointCount; ++i) { - QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - QTest::qWait(duration/pointCount); - QCoreApplication::processEvents(); - } - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); -} - -void tst_QQuickGridView::cacheBuffer() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 90; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testRightToLeft", QVariant(false)); - ctxt->setContextProperty("testTopToBottom", QVariant(false)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); - QVERIFY(gridview != 0); - - QQuickItem *contentItem = gridview->contentItem(); - QVERIFY(contentItem != 0); - QVERIFY(gridview->delegate() != 0); - QVERIFY(gridview->model() != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0); - } - - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - canvas->rootObject()->setProperty("cacheBuffer", 200); - QTRY_VERIFY(gridview->cacheBuffer() == 200); - - // items will be created one at a time - for (int i = itemCount; i < qMin(itemCount+9,model.count()); ++i) { - QVERIFY(findItem(gridview, "wrapper", i) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(gridview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - int newItemCount = 0; - newItemCount = findItems(contentItem, "wrapper").count(); - - // Confirm items positioned correctly - for (int i = 0; i < model.count() && i < newItemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0); - } - - // move view and confirm items in view are visible immediately and outside are created async - gridview->setContentY(300); - - for (int i = 15; i < 34; ++i) { // 34 due to staggered item creation - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item); - QTRY_COMPARE(item->x(), (i%3)*80.0); - QTRY_COMPARE(item->y(), (i/3)*60.0); - } - - QVERIFY(findItem(gridview, "wrapper", 34) == 0); - - // ensure buffered items are created - for (int i = 34; i < qMin(44,model.count()); ++i) { - QQuickItem *item = 0; - while (!item) { - qGuiApp->processEvents(); // allow refill to happen - bool b = false; - controller.incubateWhile(&b); - item = findItem(gridview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - delete canvas; -} - -void tst_QQuickGridView::asynchronous() -{ - QQuickView *canvas = createView(); - canvas->show(); - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - canvas->setSource(TESTDATA("asyncloader.qml")); - - QQuickItem *rootObject = qobject_cast(canvas->rootObject()); - QVERIFY(rootObject); - - QQuickGridView *gridview = 0; - while (!gridview) { - bool b = false; - controller.incubateWhile(&b); - gridview = rootObject->findChild("view"); - } - - // items will be created one at a time - for (int i = 0; i < 12; ++i) { - QVERIFY(findItem(gridview, "wrapper", i) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(gridview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - // verify positioning - QQuickItem *contentItem = gridview->contentItem(); - for (int i = 0; i < 12; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QVERIFY(item->x() == (i%3)*100); - QVERIFY(item->y() == (i/3)*100); - } - - delete canvas; -} - -/* - Find an item with the specified objectName. If index is supplied then the - item must also evaluate the {index} expression equal to index -*/ -template -T *tst_QQuickGridView::findItem(QQuickItem *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item); - if (context) { - if (context->contextProperty("index").toInt() == index) { - return static_cast(item); - } - } - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -template -QList tst_QQuickGridView::findItems(QQuickItem *parent, const QString &objectName) -{ - QList items; - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - items.append(static_cast(item)); - //qDebug() << " found:" << item; - } - items += findItems(item, objectName); - } - - return items; -} - -void tst_QQuickGridView::dumpTree(QQuickItem *parent, int depth) -{ - static QString padding(" "); - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item); - qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1); - dumpTree(item, depth+1); - } -} - - -QTEST_MAIN(tst_QQuickGridView) - -#include "tst_qquickgridview.moc" - diff --git a/tests/auto/declarative/qquickimage/data/aspectratio.qml b/tests/auto/declarative/qquickimage/data/aspectratio.qml deleted file mode 100644 index b26f0e1f04..0000000000 --- a/tests/auto/declarative/qquickimage/data/aspectratio.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Image { - source: "heart.png" - fillMode: Image.PreserveAspectFit; -} diff --git a/tests/auto/declarative/qquickimage/data/big.jpeg b/tests/auto/declarative/qquickimage/data/big.jpeg deleted file mode 100644 index bed7bd65c3..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/big.jpeg and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/big256.png b/tests/auto/declarative/qquickimage/data/big256.png deleted file mode 100644 index 1dc1596d03..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/big256.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/colors.png b/tests/auto/declarative/qquickimage/data/colors.png deleted file mode 100644 index dfb62f3d64..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/colors.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/colors1.png b/tests/auto/declarative/qquickimage/data/colors1.png deleted file mode 100644 index dfb62f3d64..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/colors1.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/green.png b/tests/auto/declarative/qquickimage/data/green.png deleted file mode 100644 index 0a2e153ba1..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/green.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/heart-win32.png b/tests/auto/declarative/qquickimage/data/heart-win32.png deleted file mode 100644 index 351da13772..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/heart-win32.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/heart.png b/tests/auto/declarative/qquickimage/data/heart.png deleted file mode 100644 index abe97fee4b..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/heart.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/heart.svg b/tests/auto/declarative/qquickimage/data/heart.svg deleted file mode 100644 index 8c982cd93c..0000000000 --- a/tests/auto/declarative/qquickimage/data/heart.svg +++ /dev/null @@ -1,55 +0,0 @@ - - - - - -Heart Left-Highlight -This is a normal valentines day heart. - - -holiday -valentines - -valentine -hash(0x8a091c0) -hash(0x8a0916c) -signs_and_symbols -hash(0x8a091f0) -day - - - - -Jon Phillips - - - - -Jon Phillips - - - - -Jon Phillips - - - -image/svg+xml - - -en - - - - - - - - - - - - - - - diff --git a/tests/auto/declarative/qquickimage/data/heart200-win32.png b/tests/auto/declarative/qquickimage/data/heart200-win32.png deleted file mode 100644 index 4976ff98ba..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/heart200-win32.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/heart200.png b/tests/auto/declarative/qquickimage/data/heart200.png deleted file mode 100644 index 7fbb13c5bb..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/heart200.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/htiling.qml b/tests/auto/declarative/qquickimage/data/htiling.qml deleted file mode 100644 index f192f931c9..0000000000 --- a/tests/auto/declarative/qquickimage/data/htiling.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200; height: 550 - - Image { - objectName: "tiling"; anchors.fill: parent - source: "green.png"; fillMode: Image.TileHorizontally - } -} - diff --git a/tests/auto/declarative/qquickimage/data/mirror.qml b/tests/auto/declarative/qquickimage/data/mirror.qml deleted file mode 100644 index 98fddf083e..0000000000 --- a/tests/auto/declarative/qquickimage/data/mirror.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 300 - height: 250 - Image { - objectName: "image" - anchors.fill: parent - source: "pattern.png" - } -} diff --git a/tests/auto/declarative/qquickimage/data/nullpixmap.qml b/tests/auto/declarative/qquickimage/data/nullpixmap.qml deleted file mode 100644 index d52f41f164..0000000000 --- a/tests/auto/declarative/qquickimage/data/nullpixmap.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Image { - width: 10; height:10; fillMode: Image.PreserveAspectFit - source: "" -} diff --git a/tests/auto/declarative/qquickimage/data/pattern.png b/tests/auto/declarative/qquickimage/data/pattern.png deleted file mode 100644 index d3d5e1e007..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/pattern.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/qtbug_16389.qml b/tests/auto/declarative/qquickimage/data/qtbug_16389.qml deleted file mode 100644 index 7b8adecb11..0000000000 --- a/tests/auto/declarative/qquickimage/data/qtbug_16389.qml +++ /dev/null @@ -1,30 +0,0 @@ -import QtQuick 2.0 -Rectangle { - width: 400 - height: 400 - - Item { - anchors.top: parent.top - anchors.left: parent.left - anchors.bottom: blueHandle.top - anchors.right: blueHandle.left - - Image { - id: iconImage - objectName: "iconImage" - anchors.top: parent.top - anchors.bottom: parent.bottom - source: "heart200.png" - fillMode: Image.PreserveAspectFit - smooth: true - } - } - - Rectangle { - id: blueHandle - objectName: "blueHandle" - color: "blue" - width: 25 - height: 25 - } -} diff --git a/tests/auto/declarative/qquickimage/data/qtbug_22125.qml b/tests/auto/declarative/qquickimage/data/qtbug_22125.qml deleted file mode 100644 index 9b68c0a125..0000000000 --- a/tests/auto/declarative/qquickimage/data/qtbug_22125.qml +++ /dev/null @@ -1,44 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - width: 800 - height: 800 - - GridView { - anchors.fill: parent - delegate: Image { - source: imagePath; - asynchronous: true - smooth: true - width: 200 - height: 200 - } - model: ListModel { - ListElement { - imagePath: "http://127.0.0.1:14451/big256.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/big256.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/big256.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/colors.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/colors1.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/big.jpeg" - } - ListElement { - imagePath: "http://127.0.0.1:14451/heart.png" - } - ListElement { - imagePath: "http://127.0.0.1:14451/green.png" - } - } - } -} diff --git a/tests/auto/declarative/qquickimage/data/rect.png b/tests/auto/declarative/qquickimage/data/rect.png deleted file mode 100644 index d564a2d5a5..0000000000 Binary files a/tests/auto/declarative/qquickimage/data/rect.png and /dev/null differ diff --git a/tests/auto/declarative/qquickimage/data/vtiling.qml b/tests/auto/declarative/qquickimage/data/vtiling.qml deleted file mode 100644 index f730f6e050..0000000000 --- a/tests/auto/declarative/qquickimage/data/vtiling.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 550; height: 200 - - Image { - objectName: "tiling"; anchors.fill: parent - source: "green.png"; fillMode: Image.TileVertically - } -} - diff --git a/tests/auto/declarative/qquickimage/qquickimage.pro b/tests/auto/declarative/qquickimage/qquickimage.pro deleted file mode 100644 index 46cbdb49aa..0000000000 --- a/tests/auto/declarative/qquickimage/qquickimage.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickimage -macx:CONFIG -= app_bundle - -HEADERS += ../shared/testhttpserver.h -SOURCES += tst_qquickimage.cpp ../shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickimage/tst_qquickimage.cpp b/tests/auto/declarative/qquickimage/tst_qquickimage.cpp deleted file mode 100644 index 520c0fe5da..0000000000 --- a/tests/auto/declarative/qquickimage/tst_qquickimage.cpp +++ /dev/null @@ -1,732 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../shared/util.h" -#include "../shared/testhttpserver.h" - -#define SERVER_PORT 14451 -#define SERVER_ADDR "http://127.0.0.1:14451" - -Q_DECLARE_METATYPE(QQuickImageBase::Status) - -class tst_qquickimage : public QObject -{ - Q_OBJECT -public: - tst_qquickimage(); - -private slots: - void noSource(); - void imageSource(); - void imageSource_data(); - void clearSource(); - void resized(); - void preserveAspectRatio(); - void smooth(); - void mirror(); - void svg(); - void geometry(); - void geometry_data(); - void big(); - void tiling_QTBUG_6716(); - void tiling_QTBUG_6716_data(); - void noLoading(); - void paintedWidthHeight(); - void sourceSize_QTBUG_14303(); - void sourceSize_QTBUG_16389(); - void nullPixmapPaint(); - void imageCrash_QTBUG_22125(); - -private: - template - T *findItem(QQuickItem *parent, const QString &id, int index=-1); - - QDeclarativeEngine engine; -}; - -tst_qquickimage::tst_qquickimage() -{ -} - -void tst_qquickimage::noSource() -{ - QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->source(), QUrl()); - QVERIFY(obj->status() == QQuickImage::Null); - QCOMPARE(obj->width(), 0.); - QCOMPARE(obj->height(), 0.); - QCOMPARE(obj->fillMode(), QQuickImage::Stretch); - QCOMPARE(obj->progress(), 0.0); - - delete obj; -} - -void tst_qquickimage::imageSource_data() -{ - QTest::addColumn("source"); - QTest::addColumn("width"); - QTest::addColumn("height"); - QTest::addColumn("remote"); - QTest::addColumn("async"); - QTest::addColumn("cache"); - QTest::addColumn("error"); - - QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << true << ""; - QTest::newRow("local no cache") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << false << ""; - QTest::newRow("local async") << QUrl::fromLocalFile(TESTDATA("colors1.png")).toString() << 120.0 << 120.0 << false << true << true << ""; - QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << 0.0 << 0.0 << false - << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString(); - QTest::newRow("local async not found") << QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString() << 0.0 << 0.0 << false - << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString(); - QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << true << ""; - QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << ""; - if (QImageReader::supportedImageFormats().contains("svg")) - QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << ""; - - QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true - << false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; - -} - -void tst_qquickimage::imageSource() -{ - QFETCH(QString, source); - QFETCH(double, width); - QFETCH(double, height); - QFETCH(bool, remote); - QFETCH(bool, async); - QFETCH(bool, cache); - QFETCH(QString, error); - - TestHTTPServer server(SERVER_PORT); - if (remote) { - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png"); - } - - if (!error.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); - - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + source + "\"; asynchronous: " - + (async ? QLatin1String("true") : QLatin1String("false")) + "; cache: " - + (cache ? QLatin1String("true") : QLatin1String("false")) + " }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - - if (async) - QVERIFY(obj->asynchronous() == true); - else - QVERIFY(obj->asynchronous() == false); - - if (cache) - QVERIFY(obj->cache() == true); - else - QVERIFY(obj->cache() == false); - - if (remote || async) - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - - QCOMPARE(obj->source(), remote ? source : QUrl(source)); - - if (error.isEmpty()) { - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QCOMPARE(obj->width(), qreal(width)); - QCOMPARE(obj->height(), qreal(height)); - QCOMPARE(obj->fillMode(), QQuickImage::Stretch); - QCOMPARE(obj->progress(), 1.0); - } else { - QTRY_VERIFY(obj->status() == QQuickImage::Error); - } - - delete obj; -} - -void tst_qquickimage::clearSource() -{ - QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); - QCOMPARE(obj->width(), 120.); - QCOMPARE(obj->height(), 120.); - QCOMPARE(obj->progress(), 1.0); - - ctxt->setContextProperty("srcImage", ""); - QVERIFY(obj->source().isEmpty()); - QVERIFY(obj->status() == QQuickImage::Null); - QCOMPARE(obj->width(), 0.); - QCOMPARE(obj->height(), 0.); - QCOMPARE(obj->progress(), 0.0); - - delete obj; -} - -void tst_qquickimage::resized() -{ - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->fillMode(), QQuickImage::Stretch); - delete obj; -} - - -void tst_qquickimage::preserveAspectRatio() -{ - QQuickView *canvas = new QQuickView(0); - canvas->show(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml"))); - QQuickImage *image = qobject_cast(canvas->rootObject()); - QVERIFY(image != 0); - image->setWidth(80.0); - QCOMPARE(image->width(), 80.); - QCOMPARE(image->height(), 80.); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml"))); - image = qobject_cast(canvas->rootObject()); - image->setHeight(60.0); - QVERIFY(image != 0); - QCOMPARE(image->height(), 60.); - QCOMPARE(image->width(), 60.); - delete canvas; -} - -void tst_qquickimage::smooth() -{ - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.); - QCOMPARE(obj->height(), 300.); - QCOMPARE(obj->smooth(), true); - QCOMPARE(obj->fillMode(), QQuickImage::Stretch); - - delete obj; -} - -void tst_qquickimage::mirror() -{ - QSKIP("Test is broken on multiple levels, will need incremental fixes"); - - QMap screenshots; - QList fillModes; - fillModes << QQuickImage::Stretch << QQuickImage::PreserveAspectFit << QQuickImage::PreserveAspectCrop - << QQuickImage::Tile << QQuickImage::TileVertically << QQuickImage::TileHorizontally; - - qreal width = 300; - qreal height = 250; - - foreach (QQuickImage::FillMode fillMode, fillModes) { - QQuickView *canvas = new QQuickView; - canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml"))); - - QQuickImage *obj = canvas->rootObject()->findChild("image"); - QVERIFY(obj != 0); - - obj->setFillMode(fillMode); - obj->setProperty("mirror", true); - canvas->show(); - - QImage screenshot = canvas->grabFrameBuffer(); - screenshots[fillMode] = screenshot; - delete canvas; - } - - foreach (QQuickImage::FillMode fillMode, fillModes) { - QPixmap srcPixmap; - QVERIFY(srcPixmap.load(TESTDATA("pattern.png"))); - - QPixmap expected(width, height); - expected.fill(); - QPainter p_e(&expected); - QTransform transform; - transform.translate(width, 0).scale(-1, 1.0); - p_e.setTransform(transform); - - switch (fillMode) { - case QQuickImage::Stretch: - p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); - break; - case QQuickImage::PreserveAspectFit: - p_e.drawPixmap(QRect(25, 0, height, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); - break; - case QQuickImage::PreserveAspectCrop: - { - qreal ratio = width/srcPixmap.width(); // width is the longer side - QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio); - rect.moveCenter(QRect(0, 0, width, height).center()); - p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); - break; - } - case QQuickImage::Tile: - p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); - break; - case QQuickImage::TileVertically: - transform.scale(width / srcPixmap.width(), 1.0); - p_e.setTransform(transform); - p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); - break; - case QQuickImage::TileHorizontally: - transform.scale(1.0, height / srcPixmap.height()); - p_e.setTransform(transform); - p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); - break; - case QQuickImage::Pad: - break; - } - - QImage img = expected.toImage(); - QEXPECT_FAIL("", "QTBUG-21005 fails", Continue); - QCOMPARE(screenshots[fillMode], img); - } -} - -void tst_qquickimage::svg() -{ - if (!QImageReader::supportedImageFormats().contains("svg")) - QSKIP("svg support not available"); - - QString src = QUrl::fromLocalFile(TESTDATA("heart.svg")).toString(); - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; sourceSize.width: 300; sourceSize.height: 300 }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 300.0); - QCOMPARE(obj->height(), 300.0); - obj->setSourceSize(QSize(200,200)); - - QCOMPARE(obj->width(), 200.0); - QCOMPARE(obj->height(), 200.0); - delete obj; -} - -void tst_qquickimage::geometry_data() -{ - QTest::addColumn("fillMode"); - QTest::addColumn("explicitWidth"); - QTest::addColumn("explicitHeight"); - QTest::addColumn("itemWidth"); - QTest::addColumn("paintedWidth"); - QTest::addColumn("boundingWidth"); - QTest::addColumn("itemHeight"); - QTest::addColumn("paintedHeight"); - QTest::addColumn("boundingHeight"); - - // tested image has width 200, height 100 - - // bounding rect and item rect are equal with fillMode PreserveAspectFit, painted rect may be smaller if the aspect ratio doesn't match - QTest::newRow("PreserveAspectFit") << "PreserveAspectFit" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; - QTest::newRow("PreserveAspectFit explicit width 300") << "PreserveAspectFit" << true << false << 300.0 << 200.0 << 300.0 << 100.0 << 100.0 << 100.0; - QTest::newRow("PreserveAspectFit explicit height 400") << "PreserveAspectFit" << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 100.0 << 400.0; - QTest::newRow("PreserveAspectFit explicit width 300, height 400") << "PreserveAspectFit" << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 150.0 << 400.0; - - // bounding rect and painted rect are equal with fillMode PreserveAspectCrop, item rect may be smaller if the aspect ratio doesn't match - QTest::newRow("PreserveAspectCrop") << "PreserveAspectCrop" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; - QTest::newRow("PreserveAspectCrop explicit width 300") << "PreserveAspectCrop" << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 150.0 << 150.0; - QTest::newRow("PreserveAspectCrop explicit height 400") << "PreserveAspectCrop" << false << true << 200.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0; - QTest::newRow("PreserveAspectCrop explicit width 300, height 400") << "PreserveAspectCrop" << true << true << 300.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0; - - // bounding rect, painted rect and item rect are equal in stretching and tiling images - QStringList fillModes; - fillModes << "Stretch" << "Tile" << "TileVertically" << "TileHorizontally"; - foreach (QString fillMode, fillModes) { - QTest::newRow(fillMode.toLatin1()) << fillMode << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; - QTest::newRow(QString(fillMode + " explicit width 300").toLatin1()) << fillMode << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 100.0 << 100.0; - QTest::newRow(QString(fillMode + " explicit height 400").toLatin1()) << fillMode << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 400.0 << 400.0; - QTest::newRow(QString(fillMode + " explicit width 300, height 400").toLatin1()) << fillMode << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 400.0 << 400.0; - } -} - -void tst_qquickimage::geometry() -{ - QFETCH(QString, fillMode); - QFETCH(bool, explicitWidth); - QFETCH(bool, explicitHeight); - QFETCH(double, itemWidth); - QFETCH(double, itemHeight); - QFETCH(double, paintedWidth); - QFETCH(double, paintedHeight); - QFETCH(double, boundingWidth); - QFETCH(double, boundingHeight); - - QString src = QUrl::fromLocalFile(TESTDATA("rect.png")).toString(); - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; fillMode: Image." + fillMode + "; "; - - if (explicitWidth) - componentStr.append("width: 300; "); - if (explicitHeight) - componentStr.append("height: 400; "); - componentStr.append("}"); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->width(), itemWidth); - QCOMPARE(obj->paintedWidth(), paintedWidth); - QCOMPARE(obj->boundingRect().width(), boundingWidth); - - QCOMPARE(obj->height(), itemHeight); - QCOMPARE(obj->paintedHeight(), paintedHeight); - QCOMPARE(obj->boundingRect().height(), boundingHeight); - delete obj; -} - -void tst_qquickimage::big() -{ - // If the JPEG loader does not implement scaling efficiently, it would - // have to build a 400 MB image. That would be a bug in the JPEG loader. - - QString src = QUrl::fromLocalFile(TESTDATA("big.jpeg")).toString(); - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 100; sourceSize.height: 256 }"; - - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 100.0); - QCOMPARE(obj->height(), 256.0); - - delete obj; -} - -// As tiling_QTBUG_6716 doesn't complete, it doesn't delete the -// canvas which causes leak warnings. Use this delete on stack -// destruction pattern to work around this. -template -struct AutoDelete { - AutoDelete(T *t) : t(t) {} - ~AutoDelete() { delete t; } -private: - T *t; -}; - -void tst_qquickimage::tiling_QTBUG_6716() -{ - QSKIP("Test is broken on multiple levels, will need incremental fixes"); - - QFETCH(QString, source); - - QQuickView *canvas = new QQuickView(0); - AutoDelete del(canvas); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA(source))); - canvas->show(); - qApp->processEvents(); - - QQuickImage *tiling = findItem(canvas->rootObject(), "tiling"); - - QVERIFY(tiling != 0); - QImage img = canvas->grabFrameBuffer(); - for (int x = 0; x < tiling->width(); ++x) { - for (int y = 0; y < tiling->height(); ++y) { - QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0)); - } - } -} - -void tst_qquickimage::tiling_QTBUG_6716_data() -{ - QTest::addColumn("source"); - QTest::newRow("vertical_tiling") << "vtiling.qml"; - QTest::newRow("horizontal_tiling") << "htiling.qml"; -} - -void tst_qquickimage::noLoading() -{ - qRegisterMetaType(); - - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png"); - - QString componentStr = "import QtQuick 2.0\nImage { source: srcImage; cache: true }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart.png"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QVERIFY(obj->status() == QQuickImage::Ready); - - QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &))); - QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); - QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status))); - - // Loading local file - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png"))); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - QTRY_COMPARE(sourceSpy.count(), 1); - QTRY_COMPARE(progressSpy.count(), 0); - QTRY_COMPARE(statusSpy.count(), 0); - - // Loading remote file - ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png"); - QTRY_VERIFY(obj->status() == QQuickImage::Loading); - QTRY_VERIFY(obj->progress() == 0.0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - QTRY_COMPARE(sourceSpy.count(), 2); - QTRY_COMPARE(progressSpy.count(), 2); - QTRY_COMPARE(statusSpy.count(), 2); - - // Loading remote file again - should not go through 'Loading' state. - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png"))); - ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png"); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - QTRY_VERIFY(obj->progress() == 1.0); - QTRY_COMPARE(sourceSpy.count(), 4); - QTRY_COMPARE(progressSpy.count(), 2); - QTRY_COMPARE(statusSpy.count(), 2); - - delete obj; -} - -void tst_qquickimage::paintedWidthHeight() -{ - { - QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString(); - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 200; height: 25; fillMode: Image.PreserveAspectFit }"; - - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 200.0); - QCOMPARE(obj->height(), 25.0); - QCOMPARE(obj->paintedWidth(), 25.0); - QCOMPARE(obj->paintedHeight(), 25.0); - - delete obj; - } - - { - QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString(); - QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 26; height: 175; fillMode: Image.PreserveAspectFit }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - QVERIFY(obj != 0); - QCOMPARE(obj->width(), 26.0); - QCOMPARE(obj->height(), 175.0); - QCOMPARE(obj->paintedWidth(), 26.0); - QCOMPARE(obj->paintedHeight(), 26.0); - - delete obj; - } -} - -void tst_qquickimage::sourceSize_QTBUG_14303() -{ - QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }"; - QDeclarativeContext *ctxt = engine.rootContext(); - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png"))); - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickImage *obj = qobject_cast(component.create()); - - QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged())); - - QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->status() == QQuickImage::Ready); - - QTRY_COMPARE(obj->sourceSize().width(), 200); - QTRY_COMPARE(obj->sourceSize().height(), 200); - QTRY_COMPARE(sourceSizeSpy.count(), 0); - - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); - QTRY_COMPARE(obj->sourceSize().width(), 120); - QTRY_COMPARE(obj->sourceSize().height(), 120); - QTRY_COMPARE(sourceSizeSpy.count(), 1); - - ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png"))); - QTRY_COMPARE(obj->sourceSize().width(), 200); - QTRY_COMPARE(obj->sourceSize().height(), 200); - QTRY_COMPARE(sourceSizeSpy.count(), 2); - - delete obj; -} - -void tst_qquickimage::sourceSize_QTBUG_16389() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug_16389.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickImage *image = findItem(canvas->rootObject(), "iconImage"); - QQuickItem *handle = findItem(canvas->rootObject(), "blueHandle"); - - QCOMPARE(image->sourceSize().width(), 200); - QCOMPARE(image->sourceSize().height(), 200); - QCOMPARE(image->paintedWidth(), 0.0); - QCOMPARE(image->paintedHeight(), 0.0); - - handle->setY(20); - - QCOMPARE(image->sourceSize().width(), 200); - QCOMPARE(image->sourceSize().height(), 200); - QCOMPARE(image->paintedWidth(), 20.0); - QCOMPARE(image->paintedHeight(), 20.0); - - delete canvas; -} - -static int numberOfWarnings = 0; -static void checkWarnings(QtMsgType, const char *msg) -{ - if (!QString(msg).contains("QGLContext::makeCurrent(): Failed.")) - numberOfWarnings++; -} - -// QTBUG-15690 -void tst_qquickimage::nullPixmapPaint() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("nullpixmap.qml"))); - canvas->show(); - - QQuickImage *image = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(image != 0); - image->setSource(SERVER_ADDR + QString("/no-such-file.png")); - - QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings); - - // used to print "QTransform::translate with NaN called" - QPixmap pm = QPixmap::fromImage(canvas->grabFrameBuffer()); - qInstallMsgHandler(previousMsgHandler); - QVERIFY(numberOfWarnings == 0); - delete image; -} - -void tst_qquickimage::imageCrash_QTBUG_22125() -{ - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA(""), TestHTTPServer::Delay); - - { - QQuickView view(QUrl::fromLocalFile(TESTDATA("qtbug_22125.qml"))); - view.show(); - qApp->processEvents(); - qApp->processEvents(); - // shouldn't crash when the view drops out of scope due to - // QDeclarativePixmapData attempting to dereference a pointer to - // the destroyed reader. - } - - // shouldn't crash when deleting cancelled QDeclarativePixmapReplys. - QTest::qWait(520); // Delay mode delays for 500 ms. - qApp->processEvents(QEventLoop::DeferredDeletion); -} - -/* - Find an item with the specified objectName. If index is supplied then the - item must also evaluate the {index} expression equal to index -*/ -template -T *tst_qquickimage::findItem(QQuickItem *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast(item); - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -QTEST_MAIN(tst_qquickimage) - -#include "tst_qquickimage.moc" diff --git a/tests/auto/declarative/qquickitem/data/order.1.qml b/tests/auto/declarative/qquickitem/data/order.1.qml deleted file mode 100644 index 963288b257..0000000000 --- a/tests/auto/declarative/qquickitem/data/order.1.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Item { - Item { objectName: "1" } - Item { objectName: "2" } - Item { objectName: "3" } -} diff --git a/tests/auto/declarative/qquickitem/data/order.2.qml b/tests/auto/declarative/qquickitem/data/order.2.qml deleted file mode 100644 index 5609c77e28..0000000000 --- a/tests/auto/declarative/qquickitem/data/order.2.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Item { - Item { objectName: "1" } - Item { objectName: "2"; z: 1.0 } - Item { objectName: "3" } -} diff --git a/tests/auto/declarative/qquickitem/qquickitem.pro b/tests/auto/declarative/qquickitem/qquickitem.pro deleted file mode 100644 index f484bae014..0000000000 --- a/tests/auto/declarative/qquickitem/qquickitem.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickitem -SOURCES += tst_qquickitem.cpp - -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private widgets testlib diff --git a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem/tst_qquickitem.cpp deleted file mode 100644 index f8660540d9..0000000000 --- a/tests/auto/declarative/qquickitem/tst_qquickitem.cpp +++ /dev/null @@ -1,1190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "qquickitem.h" -#include "qquickcanvas.h" -#include "qquickview.h" -#include -#include "private/qquickfocusscope_p.h" -#include "private/qquickitem_p.h" -#include -#include -#include "../shared/util.h" - -class TestItem : public QQuickItem -{ -Q_OBJECT -public: - TestItem(QQuickItem *parent = 0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {} - - bool focused; - int pressCount; - int releaseCount; - int wheelCount; -protected: - virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } - virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } - virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; } - virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; } - virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; } -}; - -class TestPolishItem : public QQuickItem -{ -Q_OBJECT -public: - TestPolishItem(QQuickItem *parent) - : QQuickItem(parent), wasPolished(false) { - QTimer::singleShot(10, this, SLOT(doPolish())); - } - - bool wasPolished; - -protected: - virtual void updatePolish() { - wasPolished = true; - } - -public slots: - void doPolish() { - polish(); - } -}; - -class TestFocusScope : public QQuickFocusScope -{ -Q_OBJECT -public: - TestFocusScope(QQuickItem *parent = 0) : QQuickFocusScope(parent), focused(false) {} - - bool focused; -protected: - virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } - virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } -}; - -class tst_qquickitem : public QObject -{ - Q_OBJECT -public: - tst_qquickitem(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void noCanvas(); - void simpleFocus(); - void scopedFocus(); - void addedToCanvas(); - void changeParent(); - - void constructor(); - void setParentItem(); - - void visible(); - void enabled(); - - void mouseGrab(); - void polishOutsideAnimation(); - - void wheelEvent_data(); - void wheelEvent(); - void hoverEvent_data(); - void hoverEvent(); - void hoverEventInParent(); - - void paintOrder_data(); - void paintOrder(); - -private: - - enum PaintOrderOp { - NoOp, Append, Remove, StackBefore, StackAfter, SetZ - }; - - void ensureFocus(QWindow *w) { - w->show(); - w->requestActivateWindow(); - qApp->processEvents(); - } -}; - -tst_qquickitem::tst_qquickitem() -{ -} - -void tst_qquickitem::initTestCase() -{ -} - -void tst_qquickitem::cleanupTestCase() -{ -} - -// Focus has no effect when outside a canvas -void tst_qquickitem::noCanvas() -{ - QQuickItem *root = new TestItem; - QQuickItem *child = new TestItem(root); - QQuickItem *scope = new TestItem(root); - QQuickFocusScope *scopedChild = new TestFocusScope(scope); - QQuickFocusScope *scopedChild2 = new TestFocusScope(scope); - - QCOMPARE(root->hasFocus(), false); - QCOMPARE(child->hasFocus(), false); - QCOMPARE(scope->hasFocus(), false); - QCOMPARE(scopedChild->hasFocus(), false); - QCOMPARE(scopedChild2->hasFocus(), false); - - root->setFocus(true); - scope->setFocus(true); - scopedChild2->setFocus(true); - QCOMPARE(root->hasFocus(), true); - QCOMPARE(child->hasFocus(), false); - QCOMPARE(scope->hasFocus(), true); - QCOMPARE(scopedChild->hasFocus(), false); - QCOMPARE(scopedChild2->hasFocus(), true); - - root->setFocus(false); - child->setFocus(true); - scopedChild->setFocus(true); - scope->setFocus(false); - QCOMPARE(root->hasFocus(), false); - QCOMPARE(child->hasFocus(), true); - QCOMPARE(scope->hasFocus(), false); - QCOMPARE(scopedChild->hasFocus(), true); - QCOMPARE(scopedChild2->hasFocus(), true); - - delete root; -} - -struct FocusData { - FocusData() : focus(false), activeFocus(false) {} - - void set(bool f, bool af) { focus = f; activeFocus = af; } - bool focus; - bool activeFocus; -}; -struct FocusState : public QHash -{ - FocusState() : activeFocusItem(0) {} - FocusState &operator<<(QQuickItem *item) { - insert(item, FocusData()); - return *this; - } - - void active(QQuickItem *i) { - activeFocusItem = i; - } - QQuickItem *activeFocusItem; -}; - -#define FVERIFY() \ - do { \ - if (focusState.activeFocusItem) { \ - QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \ - if (qobject_cast(canvas.activeFocusItem())) \ - QCOMPARE(qobject_cast(canvas.activeFocusItem())->focused, true); \ - else if (qobject_cast(canvas.activeFocusItem())) \ - QCOMPARE(qobject_cast(canvas.activeFocusItem())->focused, true); \ - } else { \ - QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \ - } \ - for (QHash::Iterator iter = focusState.begin(); \ - iter != focusState.end(); \ - iter++) { \ - QCOMPARE(iter.key()->hasFocus(), iter.value().focus); \ - QCOMPARE(iter.key()->hasActiveFocus(), iter.value().activeFocus); \ - } \ - } while (false) - -// Tests a simple set of top-level scoped items -void tst_qquickitem::simpleFocus() -{ - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - - QQuickItem *l1c1 = new TestItem(canvas.rootItem()); - QQuickItem *l1c2 = new TestItem(canvas.rootItem()); - QQuickItem *l1c3 = new TestItem(canvas.rootItem()); - - QQuickItem *l2c1 = new TestItem(l1c1); - QQuickItem *l2c2 = new TestItem(l1c1); - QQuickItem *l2c3 = new TestItem(l1c3); - - FocusState focusState; - focusState << l1c1 << l1c2 << l1c3 - << l2c1 << l2c2 << l2c3; - FVERIFY(); - - l1c1->setFocus(true); - focusState[l1c1].set(true, true); - focusState.active(l1c1); - FVERIFY(); - - l2c3->setFocus(true); - focusState[l1c1].set(false, false); - focusState[l2c3].set(true, true); - focusState.active(l2c3); - FVERIFY(); - - l1c3->setFocus(true); - focusState[l2c3].set(false, false); - focusState[l1c3].set(true, true); - focusState.active(l1c3); - FVERIFY(); - - l1c2->setFocus(false); - FVERIFY(); - - l1c3->setFocus(false); - focusState[l1c3].set(false, false); - focusState.active(0); - FVERIFY(); - - l2c1->setFocus(true); - focusState[l2c1].set(true, true); - focusState.active(l2c1); - FVERIFY(); -} - -// Items with a focus scope -void tst_qquickitem::scopedFocus() -{ - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - - QQuickItem *l1c1 = new TestItem(canvas.rootItem()); - QQuickItem *l1c2 = new TestItem(canvas.rootItem()); - QQuickItem *l1c3 = new TestItem(canvas.rootItem()); - - QQuickItem *l2c1 = new TestItem(l1c1); - QQuickItem *l2c2 = new TestItem(l1c1); - QQuickItem *l2c3 = new TestFocusScope(l1c3); - - QQuickItem *l3c1 = new TestItem(l2c3); - QQuickItem *l3c2 = new TestFocusScope(l2c3); - - QQuickItem *l4c1 = new TestItem(l3c2); - QQuickItem *l4c2 = new TestItem(l3c2); - - FocusState focusState; - focusState << l1c1 << l1c2 << l1c3 - << l2c1 << l2c2 << l2c3 - << l3c1 << l3c2 - << l4c1 << l4c2; - FVERIFY(); - - l4c2->setFocus(true); - focusState[l4c2].set(true, false); - FVERIFY(); - - l4c1->setFocus(true); - focusState[l4c2].set(false, false); - focusState[l4c1].set(true, false); - FVERIFY(); - - l1c1->setFocus(true); - focusState[l1c1].set(true, true); - focusState.active(l1c1); - FVERIFY(); - - l3c2->setFocus(true); - focusState[l3c2].set(true, false); - FVERIFY(); - - l2c3->setFocus(true); - focusState[l1c1].set(false, false); - focusState[l2c3].set(true, true); - focusState[l3c2].set(true, true); - focusState[l4c1].set(true, true); - focusState.active(l4c1); - FVERIFY(); - - l3c2->setFocus(false); - focusState[l3c2].set(false, false); - focusState[l4c1].set(true, false); - focusState.active(l2c3); - FVERIFY(); - - l3c2->setFocus(true); - focusState[l3c2].set(true, true); - focusState[l4c1].set(true, true); - focusState.active(l4c1); - FVERIFY(); - - l4c1->setFocus(false); - focusState[l4c1].set(false, false); - focusState.active(l3c2); - FVERIFY(); - - l1c3->setFocus(true); - focusState[l1c3].set(true, true); - focusState[l2c3].set(false, false); - focusState[l3c2].set(true, false); - focusState.active(l1c3); - FVERIFY(); -} - -// Tests focus corrects itself when a tree is added to a canvas for the first time -void tst_qquickitem::addedToCanvas() -{ - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - - QQuickItem *item = new TestItem; - - FocusState focusState; - focusState << item; - - item->setFocus(true); - focusState[item].set(true, false); - FVERIFY(); - - item->setParentItem(canvas.rootItem()); - focusState[item].set(true, true); - focusState.active(item); - FVERIFY(); - } - - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - - QQuickItem *item = new TestItem(canvas.rootItem()); - - QQuickItem *tree = new TestItem; - QQuickItem *c1 = new TestItem(tree); - QQuickItem *c2 = new TestItem(tree); - - FocusState focusState; - focusState << item << tree << c1 << c2; - - item->setFocus(true); - c1->setFocus(true); - c2->setFocus(true); - focusState[item].set(true, true); - focusState[c1].set(true, false); - focusState[c2].set(true, false); - focusState.active(item); - FVERIFY(); - - tree->setParentItem(item); - focusState[c1].set(false, false); - focusState[c2].set(false, false); - FVERIFY(); - } - - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - - QQuickItem *tree = new TestItem; - QQuickItem *c1 = new TestItem(tree); - QQuickItem *c2 = new TestItem(tree); - - FocusState focusState; - focusState << tree << c1 << c2; - c1->setFocus(true); - c2->setFocus(true); - focusState[c1].set(true, false); - focusState[c2].set(true, false); - FVERIFY(); - - tree->setParentItem(canvas.rootItem()); - focusState[c1].set(true, true); - focusState[c2].set(false, false); - focusState.active(c1); - FVERIFY(); - } - - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *tree = new TestFocusScope; - QQuickItem *c1 = new TestItem(tree); - QQuickItem *c2 = new TestItem(tree); - - FocusState focusState; - focusState << tree << c1 << c2; - c1->setFocus(true); - c2->setFocus(true); - focusState[c1].set(true, false); - focusState[c2].set(true, false); - FVERIFY(); - - tree->setParentItem(canvas.rootItem()); - focusState[c1].set(true, false); - focusState[c2].set(false, false); - FVERIFY(); - - tree->setFocus(true); - focusState[tree].set(true, true); - focusState[c1].set(true, true); - focusState.active(c1); - FVERIFY(); - } - - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *tree = new TestFocusScope; - QQuickItem *c1 = new TestItem(tree); - QQuickItem *c2 = new TestItem(tree); - - FocusState focusState; - focusState << tree << c1 << c2; - tree->setFocus(true); - c1->setFocus(true); - c2->setFocus(true); - focusState[tree].set(true, false); - focusState[c1].set(true, false); - focusState[c2].set(true, false); - FVERIFY(); - - tree->setParentItem(canvas.rootItem()); - focusState[tree].set(true, true); - focusState[c1].set(true, true); - focusState[c2].set(false, false); - focusState.active(c1); - FVERIFY(); - } - - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - QQuickItem *tree = new TestFocusScope; - QQuickItem *c1 = new TestItem(tree); - QQuickItem *c2 = new TestItem(tree); - - FocusState focusState; - focusState << child << tree << c1 << c2; - child->setFocus(true); - tree->setFocus(true); - c1->setFocus(true); - c2->setFocus(true); - focusState[child].set(true, true); - focusState[tree].set(true, false); - focusState[c1].set(true, false); - focusState[c2].set(true, false); - focusState.active(child); - FVERIFY(); - - tree->setParentItem(canvas.rootItem()); - focusState[tree].set(false, false); - focusState[c1].set(true, false); - focusState[c2].set(false, false); - FVERIFY(); - - tree->setFocus(true); - focusState[child].set(false, false); - focusState[tree].set(true, true); - focusState[c1].set(true, true); - focusState.active(c1); - FVERIFY(); - } -} - -void tst_qquickitem::changeParent() -{ - // Parent to no parent - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - - FocusState focusState; - focusState << child; - FVERIFY(); - - child->setFocus(true); - focusState[child].set(true, true); - focusState.active(child); - FVERIFY(); - - child->setParentItem(0); - focusState[child].set(true, false); - focusState.active(0); - FVERIFY(); - } - - // Different parent, same focus scope - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - QQuickItem *child2 = new TestItem(canvas.rootItem()); - - FocusState focusState; - focusState << child << child2; - FVERIFY(); - - child->setFocus(true); - focusState[child].set(true, true); - focusState.active(child); - FVERIFY(); - - child->setParentItem(child2); - FVERIFY(); - } - - // Different parent, different focus scope - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); - QQuickItem *item = new TestItem(child); - - FocusState focusState; - focusState << child << child2 << item; - FVERIFY(); - - item->setFocus(true); - focusState[item].set(true, true); - focusState.active(item); - FVERIFY(); - - item->setParentItem(child2); - focusState[item].set(true, false); - focusState.active(0); - FVERIFY(); - } - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); - QQuickItem *item = new TestItem(child2); - - FocusState focusState; - focusState << child << child2 << item; - FVERIFY(); - - item->setFocus(true); - focusState[item].set(true, false); - focusState.active(0); - FVERIFY(); - - item->setParentItem(child); - focusState[item].set(true, true); - focusState.active(item); - FVERIFY(); - } - { - QQuickCanvas canvas; - ensureFocus(&canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); - QQuickItem *child = new TestItem(canvas.rootItem()); - QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); - QQuickItem *item = new TestItem(child2); - - FocusState focusState; - focusState << child << child2 << item; - FVERIFY(); - - child->setFocus(true); - item->setFocus(true); - focusState[child].set(true, true); - focusState[item].set(true, false); - focusState.active(child); - FVERIFY(); - - item->setParentItem(child); - focusState[item].set(false, false); - FVERIFY(); - } - -} - -void tst_qquickitem::constructor() -{ - QQuickItem *root = new QQuickItem; - QVERIFY(root->parent() == 0); - QVERIFY(root->parentItem() == 0); - - QQuickItem *child1 = new QQuickItem(root); - QVERIFY(child1->parent() == root); - QVERIFY(child1->parentItem() == root); - QCOMPARE(root->childItems().count(), 1); - QCOMPARE(root->childItems().at(0), child1); - - QQuickItem *child2 = new QQuickItem(root); - QVERIFY(child2->parent() == root); - QVERIFY(child2->parentItem() == root); - QCOMPARE(root->childItems().count(), 2); - QCOMPARE(root->childItems().at(0), child1); - QCOMPARE(root->childItems().at(1), child2); - - delete root; -} - -void tst_qquickitem::setParentItem() -{ - QQuickItem *root = new QQuickItem; - QVERIFY(root->parent() == 0); - QVERIFY(root->parentItem() == 0); - - QQuickItem *child1 = new QQuickItem; - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); - - child1->setParentItem(root); - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == root); - QCOMPARE(root->childItems().count(), 1); - QCOMPARE(root->childItems().at(0), child1); - - QQuickItem *child2 = new QQuickItem; - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == 0); - child2->setParentItem(root); - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == root); - QCOMPARE(root->childItems().count(), 2); - QCOMPARE(root->childItems().at(0), child1); - QCOMPARE(root->childItems().at(1), child2); - - child1->setParentItem(0); - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); - QCOMPARE(root->childItems().count(), 1); - QCOMPARE(root->childItems().at(0), child2); - - delete root; - - QVERIFY(child1->parent() == 0); - QVERIFY(child1->parentItem() == 0); - QVERIFY(child2->parent() == 0); - QVERIFY(child2->parentItem() == 0); - - delete child1; - delete child2; -} - -void tst_qquickitem::visible() -{ - QQuickItem *root = new QQuickItem; - - QQuickItem *child1 = new QQuickItem; - child1->setParentItem(root); - - QQuickItem *child2 = new QQuickItem; - child2->setParentItem(root); - - QVERIFY(child1->isVisible()); - QVERIFY(child2->isVisible()); - - root->setVisible(false); - QVERIFY(!child1->isVisible()); - QVERIFY(!child2->isVisible()); - - root->setVisible(true); - QVERIFY(child1->isVisible()); - QVERIFY(child2->isVisible()); - - child1->setVisible(false); - QVERIFY(!child1->isVisible()); - QVERIFY(child2->isVisible()); - - child2->setParentItem(child1); - QVERIFY(!child1->isVisible()); - QVERIFY(!child2->isVisible()); - - child2->setParentItem(root); - QVERIFY(!child1->isVisible()); - QVERIFY(child2->isVisible()); - - delete root; - delete child1; - delete child2; -} - -void tst_qquickitem::enabled() -{ - QQuickItem *root = new QQuickItem; - - QQuickItem *child1 = new QQuickItem; - child1->setParentItem(root); - - QQuickItem *child2 = new QQuickItem; - child2->setParentItem(root); - - QVERIFY(child1->isEnabled()); - QVERIFY(child2->isEnabled()); - - root->setEnabled(false); - QVERIFY(!child1->isEnabled()); - QVERIFY(!child2->isEnabled()); - - root->setEnabled(true); - QVERIFY(child1->isEnabled()); - QVERIFY(child2->isEnabled()); - - child1->setEnabled(false); - QVERIFY(!child1->isEnabled()); - QVERIFY(child2->isEnabled()); - - child2->setParentItem(child1); - QVERIFY(!child1->isEnabled()); - QVERIFY(!child2->isEnabled()); - - child2->setParentItem(root); - QVERIFY(!child1->isEnabled()); - QVERIFY(child2->isEnabled()); - - delete root; - delete child1; - delete child2; -} - -void tst_qquickitem::mouseGrab() -{ - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(200, 200); - canvas->show(); - - TestItem *child1 = new TestItem; - child1->setAcceptedMouseButtons(Qt::LeftButton); - child1->setSize(QSizeF(200, 100)); - child1->setParentItem(canvas->rootItem()); - - TestItem *child2 = new TestItem; - child2->setAcceptedMouseButtons(Qt::LeftButton); - child2->setY(51); - child2->setSize(QSizeF(200, 100)); - child2->setParentItem(canvas->rootItem()); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(100); - QVERIFY(canvas->mouseGrabberItem() == child1); - QTest::qWait(100); - - QCOMPARE(child1->pressCount, 1); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QVERIFY(canvas->mouseGrabberItem() == 0); - QCOMPARE(child1->releaseCount, 1); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QVERIFY(canvas->mouseGrabberItem() == child1); - QCOMPARE(child1->pressCount, 2); - child1->setEnabled(false); - QVERIFY(canvas->mouseGrabberItem() == 0); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QCOMPARE(child1->releaseCount, 1); - child1->setEnabled(true); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QVERIFY(canvas->mouseGrabberItem() == child1); - QCOMPARE(child1->pressCount, 3); - child1->setVisible(false); - QVERIFY(canvas->mouseGrabberItem() == 0); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QCOMPARE(child1->releaseCount, 1); - child1->setVisible(true); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QVERIFY(canvas->mouseGrabberItem() == child1); - QCOMPARE(child1->pressCount, 4); - child2->grabMouse(); - QVERIFY(canvas->mouseGrabberItem() == child2); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QCOMPARE(child1->releaseCount, 1); - QCOMPARE(child2->releaseCount, 1); - - child2->grabMouse(); - QVERIFY(canvas->mouseGrabberItem() == child2); - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QCOMPARE(child1->pressCount, 4); - QCOMPARE(child2->pressCount, 1); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); - QTest::qWait(50); - QCOMPARE(child1->releaseCount, 1); - QCOMPARE(child2->releaseCount, 2); - - delete child1; - delete child2; - delete canvas; -} - -void tst_qquickitem::polishOutsideAnimation() -{ - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(200, 200); - canvas->show(); - - TestPolishItem *item = new TestPolishItem(canvas->rootItem()); - item->setSize(QSizeF(200, 100)); - QTest::qWait(50); - QTRY_VERIFY(item->wasPolished); - - delete item; - delete canvas; -} - -void tst_qquickitem::wheelEvent_data() -{ - QTest::addColumn("visible"); - QTest::addColumn("enabled"); - - QTest::newRow("visible and enabled") << true << true; - QTest::newRow("visible and disabled") << true << false; - QTest::newRow("invisible and enabled") << false << true; - QTest::newRow("invisible and disabled") << false << false; -} - -void tst_qquickitem::wheelEvent() -{ - QFETCH(bool, visible); - QFETCH(bool, enabled); - - const bool shouldReceiveWheelEvents = visible && enabled; - - QQuickCanvas *canvas = new QQuickCanvas; - canvas->resize(200, 200); - canvas->show(); - - TestItem *item = new TestItem; - item->setSize(QSizeF(200, 100)); - item->setParentItem(canvas->rootItem()); - - item->setEnabled(enabled); - item->setVisible(visible); - - QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical); - event.setAccepted(false); - QApplication::sendEvent(canvas, &event); - - if (shouldReceiveWheelEvents) { - QVERIFY(event.isAccepted()); - QCOMPARE(item->wheelCount, 1); - } else { - QVERIFY(!event.isAccepted()); - QCOMPARE(item->wheelCount, 0); - } - - delete canvas; -} - -class HoverItem : public QQuickItem -{ -Q_OBJECT -public: - HoverItem(QQuickItem *parent = 0) - : QQuickItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0) - { } - void resetCounters() { - hoverEnterCount = 0; - hoverMoveCount = 0; - hoverLeaveCount = 0; - } - int hoverEnterCount; - int hoverMoveCount; - int hoverLeaveCount; -protected: - virtual void hoverEnterEvent(QHoverEvent *event) { - event->accept(); - ++hoverEnterCount; - } - virtual void hoverMoveEvent(QHoverEvent *event) { - event->accept(); - ++hoverMoveCount; - } - virtual void hoverLeaveEvent(QHoverEvent *event) { - event->accept(); - ++hoverLeaveCount; - } -}; - -void tst_qquickitem::hoverEvent_data() -{ - QTest::addColumn("visible"); - QTest::addColumn("enabled"); - QTest::addColumn("acceptHoverEvents"); - - QTest::newRow("visible, enabled, accept hover") << true << true << true; - QTest::newRow("visible, disabled, accept hover") << true << false << true; - QTest::newRow("invisible, enabled, accept hover") << false << true << true; - QTest::newRow("invisible, disabled, accept hover") << false << false << true; - - QTest::newRow("visible, enabled, not accept hover") << true << true << false; - QTest::newRow("visible, disabled, not accept hover") << true << false << false; - QTest::newRow("invisible, enabled, not accept hover") << false << true << false; - QTest::newRow("invisible, disabled, not accept hover") << false << false << false; -} - -// ### For some unknown reason QTest::mouseMove() isn't working correctly. -static void sendMouseMove(QObject *object, const QPoint &position) -{ - QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0); - QApplication::sendEvent(object, &moveEvent); -} - -void tst_qquickitem::hoverEvent() -{ - QFETCH(bool, visible); - QFETCH(bool, enabled); - QFETCH(bool, acceptHoverEvents); - - QQuickCanvas *canvas = new QQuickCanvas(); - canvas->resize(200, 200); - canvas->show(); - - HoverItem *item = new HoverItem; - item->setSize(QSizeF(100, 100)); - item->setParentItem(canvas->rootItem()); - - item->setEnabled(enabled); - item->setVisible(visible); - item->setAcceptHoverEvents(acceptHoverEvents); - - const QPoint outside(150, 150); - const QPoint inside(50, 50); - const QPoint anotherInside(51, 51); - - sendMouseMove(canvas, outside); - item->resetCounters(); - - // Enter, then move twice inside, then leave. - sendMouseMove(canvas, inside); - sendMouseMove(canvas, anotherInside); - sendMouseMove(canvas, inside); - sendMouseMove(canvas, outside); - - const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents; - if (shouldReceiveHoverEvents) { - QCOMPARE(item->hoverEnterCount, 1); - QCOMPARE(item->hoverMoveCount, 2); - QCOMPARE(item->hoverLeaveCount, 1); - } else { - QCOMPARE(item->hoverEnterCount, 0); - QCOMPARE(item->hoverMoveCount, 0); - QCOMPARE(item->hoverLeaveCount, 0); - } - - delete canvas; -} - -void tst_qquickitem::hoverEventInParent() -{ - QQuickCanvas *canvas = new QQuickCanvas(); - canvas->resize(200, 200); - canvas->show(); - - HoverItem *parentItem = new HoverItem(canvas->rootItem()); - parentItem->setSize(QSizeF(200, 200)); - parentItem->setAcceptHoverEvents(true); - - HoverItem *leftItem = new HoverItem(parentItem); - leftItem->setSize(QSizeF(100, 200)); - leftItem->setAcceptHoverEvents(true); - - HoverItem *rightItem = new HoverItem(parentItem); - rightItem->setSize(QSizeF(100, 200)); - rightItem->setPos(QPointF(100, 0)); - rightItem->setAcceptHoverEvents(true); - - const QPoint insideLeft(50, 100); - const QPoint insideRight(150, 100); - - sendMouseMove(canvas, insideLeft); - parentItem->resetCounters(); - leftItem->resetCounters(); - rightItem->resetCounters(); - - sendMouseMove(canvas, insideRight); - QCOMPARE(parentItem->hoverEnterCount, 0); - QCOMPARE(parentItem->hoverLeaveCount, 0); - QCOMPARE(leftItem->hoverEnterCount, 0); - QCOMPARE(leftItem->hoverLeaveCount, 1); - QCOMPARE(rightItem->hoverEnterCount, 1); - QCOMPARE(rightItem->hoverLeaveCount, 0); - - sendMouseMove(canvas, insideLeft); - QCOMPARE(parentItem->hoverEnterCount, 0); - QCOMPARE(parentItem->hoverLeaveCount, 0); - QCOMPARE(leftItem->hoverEnterCount, 1); - QCOMPARE(leftItem->hoverLeaveCount, 1); - QCOMPARE(rightItem->hoverEnterCount, 1); - QCOMPARE(rightItem->hoverLeaveCount, 1); - - delete canvas; -} - -void tst_qquickitem::paintOrder_data() -{ - QTest::addColumn("source"); - QTest::addColumn("op"); - QTest::addColumn("param1"); - QTest::addColumn("param2"); - QTest::addColumn("expected"); - - QTest::newRow("test 1 noop") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(NoOp) << QVariant() << QVariant() - << (QStringList() << "1" << "2" << "3"); - QTest::newRow("test 1 add") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(Append) << QVariant("new") << QVariant() - << (QStringList() << "1" << "2" << "3" << "new"); - QTest::newRow("test 1 remove") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(Remove) << QVariant(1) << QVariant() - << (QStringList() << "1" << "3"); - QTest::newRow("test 1 stack before") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(StackBefore) << QVariant(2) << QVariant(1) - << (QStringList() << "1" << "3" << "2"); - QTest::newRow("test 1 stack after") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(StackAfter) << QVariant(0) << QVariant(1) - << (QStringList() << "2" << "1" << "3"); - QTest::newRow("test 1 set z") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(SetZ) << QVariant(1) << QVariant(qreal(1.)) - << (QStringList() << "1" << "3" << "2"); - - QTest::newRow("test 2 noop") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(NoOp) << QVariant() << QVariant() - << (QStringList() << "1" << "3" << "2"); - QTest::newRow("test 2 add") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(Append) << QVariant("new") << QVariant() - << (QStringList() << "1" << "3" << "new" << "2"); - QTest::newRow("test 2 remove 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(Remove) << QVariant(1) << QVariant() - << (QStringList() << "1" << "3"); - QTest::newRow("test 2 remove 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(Remove) << QVariant(2) << QVariant() - << (QStringList() << "1" << "2"); - QTest::newRow("test 2 stack before 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(StackBefore) << QVariant(1) << QVariant(0) - << (QStringList() << "1" << "3" << "2"); - QTest::newRow("test 2 stack before 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(StackBefore) << QVariant(2) << QVariant(0) - << (QStringList() << "3" << "1" << "2"); - QTest::newRow("test 2 stack after 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(StackAfter) << QVariant(0) << QVariant(1) - << (QStringList() << "1" << "3" << "2"); - QTest::newRow("test 2 stack after 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) - << int(StackAfter) << QVariant(0) << QVariant(2) - << (QStringList() << "3" << "1" << "2"); - QTest::newRow("test 1 set z") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) - << int(SetZ) << QVariant(2) << QVariant(qreal(2.)) - << (QStringList() << "1" << "2" << "3"); -} - -void tst_qquickitem::paintOrder() -{ - QFETCH(QUrl, source); - QFETCH(int, op); - QFETCH(QVariant, param1); - QFETCH(QVariant, param2); - QFETCH(QStringList, expected); - - QQuickView view; - view.setSource(source); - - QQuickItem *root = qobject_cast(view.rootObject()); - QVERIFY(root); - - switch (op) { - case Append: { - QQuickItem *item = new QQuickItem(root); - item->setObjectName(param1.toString()); - } - break; - case Remove: { - QQuickItem *item = root->childItems().at(param1.toInt()); - delete item; - } - break; - case StackBefore: { - QQuickItem *item1 = root->childItems().at(param1.toInt()); - QQuickItem *item2 = root->childItems().at(param2.toInt()); - item1->stackBefore(item2); - } - break; - case StackAfter: { - QQuickItem *item1 = root->childItems().at(param1.toInt()); - QQuickItem *item2 = root->childItems().at(param2.toInt()); - item1->stackAfter(item2); - } - break; - case SetZ: { - QQuickItem *item = root->childItems().at(param1.toInt()); - item->setZ(param2.toReal()); - } - break; - default: - break; - } - - QList list = QQuickItemPrivate::get(root)->paintOrderChildItems(); - - QStringList items; - for (int i = 0; i < list.count(); ++i) - items << list.at(i)->objectName(); - - QCOMPARE(items, expected); -} - - -QTEST_MAIN(tst_qquickitem) - -#include "tst_qquickitem.moc" diff --git a/tests/auto/declarative/qquickitem2/data/childrenProperty.qml b/tests/auto/declarative/qquickitem2/data/childrenProperty.qml deleted file mode 100644 index 85ddbc1446..0000000000 --- a/tests/auto/declarative/qquickitem2/data/childrenProperty.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - property bool test1: root.children.length == 3 - property bool test2: root.children[0] == item1 - property bool test3: root.children[1] == item2 - property bool test4: root.children[2] == item3 - property bool test5: root.children[3] == null - - children: [ Item { id: item1 }, Item { id: item2 }, Item { id: item3 } ] -} - diff --git a/tests/auto/declarative/qquickitem2/data/childrenRect.qml b/tests/auto/declarative/qquickitem2/data/childrenRect.qml deleted file mode 100644 index ebc57aefbe..0000000000 --- a/tests/auto/declarative/qquickitem2/data/childrenRect.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - property int childCount: 0; - - Item { - objectName: "testItem" - width: childrenRect.width - height: childrenRect.height - - Repeater { - id: repeater - model: childCount - delegate: Rectangle { - x: index*10 - y: index*20 - width: 10 - height: 20 - - color: "red" - } - } - } -} diff --git a/tests/auto/declarative/qquickitem2/data/childrenRectBug.qml b/tests/auto/declarative/qquickitem2/data/childrenRectBug.qml deleted file mode 100644 index 86a4f19c5c..0000000000 --- a/tests/auto/declarative/qquickitem2/data/childrenRectBug.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 200 - - Item { - objectName: "theItem" - anchors.centerIn: parent - width: childrenRect.width - height: childrenRect.height - Rectangle { - id: text1 - anchors.verticalCenter: parent.verticalCenter - width: 100; height: 100; color: "green" - } - Rectangle { - anchors.left: text1.right - anchors.verticalCenter: parent.verticalCenter - width: 100; height: 100; color: "green" - } - } -} diff --git a/tests/auto/declarative/qquickitem2/data/childrenRectBug2.qml b/tests/auto/declarative/qquickitem2/data/childrenRectBug2.qml deleted file mode 100644 index 6e80ed28af..0000000000 --- a/tests/auto/declarative/qquickitem2/data/childrenRectBug2.qml +++ /dev/null @@ -1,53 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width:360; - height: 200 - - Item { - objectName: "theItem" - anchors.centerIn: parent - width: childrenRect.width - height: childrenRect.height - Rectangle { - id: header1 - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - width: 100; height: 50 - color: "green" - } - Rectangle { - id: text1 - anchors.top: header1.bottom - anchors.topMargin: 10 - anchors.horizontalCenter: parent.horizontalCenter - width: 100; height: 50 - color: "blue" - } - } - - states: [ - State { - name: "row" - AnchorChanges { - target: header1 - anchors.horizontalCenter: undefined - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.top: undefined - } - AnchorChanges { - target: text1 - anchors.horizontalCenter: undefined - anchors.verticalCenter: parent.verticalCenter - anchors.top: undefined - anchors.left: header1.right - } - PropertyChanges { - target: text1 - anchors.leftMargin: 10 - anchors.topMargin: 0 - } - } - ] -} diff --git a/tests/auto/declarative/qquickitem2/data/childrenRectBug3.qml b/tests/auto/declarative/qquickitem2/data/childrenRectBug3.qml deleted file mode 100644 index 518e76509e..0000000000 --- a/tests/auto/declarative/qquickitem2/data/childrenRectBug3.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 300 - height: 300 - - Rectangle { - height: childrenRect.height - - Repeater { - model: 1 - Rectangle { } - } - } -} diff --git a/tests/auto/declarative/qquickitem2/data/implicitsize.qml b/tests/auto/declarative/qquickitem2/data/implicitsize.qml deleted file mode 100644 index cc6aaf7d60..0000000000 --- a/tests/auto/declarative/qquickitem2/data/implicitsize.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Item { - implicitWidth: 200 - implicitHeight: 100 - - width: 80 - height: 60 - - function resetSize() { - width = undefined - height = undefined - } - - function changeImplicit() { - implicitWidth = 150 - implicitHeight = 80 - } -} diff --git a/tests/auto/declarative/qquickitem2/data/keynavigationtest.qml b/tests/auto/declarative/qquickitem2/data/keynavigationtest.qml deleted file mode 100644 index aacb621fb0..0000000000 --- a/tests/auto/declarative/qquickitem2/data/keynavigationtest.qml +++ /dev/null @@ -1,87 +0,0 @@ -import QtQuick 2.0 - -Grid { - columns: 2 - width: 100; height: 100 - function verify() { - if (item1.KeyNavigation.right != item2) - return false; - if (item1.KeyNavigation.down != item3) - return false; - if (item1.KeyNavigation.tab != item2) - return false; - if (item1.KeyNavigation.backtab != item4) - return false; - - if (item2.KeyNavigation.left != item1) - return false; - if (item2.KeyNavigation.down != item4) - return false; - if (item2.KeyNavigation.tab != item3) - return false; - if (item2.KeyNavigation.backtab != item1) - return false; - - if (item3.KeyNavigation.right != item4) - return false; - if (item3.KeyNavigation.up != item1) - return false; - if (item3.KeyNavigation.tab != item4) - return false; - if (item3.KeyNavigation.backtab != item2) - return false; - - if (item4.KeyNavigation.left != item3) - return false; - if (item4.KeyNavigation.up != item2) - return false; - if (item4.KeyNavigation.tab != item1) - return false; - if (item4.KeyNavigation.backtab != item3) - return false; - - return true; - } - - Rectangle { - id: item1 - objectName: "item1" - focus: true - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item2 - KeyNavigation.down: item3 - KeyNavigation.tab: item2 - KeyNavigation.backtab: item4 - } - Rectangle { - id: item2 - objectName: "item2" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item1 - KeyNavigation.down: item4 - KeyNavigation.tab: item3 - KeyNavigation.backtab: item1 - } - Rectangle { - id: item3 - objectName: "item3" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item4 - KeyNavigation.up: item1 - KeyNavigation.tab: item4 - KeyNavigation.backtab: item2 - } - Rectangle { - id: item4 - objectName: "item4" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item3 - KeyNavigation.up: item2 - KeyNavigation.tab: item1 - KeyNavigation.backtab: item3 - } -} diff --git a/tests/auto/declarative/qquickitem2/data/keynavigationtest_implicit.qml b/tests/auto/declarative/qquickitem2/data/keynavigationtest_implicit.qml deleted file mode 100644 index 92d4ae23de..0000000000 --- a/tests/auto/declarative/qquickitem2/data/keynavigationtest_implicit.qml +++ /dev/null @@ -1,68 +0,0 @@ -import QtQuick 2.0 - -Grid { - columns: 2 - width: 100; height: 100 - function verify() { - if (item1.KeyNavigation.tab != item2) - return false; - if (item1.KeyNavigation.backtab != item4) - return false; - - if (item2.KeyNavigation.left != item1) - return false; - if (item2.KeyNavigation.down != item4) - return false; - if (item2.KeyNavigation.tab != item3) - return false; - if (item2.KeyNavigation.backtab != item1) - return false; - - if (item3.KeyNavigation.right != item4) - return false; - if (item3.KeyNavigation.up != item1) - return false; - if (item3.KeyNavigation.tab != item4) - return false; - if (item3.KeyNavigation.backtab != item2) - return false; - - return true; - } - - Rectangle { - id: item1 - objectName: "item1" - focus: true - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.tab: item2 - KeyNavigation.backtab: item4 - } - Rectangle { - id: item2 - objectName: "item2" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.left: item1 - KeyNavigation.down: item4 - KeyNavigation.tab: item3 - KeyNavigation.backtab: item1 - } - Rectangle { - id: item3 - objectName: "item3" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - KeyNavigation.right: item4 - KeyNavigation.up: item1 - KeyNavigation.tab: item4 - KeyNavigation.backtab: item2 - } - Rectangle { - id: item4 - objectName: "item4" - width: 50; height: 50 - color: focus ? "red" : "lightgray" - } -} diff --git a/tests/auto/declarative/qquickitem2/data/keyspriority.qml b/tests/auto/declarative/qquickitem2/data/keyspriority.qml deleted file mode 100644 index 114cf0488a..0000000000 --- a/tests/auto/declarative/qquickitem2/data/keyspriority.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 -import Test 1.0 - -KeyTestItem { - focus: true - Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) - Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } - Keys.priority: keysTestObject.processLast ? Keys.AfterItem : Keys.BeforeItem -} diff --git a/tests/auto/declarative/qquickitem2/data/keystest.qml b/tests/auto/declarative/qquickitem2/data/keystest.qml deleted file mode 100644 index c70e0061f5..0000000000 --- a/tests/auto/declarative/qquickitem2/data/keystest.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Item { - focus: true - - property bool isEnabled: Keys.enabled - - Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) - Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } - Keys.onReturnPressed: keysTestObject.keyPress(event.key, "Return", event.modifiers) - Keys.onDigit0Pressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) - Keys.onDigit9Pressed: { event.accepted = false; keysTestObject.keyPress(event.key, event.text, event.modifiers) } - Keys.onTabPressed: keysTestObject.keyPress(event.key, "Tab", event.modifiers) - Keys.onBacktabPressed: keysTestObject.keyPress(event.key, "Backtab", event.modifiers) - Keys.forwardTo: [ item2 ] - Keys.enabled: enableKeyHanding - - Item { - id: item2 - visible: forwardeeVisible - Keys.onPressed: keysTestObject.forwardedKey(event.key) - Keys.onReleased: keysTestObject.forwardedKey(event.key) - } -} diff --git a/tests/auto/declarative/qquickitem2/data/layoutmirroring.qml b/tests/auto/declarative/qquickitem2/data/layoutmirroring.qml deleted file mode 100644 index 036819740c..0000000000 --- a/tests/auto/declarative/qquickitem2/data/layoutmirroring.qml +++ /dev/null @@ -1,54 +0,0 @@ -import QtQuick 2.0 - -Item { - property bool childrenInherit: true - Item { - objectName: "mirrored1" - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: parent.childrenInherit - Item { - Item { - objectName: "notMirrored1" - LayoutMirroring.enabled: false - Item { - objectName: "inheritedMirror1" - } - } - Item { - objectName: "inheritedMirror2" - } - } - } - Item { - objectName: "mirrored2" - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: false - Item { - objectName: "notMirrored2" - } - } - Item { - LayoutMirroring.enabled: true - LayoutMirroring.childrenInherit: true - Loader { - id: loader - } - } - states: State { - name: "newContent" - PropertyChanges { - target: loader - sourceComponent: component - } - } - Component { - id: component - Item { - objectName: "notMirrored3" - LayoutMirroring.enabled: false - Item { - objectName: "inheritedMirror3" - } - } - } -} diff --git a/tests/auto/declarative/qquickitem2/data/mapCoordinates.qml b/tests/auto/declarative/qquickitem2/data/mapCoordinates.qml deleted file mode 100644 index 566cb220ff..0000000000 --- a/tests/auto/declarative/qquickitem2/data/mapCoordinates.qml +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Item { - id: root; objectName: "root" - width: 200; height: 200 - - Item { id: itemA; objectName: "itemA"; x: 50; y: 50 } - - Item { - x: 50; y: 50 - Item { id: itemB; objectName: "itemB"; x: 100; y: 100 } - } - - function mapAToB(x, y) { - var pos = itemA.mapToItem(itemB, x, y) - return Qt.point(pos.x, pos.y) - } - - function mapAFromB(x, y) { - var pos = itemA.mapFromItem(itemB, x, y) - return Qt.point(pos.x, pos.y) - } - - function mapAToNull(x, y) { - var pos = itemA.mapToItem(null, x, y) - return Qt.point(pos.x, pos.y) - } - - function mapAFromNull(x, y) { - var pos = itemA.mapFromItem(null, x, y) - return Qt.point(pos.x, pos.y) - } - - function checkMapAToInvalid(x, y) { - var pos = itemA.mapToItem(1122, x, y) - return pos == undefined; - } - - function checkMapAFromInvalid(x, y) { - var pos = itemA.mapFromItem(1122, x, y) - return pos == undefined; - } -} diff --git a/tests/auto/declarative/qquickitem2/data/propertychanges.qml b/tests/auto/declarative/qquickitem2/data/propertychanges.qml deleted file mode 100644 index 3fa5ea9c23..0000000000 --- a/tests/auto/declarative/qquickitem2/data/propertychanges.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Item { - Item { - objectName: "item" - } - Item { - objectName: "parentItem" - } -} diff --git a/tests/auto/declarative/qquickitem2/data/qtbug_16871.qml b/tests/auto/declarative/qquickitem2/data/qtbug_16871.qml deleted file mode 100644 index f1e7377730..0000000000 --- a/tests/auto/declarative/qquickitem2/data/qtbug_16871.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Item { - children: [ 10 ] -} diff --git a/tests/auto/declarative/qquickitem2/data/resourcesProperty.qml b/tests/auto/declarative/qquickitem2/data/resourcesProperty.qml deleted file mode 100644 index b8f18bb375..0000000000 --- a/tests/auto/declarative/qquickitem2/data/resourcesProperty.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - property bool test1 - property bool test2 - property bool test3 - property bool test4 - property bool test5 - - Component.onCompleted: { - test1 = (root.resources.length >= 3) - test2 = root.resources[0] == item1 - test3 = root.resources[1] == item2 - test4 = root.resources[2] == item3 - test5 = root.resources[10] == null - } - - resources: [ Item { id: item1 }, Item { id: item2 }, Item { id: item3 } ] -} diff --git a/tests/auto/declarative/qquickitem2/data/transformCrash.qml b/tests/auto/declarative/qquickitem2/data/transformCrash.qml deleted file mode 100644 index 284e85f0e0..0000000000 --- a/tests/auto/declarative/qquickitem2/data/transformCrash.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -Item { - id: wrapper - width: 200 - height: 200 - - QtObject { - id: object - } - - Component.onCompleted: wrapper.transform = object -} diff --git a/tests/auto/declarative/qquickitem2/qquickitem2.pro b/tests/auto/declarative/qquickitem2/qquickitem2.pro deleted file mode 100644 index 2fe1eb1e3a..0000000000 --- a/tests/auto/declarative/qquickitem2/qquickitem2.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickitem2 -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickitem.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp b/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp deleted file mode 100644 index 3604128ccd..0000000000 --- a/tests/auto/declarative/qquickitem2/tst_qquickitem.cpp +++ /dev/null @@ -1,1254 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_QQuickItem : public QObject -{ - Q_OBJECT -public: - tst_QQuickItem(); - -private slots: - void initTestCase(); - void keys(); - void keysProcessingOrder(); - void keyNavigation(); - void keyNavigation_RightToLeft(); - void keyNavigation_skipNotVisible(); - void keyNavigation_implicitSetting(); - void layoutMirroring(); - void layoutMirroringIllegalParent(); - void smooth(); - void clip(); - void mapCoordinates(); - void mapCoordinates_data(); - void propertyChanges(); - void transforms(); - void transforms_data(); - void childrenRect(); - void childrenRectBug(); - void childrenRectBug2(); - void childrenRectBug3(); - - void childrenProperty(); - void resourcesProperty(); - - void transformCrash(); - void implicitSize(); - void qtbug_16871(); -private: - QDeclarativeEngine engine; -}; - -template -T *findItem(QQuickItem *parent, const QString &objectName) -{ - if (!parent) - return 0; - - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->QQuickItem::children().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) - return static_cast(item); - item = findItem(item, objectName); - if (item) - return static_cast(item); - } - - return 0; -} - -class KeysTestObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged) - -public: - KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {} - - void reset() { - mKey = 0; - mText = QString(); - mModifiers = 0; - mForwardedKey = 0; - } - - bool processLast() const { return mLast; } - void setProcessLast(bool b) { - if (b != mLast) { - mLast = b; - emit processLastChanged(); - } - } - -public slots: - void keyPress(int key, QString text, int modifiers) { - mKey = key; - mText = text; - mModifiers = modifiers; - } - void keyRelease(int key, QString text, int modifiers) { - mKey = key; - mText = text; - mModifiers = modifiers; - } - void forwardedKey(int key) { - mForwardedKey = key; - } - -signals: - void processLastChanged(); - -public: - int mKey; - QString mText; - int mModifiers; - int mForwardedKey; - bool mLast; - -private: -}; - -class KeyTestItem : public QQuickItem -{ - Q_OBJECT -public: - KeyTestItem(QQuickItem *parent=0) : QQuickItem(parent), mKey(0) {} - -protected: - void keyPressEvent(QKeyEvent *e) { - mKey = e->key(); - - if (e->key() == Qt::Key_A) - e->accept(); - else - e->ignore(); - } - - void keyReleaseEvent(QKeyEvent *e) { - if (e->key() == Qt::Key_B) - e->accept(); - else - e->ignore(); - } - -public: - int mKey; -}; - -QML_DECLARE_TYPE(KeyTestItem); - - -tst_QQuickItem::tst_QQuickItem() -{ -} - -void tst_QQuickItem::initTestCase() -{ - qmlRegisterType("Test",1,0,"KeyTestItem"); -} - -void tst_QQuickItem::keys() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - KeysTestObject *testObject = new KeysTestObject; - canvas->rootContext()->setContextProperty("keysTestObject", testObject); - - canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); - canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QVERIFY(canvas->rootObject()); - QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); - - QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_A)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); - QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(!key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_A)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); - QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::ShiftModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_Return)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return)); - QCOMPARE(testObject->mText, QLatin1String("Return")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_0)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0)); - QCOMPARE(testObject->mText, QLatin1String("0")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_9)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9)); - QCOMPARE(testObject->mText, QLatin1String("9")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(!key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_Tab)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab)); - QCOMPARE(testObject->mText, QLatin1String("Tab")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_Backtab)); - QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab)); - QCOMPARE(testObject->mText, QLatin1String("Backtab")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false)); - key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_A)); - QCOMPARE(testObject->mForwardedKey, 0); - QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(!key.isAccepted()); - - testObject->reset(); - - canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false)); - QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, 0); - QVERIFY(!key.isAccepted()); - - canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); - QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_Return)); - QVERIFY(key.isAccepted()); - - delete canvas; - delete testObject; -} - -void tst_QQuickItem::keysProcessingOrder() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - KeysTestObject *testObject = new KeysTestObject; - canvas->rootContext()->setContextProperty("keysTestObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - KeyTestItem *testItem = qobject_cast(canvas->rootObject()); - QVERIFY(testItem); - - QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_A)); - QCOMPARE(testObject->mText, QLatin1String("A")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - testObject->setProcessLast(true); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, 0); - QVERIFY(key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, int(Qt::Key_B)); - QCOMPARE(testObject->mText, QLatin1String("B")); - QVERIFY(testObject->mModifiers == Qt::NoModifier); - QVERIFY(!key.isAccepted()); - - testObject->reset(); - - key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1); - QApplication::sendEvent(canvas, &key); - QCOMPARE(testObject->mKey, 0); - QVERIFY(key.isAccepted()); - - delete canvas; - delete testObject; -} - -QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString) -{ - QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); - QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); - return itemPrivate; -} - -QVariant childProperty(QQuickItem *rootItem, const char * itemString, const char * property) -{ - QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); - return item->property(property); -} - -bool anchorsMirrored(QQuickItem *rootItem, const char * itemString) -{ - QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); - QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); - return itemPrivate->anchors()->mirrored(); -} - -void tst_QQuickItem::layoutMirroring() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("layoutmirroring.qml"))); - canvas->show(); - - QQuickItem *rootItem = qobject_cast(canvas->rootObject()); - QVERIFY(rootItem); - QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(rootItem); - QVERIFY(rootPrivate); - - QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true); - - QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true); - QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true); - QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false); - QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false); - QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true); - QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true); - - QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true); - - QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false); - QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false); - QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true); - - QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true); - QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true); - QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true); - - QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true); - QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false); - QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false); - - // load dynamic content using Loader that needs to inherit mirroring - rootItem->setProperty("state", "newContent"); - QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true); - - QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true); - - QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true); - - QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true); - - QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false); - QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false); - - // disable inheritance - rootItem->setProperty("childrenInherit", false); - - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); - - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false); - - // re-enable inheritance - rootItem->setProperty("childrenInherit", true); - - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); - - QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true); - QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true); - - // - // dynamic parenting - // - QQuickItem *parentItem1 = new QQuickItem(); - QQuickItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true - QQuickItemPrivate::get(parentItem1)->isMirrorImplicit = false; - QQuickItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true - QQuickItemPrivate::get(parentItem1)->resolveLayoutMirror(); - - // inherit in constructor - QQuickItem *childItem1 = new QQuickItem(parentItem1); - QCOMPARE(QQuickItemPrivate::get(childItem1)->effectiveLayoutMirror, true); - QCOMPARE(QQuickItemPrivate::get(childItem1)->inheritMirrorFromParent, true); - - // inherit through a parent change - QQuickItem *childItem2 = new QQuickItem(); - QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); - QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); - childItem2->setParentItem(parentItem1); - QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, true); - QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, true); - - // stop inherting through a parent change - QQuickItem *parentItem2 = new QQuickItem(); - QQuickItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true - QQuickItemPrivate::get(parentItem2)->resolveLayoutMirror(); - childItem2->setParentItem(parentItem2); - QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); - QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); - - delete parentItem1; - delete parentItem2; -} - -void tst_QQuickItem::layoutMirroringIllegalParent() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile("")); - QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items"); - QObject *object = component.create(); - QVERIFY(object != 0); -} - -void tst_QQuickItem::keyNavigation() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QQuickItem *item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - QVariant result; - QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", - Q_RETURN_ARG(QVariant, result))); - QVERIFY(result.toBool()); - - // right - QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // down - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // left - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // up - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // tab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // backtab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - delete canvas; -} - -void tst_QQuickItem::keyNavigation_RightToLeft() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QQuickItem *rootItem = qobject_cast(canvas->rootObject()); - QVERIFY(rootItem); - QQuickItemPrivate* rootItemPrivate = QQuickItemPrivate::get(rootItem); - - rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true - rootItemPrivate->isMirrorImplicit = false; - rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true - rootItemPrivate->resolveLayoutMirror(); - - QEvent wa(QEvent::WindowActivate); - QApplication::sendEvent(canvas, &wa); - QFocusEvent fe(QEvent::FocusIn); - QApplication::sendEvent(canvas, &fe); - - QQuickItem *item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - QVariant result; - QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", - Q_RETURN_ARG(QVariant, result))); - QVERIFY(result.toBool()); - - // right - QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // left - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - delete canvas; -} - -void tst_QQuickItem::keyNavigation_skipNotVisible() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QQuickItem *item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // Set item 2 to not visible - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - item->setVisible(false); - QVERIFY(!item->isVisible()); - - // right - QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // tab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // backtab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - //Set item 3 to not visible - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - item->setVisible(false); - QVERIFY(!item->isVisible()); - - // tab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // backtab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - delete canvas; -} - -void tst_QQuickItem::keyNavigation_implicitSetting() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QEvent wa(QEvent::WindowActivate); - QApplication::sendEvent(canvas, &wa); - QFocusEvent fe(QEvent::FocusIn); - QApplication::sendEvent(canvas, &fe); - - QQuickItem *item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - QVariant result; - QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", - Q_RETURN_ARG(QVariant, result))); - QVERIFY(result.toBool()); - - // right - QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // back to item1 - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // down - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // move to item4 - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // left - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // back to item4 - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // up - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item2"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // back to item4 - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // tab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item1"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // back to item4 - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item4"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - // backtab - key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); - QApplication::sendEvent(canvas, &key); - QVERIFY(key.isAccepted()); - - item = findItem(canvas->rootObject(), "item3"); - QVERIFY(item); - QVERIFY(item->hasActiveFocus()); - - delete canvas; -} - -void tst_QQuickItem::smooth() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QSignalSpy spy(item, SIGNAL(smoothChanged(bool))); - - QVERIFY(item); - QVERIFY(!item->smooth()); - - item->setSmooth(true); - QVERIFY(item->smooth()); - QCOMPARE(spy.count(),1); - QList arguments = spy.first(); - QVERIFY(arguments.count() == 1); - QVERIFY(arguments.at(0).toBool() == true); - - item->setSmooth(true); - QCOMPARE(spy.count(),1); - - item->setSmooth(false); - QVERIFY(!item->smooth()); - QCOMPARE(spy.count(),2); - item->setSmooth(false); - QCOMPARE(spy.count(),2); - - delete item; -} - -void tst_QQuickItem::clip() -{ - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QSignalSpy spy(item, SIGNAL(clipChanged(bool))); - - QVERIFY(item); - QVERIFY(!item->clip()); - - item->setClip(true); - QVERIFY(item->clip()); - - QList arguments = spy.first(); - QVERIFY(arguments.count() == 1); - QVERIFY(arguments.at(0).toBool() == true); - - QCOMPARE(spy.count(),1); - item->setClip(true); - QCOMPARE(spy.count(),1); - - item->setClip(false); - QVERIFY(!item->clip()); - QCOMPARE(spy.count(),2); - item->setClip(false); - QCOMPARE(spy.count(),2); - - delete item; -} - -void tst_QQuickItem::mapCoordinates() -{ - QFETCH(int, x); - QFETCH(int, y); - - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(300, 300)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root != 0); - QQuickItem *a = findItem(canvas->rootObject(), "itemA"); - QVERIFY(a != 0); - QQuickItem *b = findItem(canvas->rootObject(), "itemB"); - QVERIFY(b != 0); - - QVariant result; - - QVERIFY(QMetaObject::invokeMethod(root, "mapAToB", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QCOMPARE(result.value(), qobject_cast(a)->mapToItem(b, QPointF(x, y))); - - QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QCOMPARE(result.value(), qobject_cast(a)->mapFromItem(b, QPointF(x, y))); - - QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QCOMPARE(result.value(), qobject_cast(a)->mapToScene(QPointF(x, y))); - - QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QCOMPARE(result.value(), qobject_cast(a)->mapFromScene(QPointF(x, y))); - - QString warning1 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item"; - QString warning2 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item"; - - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); - QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QVERIFY(result.toBool()); - - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); - QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid", - Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); - QVERIFY(result.toBool()); - - delete canvas; -} - -void tst_QQuickItem::mapCoordinates_data() -{ - QTest::addColumn("x"); - QTest::addColumn("y"); - - for (int i=-20; i<=20; i+=10) - QTest::newRow(QTest::toString(i)) << i << i; -} - -void tst_QQuickItem::transforms_data() -{ - QTest::addColumn("qml"); - QTest::addColumn("transform"); - QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }") - << QTransform(1,0,0,0,1,0,10,20,1); - QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }") - << QTransform(0,1,0,-1,0,0,0,0,1); - QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2 }") - << QTransform(1.5,0,0,0,-2,0,0,0,1); - QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2 } ]") - << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1); -} - -void tst_QQuickItem::transforms() -{ - QFETCH(QByteArray, qml); - QFETCH(QTransform, transform); - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(item->itemTransform(0,0), transform); -} - -void tst_QQuickItem::childrenProperty() -{ - QDeclarativeComponent component(&engine, TESTDATA("childrenProperty.qml")); - - QObject *o = component.create(); - QVERIFY(o != 0); - - QCOMPARE(o->property("test1").toBool(), true); - QCOMPARE(o->property("test2").toBool(), true); - QCOMPARE(o->property("test3").toBool(), true); - QCOMPARE(o->property("test4").toBool(), true); - QCOMPARE(o->property("test5").toBool(), true); - delete o; -} - -void tst_QQuickItem::resourcesProperty() -{ - QDeclarativeComponent component(&engine, TESTDATA("resourcesProperty.qml")); - - QObject *o = component.create(); - QVERIFY(o != 0); - - QCOMPARE(o->property("test1").toBool(), true); - QCOMPARE(o->property("test2").toBool(), true); - QCOMPARE(o->property("test3").toBool(), true); - QCOMPARE(o->property("test4").toBool(), true); - QCOMPARE(o->property("test5").toBool(), true); - delete o; -} - -void tst_QQuickItem::propertyChanges() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(300, 300)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); - - QQuickItem *item = findItem(canvas->rootObject(), "item"); - QQuickItem *parentItem = findItem(canvas->rootObject(), "parentItem"); - - QVERIFY(item); - QVERIFY(parentItem); - - QSignalSpy parentSpy(item, SIGNAL(parentChanged(QQuickItem *))); - QSignalSpy widthSpy(item, SIGNAL(widthChanged())); - QSignalSpy heightSpy(item, SIGNAL(heightChanged())); - QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal))); - QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF))); - QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); - QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool))); - QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged())); - QSignalSpy xSpy(item, SIGNAL(xChanged())); - QSignalSpy ySpy(item, SIGNAL(yChanged())); - - item->setParentItem(parentItem); - item->setWidth(100.0); - item->setHeight(200.0); - item->setFocus(true); - item->setBaselineOffset(10.0); - - QCOMPARE(item->parentItem(), parentItem); - QCOMPARE(parentSpy.count(),1); - QList parentArguments = parentSpy.first(); - QVERIFY(parentArguments.count() == 1); - QCOMPARE(item->parentItem(), qvariant_cast(parentArguments.at(0))); - QCOMPARE(childrenChangedSpy.count(),1); - - item->setParentItem(parentItem); - QCOMPARE(childrenChangedSpy.count(),1); - - QCOMPARE(item->width(), 100.0); - QCOMPARE(widthSpy.count(),1); - - QCOMPARE(item->height(), 200.0); - QCOMPARE(heightSpy.count(),1); - - QCOMPARE(item->baselineOffset(), 10.0); - QCOMPARE(baselineOffsetSpy.count(),1); - QList baselineOffsetArguments = baselineOffsetSpy.first(); - QVERIFY(baselineOffsetArguments.count() == 1); - QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); - - QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); - QCOMPARE(childrenRectSpy.count(),1); - QList childrenRectArguments = childrenRectSpy.at(0); - QVERIFY(childrenRectArguments.count() == 1); - QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); - - QCOMPARE(item->hasActiveFocus(), true); - QCOMPARE(focusSpy.count(),1); - QList focusArguments = focusSpy.first(); - QVERIFY(focusArguments.count() == 1); - QCOMPARE(focusArguments.at(0).toBool(), true); - - QCOMPARE(parentItem->hasActiveFocus(), false); - QCOMPARE(parentItem->hasFocus(), false); - QCOMPARE(wantsFocusSpy.count(),0); - - item->setX(10.0); - QCOMPARE(item->x(), 10.0); - QCOMPARE(xSpy.count(), 1); - - item->setY(10.0); - QCOMPARE(item->y(), 10.0); - QCOMPARE(ySpy.count(), 1); - - delete canvas; -} - -void tst_QQuickItem::childrenRect() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRect.qml"))); - canvas->setBaseSize(QSize(240,320)); - canvas->show(); - - QQuickItem *o = canvas->rootObject(); - QQuickItem *item = o->findChild("testItem"); - QCOMPARE(item->width(), qreal(0)); - QCOMPARE(item->height(), qreal(0)); - - o->setProperty("childCount", 1); - QCOMPARE(item->width(), qreal(10)); - QCOMPARE(item->height(), qreal(20)); - - o->setProperty("childCount", 5); - QCOMPARE(item->width(), qreal(50)); - QCOMPARE(item->height(), qreal(100)); - - o->setProperty("childCount", 0); - QCOMPARE(item->width(), qreal(0)); - QCOMPARE(item->height(), qreal(0)); - - delete o; - delete canvas; -} - -// QTBUG-11383 -void tst_QQuickItem::childrenRectBug() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug.qml"))); - canvas->show(); - - QQuickItem *o = canvas->rootObject(); - QQuickItem *item = o->findChild("theItem"); - QCOMPARE(item->width(), qreal(200)); - QCOMPARE(item->height(), qreal(100)); - QCOMPARE(item->x(), qreal(100)); - - delete canvas; -} - -// QTBUG-11465 -void tst_QQuickItem::childrenRectBug2() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug2.qml"))); - canvas->show(); - - QQuickRectangle *rect = qobject_cast(canvas->rootObject()); - QVERIFY(rect); - QQuickItem *item = rect->findChild("theItem"); - QCOMPARE(item->width(), qreal(100)); - QCOMPARE(item->height(), qreal(110)); - QCOMPARE(item->x(), qreal(130)); - - QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); - rectPrivate->setState("row"); - QCOMPARE(item->width(), qreal(210)); - QCOMPARE(item->height(), qreal(50)); - QCOMPARE(item->x(), qreal(75)); - - delete canvas; -} - -// QTBUG-12722 -void tst_QQuickItem::childrenRectBug3() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug3.qml"))); - canvas->show(); - - //don't crash on delete - delete canvas; -} - -// QTBUG-13893 -void tst_QQuickItem::transformCrash() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("transformCrash.qml"))); - canvas->show(); - - delete canvas; -} - -void tst_QQuickItem::implicitSize() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("implicitsize.qml"))); - canvas->show(); - - QQuickItem *item = qobject_cast(canvas->rootObject()); - QVERIFY(item); - QCOMPARE(item->width(), qreal(80)); - QCOMPARE(item->height(), qreal(60)); - - QCOMPARE(item->implicitWidth(), qreal(200)); - QCOMPARE(item->implicitHeight(), qreal(100)); - - QMetaObject::invokeMethod(item, "resetSize"); - - QCOMPARE(item->width(), qreal(200)); - QCOMPARE(item->height(), qreal(100)); - - QMetaObject::invokeMethod(item, "changeImplicit"); - - QCOMPARE(item->implicitWidth(), qreal(150)); - QCOMPARE(item->implicitHeight(), qreal(80)); - QCOMPARE(item->width(), qreal(150)); - QCOMPARE(item->height(), qreal(80)); - - delete canvas; -} - -void tst_QQuickItem::qtbug_16871() -{ - QDeclarativeComponent component(&engine, TESTDATA("qtbug_16871.qml")); - QObject *o = component.create(); - QVERIFY(o != 0); - delete o; -} - -QTEST_MAIN(tst_QQuickItem) - -#include "tst_qquickitem.moc" diff --git a/tests/auto/declarative/qquicklistview/data/ComponentView.qml b/tests/auto/declarative/qquicklistview/data/ComponentView.qml deleted file mode 100644 index 3e87be8799..0000000000 --- a/tests/auto/declarative/qquicklistview/data/ComponentView.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 - -ListView { - id: view - - property string title - - width: 100; height: 100; - - model: 1 - delegate: Text { objectName: "listItem"; text: view.title } - header: Text { objectName: "header"; text: view.title } - footer: Text { objectName: "footer"; text: view.title } - section.delegate: Text { objectName: "section"; text: view.title } - section.property: "modelData" -} diff --git a/tests/auto/declarative/qquicklistview/data/asyncloader.qml b/tests/auto/declarative/qquicklistview/data/asyncloader.qml deleted file mode 100644 index f038f0960c..0000000000 --- a/tests/auto/declarative/qquicklistview/data/asyncloader.qml +++ /dev/null @@ -1,36 +0,0 @@ - -import QtQuick 2.0 - -Rectangle { - id: root - width: 300; height: 400 - color: "#2200FF00" - - Loader { - asynchronous: true - sourceComponent: viewComp - anchors.fill: parent - } - - Component { - id: viewComp - ListView { - objectName: "view" - width: 300; height: 400 - model: 20 - delegate: aDelegate - - highlight: Rectangle { color: "lightsteelblue" } - } - } - // The delegate for each list - Component { - id: aDelegate - Item { - objectName: "wrapper" - width: 300 - height: 50 - Text { text: 'Index: ' + index } - } - } -} diff --git a/tests/auto/declarative/qquicklistview/data/attachedSignals.qml b/tests/auto/declarative/qquicklistview/data/attachedSignals.qml deleted file mode 100644 index 2c3c0bbada..0000000000 --- a/tests/auto/declarative/qquicklistview/data/attachedSignals.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -ListView { - id: view - width: 240; height: 320 - - property variant addedDelegates: [] - property int removedDelegateCount - - model: testModel - - delegate: Rectangle { - width: 200; height: delegateHeight - border.width: 1 - ListView.onAdd: { - var obj = ListView.view.addedDelegates - obj.push(model.name) - ListView.view.addedDelegates = obj - } - ListView.onRemove: { - view.removedDelegateCount += 1 - } - } -} diff --git a/tests/auto/declarative/qquicklistview/data/creationContext.qml b/tests/auto/declarative/qquicklistview/data/creationContext.qml deleted file mode 100644 index 79a682788b..0000000000 --- a/tests/auto/declarative/qquicklistview/data/creationContext.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -ComponentView { - title: "Hello!" -} diff --git a/tests/auto/declarative/qquicklistview/data/displaylist.qml b/tests/auto/declarative/qquicklistview/data/displaylist.qml deleted file mode 100644 index 4e8fd32f6a..0000000000 --- a/tests/auto/declarative/qquicklistview/data/displaylist.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - property real delegateHeight: 20 - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: root.delegateHeight - Behavior on height { NumberAnimation { duration: 200} } - width: 240 - Text { - text: index - } - Text { - x: 30 - objectName: "displayText" - text: display - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - }, - Component { - id: myHighlight - Rectangle { color: "green" } - } - ] - ListView { - id: list - objectName: "list" - focus: true - width: 240 - height: 320 - model: testModel - delegate: myDelegate - highlight: myHighlight - highlightMoveSpeed: 1000 - highlightResizeSpeed: 1000 - } -} diff --git a/tests/auto/declarative/qquicklistview/data/fillModelOnComponentCompleted.qml b/tests/auto/declarative/qquicklistview/data/fillModelOnComponentCompleted.qml deleted file mode 100644 index 906e6adb6b..0000000000 --- a/tests/auto/declarative/qquicklistview/data/fillModelOnComponentCompleted.qml +++ /dev/null @@ -1,36 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - - ListModel { id: testModel } - - ListView { - id: list - objectName: "list" - width: parent.width - anchors.top: parent.top - anchors.bottom: parent.bottom - model: testModel - - delegate: Text { - objectName: "wrapper" - font.pointSize: 20 - text: index - } - footer: Rectangle { - width: parent.width - height: 40 - color: "green" - } - header: Text { objectName: "header"; text: "Header" } - } - - Component.onCompleted: { - if (setCurrentToZero == 0) - list.currentIndex = 0 - for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i}) - } -} diff --git a/tests/auto/declarative/qquicklistview/data/footer.qml b/tests/auto/declarative/qquicklistview/data/footer.qml deleted file mode 100644 index 2a5619999e..0000000000 --- a/tests/auto/declarative/qquicklistview/data/footer.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property bool showHeader: false - - function changeFooter() { - list.footer = footer2 - } - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 40 - Text { - text: index + " " + x + "," + y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - } - Component { - id: headerComponent - Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } - } - - ListView { - id: list - objectName: "list" - focus: true - width: 240 - height: 320 - model: testModel - delegate: myDelegate - header: parent.showHeader ? headerComponent : null - footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 } - } - - Component { - id: footer2 - Text { objectName: "footer2"; text: "Footer 2 " + x + "," + y; width: 50; height: 20 } - } -} diff --git a/tests/auto/declarative/qquicklistview/data/header.qml b/tests/auto/declarative/qquicklistview/data/header.qml deleted file mode 100644 index bf70310630..0000000000 --- a/tests/auto/declarative/qquicklistview/data/header.qml +++ /dev/null @@ -1,39 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - function changeHeader() { - list.header = header2 - } - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 30 - width: 240 - Text { - text: index + " " + x + "," + y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ListView { - id: list - objectName: "list" - focus: true - width: initialViewWidth - height: initialViewHeight - snapMode: ListView.SnapToItem - model: testModel - delegate: myDelegate - header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } - } - Component { - id: header2 - Text { objectName: "header2"; text: "Header " + x + "," + y; width: 50; height: 20 } - } - -} diff --git a/tests/auto/declarative/qquicklistview/data/headerfooter.qml b/tests/auto/declarative/qquicklistview/data/headerfooter.qml deleted file mode 100644 index 8e8463d645..0000000000 --- a/tests/auto/declarative/qquicklistview/data/headerfooter.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -ListView { - id: view - property bool horizontal: false - property bool rtl: false - width: 240 - height: 320 - - orientation: horizontal ? ListView.Horizontal : ListView.Vertical - header: Rectangle { - objectName: "header" - width: horizontal ? 20 : view.width - height: horizontal ? view.height : 20 - color: "red" - } - footer: Rectangle { - objectName: "footer" - width: horizontal ? 30 : view.width - height: horizontal ? view.height : 30 - color: "blue" - } - - delegate: Text { width: 30; height: 30; text: index + "(" + x + ")" } - layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight -} diff --git a/tests/auto/declarative/qquicklistview/data/itemlist.qml b/tests/auto/declarative/qquicklistview/data/itemlist.qml deleted file mode 100644 index 5c7ecdd5e8..0000000000 --- a/tests/auto/declarative/qquicklistview/data/itemlist.qml +++ /dev/null @@ -1,46 +0,0 @@ -// This example demonstrates placing items in a view using -// a VisualItemModel - -import QtQuick 2.0 - -Rectangle { - color: "lightgray" - width: 240 - height: 320 - - VisualItemModel { - id: itemModel - objectName: "itemModel" - Rectangle { - objectName: "item1" - height: ListView.view ? ListView.view.height : 0 - width: view.width; color: "#FFFEF0" - Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item2" - height: ListView.view ? ListView.view.height : 0 - width: view.width; color: "#F0FFF7" - Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item3" - height: ListView.view ? ListView.view.height : 0 - width: view.width; color: "#F4F0FF" - Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - } - - ListView { - id: view - objectName: "view" - anchors.fill: parent - anchors.bottomMargin: 30 - model: itemModel - preferredHighlightBegin: 0 - preferredHighlightEnd: 0 - highlightRangeMode: "StrictlyEnforceRange" - orientation: ListView.Horizontal - flickDeceleration: 2000 - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listview-enforcerange-nohighlight.qml b/tests/auto/declarative/qquicklistview/data/listview-enforcerange-nohighlight.qml deleted file mode 100644 index 1db1096499..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-enforcerange-nohighlight.qml +++ /dev/null @@ -1,61 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - color: "transparent" - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - } - } - - Rectangle { // current listview item should be always in this area - y: 100 - height: 20 - width: 240 - color: "purple" - } - - ListView { - id: list - objectName: "list" - width: 240 - height: 320 - model: testModel - delegate: myDelegate - focus: true - - preferredHighlightBegin: 100 - preferredHighlightEnd: 100 - highlightRangeMode: "StrictlyEnforceRange" - - section.property: "number" - section.delegate: Rectangle { width: 240; height: 10; color: "lightsteelblue" } - } -} - diff --git a/tests/auto/declarative/qquicklistview/data/listview-enforcerange.qml b/tests/auto/declarative/qquicklistview/data/listview-enforcerange.qml deleted file mode 100644 index f1bf6c2b57..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-enforcerange.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Item { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - } - } - - Component { - id: myHighlight - Rectangle { - color: "lightsteelblue" - } - } - - ListView { - id: list - objectName: "list" - width: 240 - height: 320 - model: testModel - delegate: myDelegate - highlight: myHighlight - preferredHighlightBegin: 100 - preferredHighlightEnd: 100 - highlightRangeMode: "StrictlyEnforceRange" - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listview-initCurrent.qml b/tests/auto/declarative/qquicklistview/data/listview-initCurrent.qml deleted file mode 100644 index c4f1860eda..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-initCurrent.qml +++ /dev/null @@ -1,64 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - - property int current: list.currentIndex - property bool showHeader: false - property bool showFooter: false - - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ] - - Component { - id: headerFooter - Rectangle { height: 30; width: 240; color: "blue" } - } - - ListView { - id: list - objectName: "list" - focus: true - currentIndex: 20 - width: 240 - height: 320 - keyNavigationWraps: testWrap - delegate: myDelegate - highlightMoveSpeed: 1000 - model: testModel - header: root.showHeader ? headerFooter : null - footer: root.showFooter ? headerFooter : null - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listview-noCurrent.qml b/tests/auto/declarative/qquicklistview/data/listview-noCurrent.qml deleted file mode 100644 index 079966d8e4..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-noCurrent.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property int current: list.currentIndex - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ] - ListView { - id: list - objectName: "list" - focus: true - currentIndex: -1 - width: 240 - height: 320 - delegate: myDelegate - highlightMoveSpeed: 1000 - model: testModel - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listview-sections.qml b/tests/auto/declarative/qquicklistview/data/listview-sections.qml deleted file mode 100644 index d5b8a4400d..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-sections.qml +++ /dev/null @@ -1,64 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Item { - id: wrapper - objectName: "wrapper" - height: ListView.previousSection != ListView.section ? 40 : 20; - width: 240 - Rectangle { - y: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 - height: 20 - width: parent.width - color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white" - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 100 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - objectName: "nextSection" - x: 150 - text: wrapper.ListView.nextSection - } - Text { - x: 200 - text: wrapper.y - } - } - Rectangle { - color: "#99bb99" - height: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 - width: parent.width - visible: wrapper.ListView.previousSection != wrapper.ListView.section ? true : false - Text { text: wrapper.ListView.section } - } - } - } - ] - ListView { - id: list - objectName: "list" - width: 240 - height: 320 - model: testModel - delegate: myDelegate - section.property: "number" - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listview-sections_delegate.qml b/tests/auto/declarative/qquicklistview/data/listview-sections_delegate.qml deleted file mode 100644 index 496d8d7784..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listview-sections_delegate.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property string sectionProperty: "number" - property int sectionPositioning: ViewSection.InlineLabels - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: myDelegate - Item { - id: wrapper - objectName: "wrapper" - height: 20; - width: 240 - Rectangle { - height: 20 - width: parent.width - color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white" - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 100 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - objectName: "nextSection" - x: 150 - text: wrapper.ListView.nextSection - } - Text { - x: 200 - text: wrapper.y - } - } - ListView.onRemove: SequentialAnimation { - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "height"; to: 0; duration: 100; easing.type: Easing.InOutQuad } - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } - } - } - } - ] - ListView { - id: list - objectName: "list" - width: 240 - height: 320 - model: testModel - delegate: myDelegate - section.property: sectionProperty - section.delegate: Rectangle { - objectName: "sect_" + section - color: "#99bb99" - height: 20 - width: list.width - Text { text: section + ", " + parent.y + ", " + parent.objectName } - } - section.labelPositioning: sectionPositioning - } -} diff --git a/tests/auto/declarative/qquicklistview/data/listviewtest.qml b/tests/auto/declarative/qquicklistview/data/listviewtest.qml deleted file mode 100644 index 47b341c1fc..0000000000 --- a/tests/auto/declarative/qquicklistview/data/listviewtest.qml +++ /dev/null @@ -1,133 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 240 - height: 320 - color: "#ffffff" - - property int count: list.count - property bool showHeader: false - property bool showFooter: false - property real hr: list.visibleArea.heightRatio - function heightRatio() { - return list.visibleArea.heightRatio - } - - function checkProperties() { - testObject.error = false; - if (list.model != testModel) { - console.log("model property incorrect"); - testObject.error = true; - } - if (!testObject.animate && list.delegate != myDelegate) { - console.log("delegate property incorrect - expected myDelegate"); - testObject.error = true; - } - if (testObject.animate && list.delegate != animatedDelegate) { - console.log("delegate property incorrect - expected animatedDelegate"); - testObject.error = true; - } - if (testObject.invalidHighlight && list.highlight != invalidHl) { - console.log("highlight property incorrect - expected invalidHl"); - testObject.error = true; - } - if (!testObject.invalidHighlight && list.highlight != myHighlight) { - console.log("highlight property incorrect - expected myHighlight"); - testObject.error = true; - } - } - resources: [ - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "#EEEEEE" - } - }, - Component { - id: animatedDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - ListView.onRemove: SequentialAnimation { - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } - PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } - - } - } - }, - Component { - id: myHighlight - Rectangle { color: "green" } - }, - Component { - id: invalidHl - SmoothedAnimation {} - }, - Component { - id: headerFooter - Rectangle { height: 30; width: 240; color: "blue" } - } - ] - ListView { - id: list - objectName: "list" - focus: true - width: 240 - height: 320 - model: testModel - delegate: testObject.animate ? animatedDelegate : myDelegate - highlight: testObject.invalidHighlight ? invalidHl : myHighlight - highlightMoveSpeed: 1000 - highlightResizeSpeed: 1000 - cacheBuffer: testObject.cacheBuffer - header: root.showHeader ? headerFooter : null - footer: root.showFooter ? headerFooter : null - } -} diff --git a/tests/auto/declarative/qquicklistview/data/manual-highlight.qml b/tests/auto/declarative/qquicklistview/data/manual-highlight.qml deleted file mode 100644 index aac4599f01..0000000000 --- a/tests/auto/declarative/qquicklistview/data/manual-highlight.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.0 - -Item { - - ListModel { - id: model - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - ListElement { - name: "Bob Brown" - number: "555 5845" - } - } - - Component { - id: highlight - Rectangle { - objectName: "highlight" - width: 180; height: 20 - color: "lightsteelblue"; radius: 5 - y: list.currentItem.y+5 - } - } - - ListView { - id: list - objectName: "list" - anchors.fill: parent - model: model - delegate: Text { objectName: "wrapper"; text: name } - - highlight: highlight - highlightFollowsCurrentItem: false - focus: true - } - -} diff --git a/tests/auto/declarative/qquicklistview/data/margins.qml b/tests/auto/declarative/qquicklistview/data/margins.qml deleted file mode 100644 index 19bbef500f..0000000000 --- a/tests/auto/declarative/qquicklistview/data/margins.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 240 - height: 320 - color: "#ffffff" - - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 240 - Text { - text: index - } - Text { - x: 30 - id: textName - objectName: "textName" - text: name - } - Text { - x: 120 - id: textNumber - objectName: "textNumber" - text: number - } - Text { - x: 200 - text: wrapper.y - } - color: ListView.isCurrentItem ? "lightsteelblue" : "white" - } - } - ListView { - id: list - objectName: "list" - anchors.fill: parent - topMargin: 30 - bottomMargin: 50 - model: testModel - delegate: myDelegate - } -} diff --git a/tests/auto/declarative/qquicklistview/data/propertychangestest.qml b/tests/auto/declarative/qquicklistview/data/propertychangestest.qml deleted file mode 100644 index 146f3f13b0..0000000000 --- a/tests/auto/declarative/qquicklistview/data/propertychangestest.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 180; height: 120; color: "white" - Component { - id: delegate - Item { - id: wrapper - width: 180; height: 40; - Column { - x: 5; y: 5 - Text { text: 'Name: ' + name } - Text { text: 'Number: ' + number } - } - } - } - Component { - id: highlightRed - Rectangle { - color: "red" - radius: 10 - opacity: 0.5 - } - } - ListView { - objectName: "listView" - anchors.fill: parent - model: listModel - delegate: delegate - highlight: highlightRed - focus: true - highlightFollowsCurrentItem: true - preferredHighlightBegin: 0.0 - preferredHighlightEnd: 0.0 - highlightRangeMode: ListView.ApplyRange - keyNavigationWraps: true - cacheBuffer: 10 - snapMode: ListView.SnapToItem - } - - data:[ - ListModel { - id: listModel - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - }, - ListModel { - objectName: "alternateModel" - ListElement { - name: "Jack" - number: "555 8426" - } - ListElement { - name: "Mary" - number: "555 3264" - } - } - ] -} - - diff --git a/tests/auto/declarative/qquicklistview/data/qtbug-21742.qml b/tests/auto/declarative/qquicklistview/data/qtbug-21742.qml deleted file mode 100644 index 774f9041fb..0000000000 --- a/tests/auto/declarative/qquicklistview/data/qtbug-21742.qml +++ /dev/null @@ -1,36 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - height: 200 - width: 200 - property int count: menuView.count - - Component.onCompleted: { setModel(); } - - function setModel() - { - menuModel.append({"enabledItem" : true}); - menuView.currentIndex = 0; - } - - ListModel { - id: menuModel - } - - ListView { - id: menuView - anchors.fill: parent - model: menuModel - delegate: mything - } - - Component { - id: mything - Rectangle { - height: 50 - width: 200 - color: index == menuView.currentIndex ? "green" : "blue" - } - } - -} \ No newline at end of file diff --git a/tests/auto/declarative/qquicklistview/data/qtbug14821.qml b/tests/auto/declarative/qquicklistview/data/qtbug14821.qml deleted file mode 100644 index 0a5e0acbb4..0000000000 --- a/tests/auto/declarative/qquicklistview/data/qtbug14821.qml +++ /dev/null @@ -1,31 +0,0 @@ -import QtQuick 2.0 - -ListView { - id: view - width: 300; height: 200 - focus: true - keyNavigationWraps: true - - model: 100 - - preferredHighlightBegin: 90 - preferredHighlightEnd: 110 - - highlightRangeMode: ListView.StrictlyEnforceRange - highlight: Component { - Rectangle { - border.color: "blue" - border.width: 3 - color: "transparent" - width: 300; height: 15 - } - } - - delegate: Component { - Item { - height: 15 + (view.currentIndex == index ? 20 : 0) - width: 200 - Text { text: 'Index: ' + index; anchors.verticalCenter: parent.verticalCenter } - } - } -} diff --git a/tests/auto/declarative/qquicklistview/data/qtbug16037.qml b/tests/auto/declarative/qquicklistview/data/qtbug16037.qml deleted file mode 100644 index 21faeb3f32..0000000000 --- a/tests/auto/declarative/qquicklistview/data/qtbug16037.qml +++ /dev/null @@ -1,37 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - - function setModel() { - listView.model = listModel1 - } - - ListModel { - id: listModel1 - ListElement { text: "Apple" } - ListElement { text: "Banana" } - ListElement { text: "Orange" } - ListElement { text: "Coconut" } - } - - Rectangle { - width: 200 - height: listView.contentHeight - color: "yellow" - anchors.centerIn: parent - - ListView { - id: listView - objectName: "listview" - anchors.fill: parent - - delegate: Item { - width: 200 - height: 20 - Text { text: model.text; anchors.centerIn: parent } - } - } - } -} diff --git a/tests/auto/declarative/qquicklistview/data/resizeview.qml b/tests/auto/declarative/qquicklistview/data/resizeview.qml deleted file mode 100644 index 071cdedf2e..0000000000 --- a/tests/auto/declarative/qquicklistview/data/resizeview.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - - property real initialHeight - - ListView { - id: list - objectName: "list" - width: 240 - height: initialHeight - model: testModel - delegate: Rectangle { - objectName: "wrapper" - width: 240 - height: 20 - border.width: 1 - } - } -} - diff --git a/tests/auto/declarative/qquicklistview/data/rightToLeft.qml b/tests/auto/declarative/qquicklistview/data/rightToLeft.qml deleted file mode 100644 index 6d77de26f4..0000000000 --- a/tests/auto/declarative/qquicklistview/data/rightToLeft.qml +++ /dev/null @@ -1,42 +0,0 @@ -// This example demonstrates how item positioning -// changes in right-to-left layout direction - -import QtQuick 2.0 - -Rectangle { - color: "lightgray" - width: 640 - height: 320 - - VisualItemModel { - id: itemModel - objectName: "itemModel" - Rectangle { - objectName: "item1" - height: view.height; width: 100; color: "#FFFEF0" - Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item2" - height: view.height; width: 200; color: "#F0FFF7" - Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item3" - height: view.height; width: 240; color: "#F4F0FF" - Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - } - - ListView { - id: view - objectName: "view" - anchors.fill: parent - anchors.bottomMargin: 30 - model: itemModel - highlightRangeMode: "StrictlyEnforceRange" - orientation: ListView.Horizontal - flickDeceleration: 2000 - layoutDirection: Qt.RightToLeft - } -} diff --git a/tests/auto/declarative/qquicklistview/data/sizelessthan1.qml b/tests/auto/declarative/qquicklistview/data/sizelessthan1.qml deleted file mode 100644 index aa9dc20ae9..0000000000 --- a/tests/auto/declarative/qquicklistview/data/sizelessthan1.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 0.5 - width: 240 - color: ((index % 2) == 1 ? "red" : "blue") - } - } - ListView { - id: list - objectName: "list" - focus: true - width: 240 - height: 320 - model: testModel - delegate: myDelegate - } -} diff --git a/tests/auto/declarative/qquicklistview/data/snapToItem.qml b/tests/auto/declarative/qquicklistview/data/snapToItem.qml deleted file mode 100644 index 6f201072f0..0000000000 --- a/tests/auto/declarative/qquicklistview/data/snapToItem.qml +++ /dev/null @@ -1,49 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - width: 240 - height: 240 - color: "#ffffff" - - Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 80 - width: 80 - Column { - Text { - text: index - } - Text { - text: wrapper.x + ", " + wrapper.y - } - } - color: ListView.isCurrentItem ? "lightsteelblue" : "transparent" - } - } - ListView { - id: list - objectName: "list" - anchors.fill: parent -// preferredHighlightBegin: 20 -// preferredHighlightEnd: 100 - preferredHighlightBegin: 20 - preferredHighlightEnd: 100 - snapMode: ListView.SnapToItem - orientation: ListView.Horizontal - layoutDirection: Qt.RightToLeft - highlightRangeMode: ListView.StrictlyEnforceRange - highlight: Rectangle { width: 80; height: 80; color: "yellow" } - model: 18 - delegate: myDelegate - } - - Text { - anchors.right: parent.right - anchors.bottom: parent.bottom - text: list.contentX + ", " + list.contentY - } -} diff --git a/tests/auto/declarative/qquicklistview/data/strictlyenforcerange.qml b/tests/auto/declarative/qquicklistview/data/strictlyenforcerange.qml deleted file mode 100644 index 7960ac4abb..0000000000 --- a/tests/auto/declarative/qquicklistview/data/strictlyenforcerange.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -ListView { - id: list - objectName: "list" - width: 320 - height: 480 - - function fillModel() { - list.model.append({"col": "red"}); - list.currentIndex = list.count-1 - list.model.append({"col": "blue"}); - list.currentIndex = list.count-1 - list.model.append({"col": "green"}); - list.currentIndex = list.count-1 - } - - model: ListModel { id: listModel } // empty model - delegate: Rectangle { id: wrapper; objectName: "wrapper"; color: col; width: 300; height: 400 } - orientation: "Horizontal" - snapMode: "SnapToItem" - cacheBuffer: 1000 - - preferredHighlightBegin: 10 - preferredHighlightEnd: 10 - - highlightRangeMode: "StrictlyEnforceRange" - focus: true -} diff --git a/tests/auto/declarative/qquicklistview/incrementalmodel.cpp b/tests/auto/declarative/qquicklistview/incrementalmodel.cpp deleted file mode 100644 index 53d30915f5..0000000000 --- a/tests/auto/declarative/qquicklistview/incrementalmodel.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "incrementalmodel.h" -#include -#include - -IncrementalModel::IncrementalModel(QObject *parent) - : QAbstractListModel(parent), count(0) -{ - for (int i = 0; i < 100; ++i) - list.append("Item " + QString::number(i)); -} - -int IncrementalModel::rowCount(const QModelIndex & /* parent */) const -{ - return count; -} - -QVariant IncrementalModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - if (index.row() >= list.size() || index.row() < 0) - return QVariant(); - - if (role == Qt::DisplayRole) - return list.at(index.row()); - return QVariant(); -} - -bool IncrementalModel::canFetchMore(const QModelIndex & /* index */) const -{ - if (count < list.size()) - return true; - else - return false; -} - -void IncrementalModel::fetchMore(const QModelIndex & /* index */) -{ - int remainder = list.size() - count; - int itemsToFetch = qMin(5, remainder); - - beginInsertRows(QModelIndex(), count, count+itemsToFetch-1); - - count += itemsToFetch; - - endInsertRows(); -} diff --git a/tests/auto/declarative/qquicklistview/incrementalmodel.h b/tests/auto/declarative/qquicklistview/incrementalmodel.h deleted file mode 100644 index a6cddb6b07..0000000000 --- a/tests/auto/declarative/qquicklistview/incrementalmodel.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef IncrementalModel_H -#define IncrementalModel_H - -#include -#include -#include - -class IncrementalModel : public QAbstractListModel -{ - Q_OBJECT - -public: - IncrementalModel(QObject *parent = 0); - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - -protected: - bool canFetchMore(const QModelIndex &parent) const; - void fetchMore(const QModelIndex &parent); - -private: - QStringList list; - int count; -}; - -#endif diff --git a/tests/auto/declarative/qquicklistview/qquicklistview.pro b/tests/auto/declarative/qquicklistview/qquicklistview.pro deleted file mode 100644 index 3ffd3a7dc6..0000000000 --- a/tests/auto/declarative/qquicklistview/qquicklistview.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquicklistview -macx:CONFIG -= app_bundle - -HEADERS += incrementalmodel.h -SOURCES += tst_qquicklistview.cpp incrementalmodel.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private declarative-private widgets widgets-private v8-private opengl-private testlib diff --git a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp b/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp deleted file mode 100644 index 3b41600eb6..0000000000 --- a/tests/auto/declarative/qquicklistview/tst_qquicklistview.cpp +++ /dev/null @@ -1,4379 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include "incrementalmodel.h" -#include - -Q_DECLARE_METATYPE(Qt::LayoutDirection) -Q_DECLARE_METATYPE(QQuickListView::Orientation) - -class tst_QQuickListView : public QObject -{ - Q_OBJECT -public: - tst_QQuickListView(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - // Test both QListModelInterface and QAbstractItemModel model types - void qListModelInterface_items(); - void qAbstractItemModel_items(); - - void qListModelInterface_changed(); - void qAbstractItemModel_changed(); - - void qListModelInterface_inserted(); - void qListModelInterface_inserted_more(); - void qListModelInterface_inserted_more_data(); - void qAbstractItemModel_inserted(); - void qAbstractItemModel_inserted_more(); - void qAbstractItemModel_inserted_more_data(); - - void qListModelInterface_removed(); - void qAbstractItemModel_removed(); - - void qListModelInterface_moved(); - void qListModelInterface_moved_data(); - void qAbstractItemModel_moved(); - void qAbstractItemModel_moved_data(); - - void multipleChanges(); - void multipleChanges_data(); - - void qListModelInterface_clear(); - void qAbstractItemModel_clear(); - - void insertBeforeVisible(); - void insertBeforeVisible_data(); - void swapWithFirstItem(); - void itemList(); - void currentIndex_delayedItemCreation(); - void currentIndex_delayedItemCreation_data(); - void currentIndex(); - void noCurrentIndex(); - void enforceRange(); - void enforceRange_withoutHighlight(); - void spacing(); - void sections(); - void sectionsPositioning(); - void sectionsDelegate(); - void cacheBuffer(); - void positionViewAtIndex(); - void resetModel(); - void propertyChanges(); - void componentChanges(); - void modelChanges(); - void manualHighlight(); - void header(); - void header_data(); - void header_delayItemCreation(); - void footer(); - void footer_data(); - void headerFooter(); - void resizeView(); - void resizeViewAndRepaint(); - void sizeLessThan1(); - void QTBUG_14821(); - void resizeDelegate(); - void resizeFirstDelegate(); - void QTBUG_16037(); - void indexAt(); - void incrementalModel(); - void onAdd(); - void onAdd_data(); - void onRemove(); - void onRemove_data(); - void rightToLeft(); - void test_mirroring(); - void margins(); - void creationContext(); - void snapToItem_data(); - void snapToItem(); - - void QTBUG_9791(); - void QTBUG_11105(); - void QTBUG_21742(); - - void asynchronous(); - -private: - template void items(); - template void changed(); - template void inserted(); - template void inserted_more(); - template void removed(bool animated); - template void moved(); - template void clear(); - QQuickView *createView(); - void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); - QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName); - template - T *findItem(QQuickItem *parent, const QString &id, int index=-1); - template - QList findItems(QQuickItem *parent, const QString &objectName); - void dumpTree(QQuickItem *parent, int depth = 0); - - void inserted_more_data(); - void moved_data(); -}; - -void tst_QQuickListView::initTestCase() -{ -} - -void tst_QQuickListView::cleanupTestCase() -{ - -} -class TestObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError) - Q_PROPERTY(bool animate READ animate NOTIFY changedAnim) - Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl) - Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer) - -public: - TestObject(QObject *parent = 0) - : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false) - , mCacheBuffer(0) {} - - bool error() const { return mError; } - void setError(bool err) { mError = err; emit changedError(); } - - bool animate() const { return mAnimate; } - void setAnimate(bool anim) { mAnimate = anim; emit changedAnim(); } - - bool invalidHighlight() const { return mInvalidHighlight; } - void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); } - - int cacheBuffer() const { return mCacheBuffer; } - void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); } - -signals: - void changedError(); - void changedAnim(); - void changedHl(); - void changedCacheBuffer(); - -public: - bool mError; - bool mAnimate; - bool mInvalidHighlight; - int mCacheBuffer; -}; - -template -void tst_qquicklistview_move(int from, int to, int n, T *items) -{ - if (from > to) { - // Only move forwards - flip if backwards moving - int tfrom = from; - int tto = to; - from = tto; - to = tto+n; - n = tfrom-tto; - } - if (n == 1) { - items->move(from, to); - } else { - T replaced; - int i=0; - typename T::ConstIterator it=items->begin(); it += from+n; - for (; ibegin(); it += from; - for (; ibegin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } -} - -class TestModel : public QListModelInterface -{ - Q_OBJECT -public: - TestModel(QObject *parent = 0) : QListModelInterface(parent) {} - ~TestModel() {} - - enum Roles { Name, Number }; - - QString name(int index) const { return list.at(index).first; } - QString number(int index) const { return list.at(index).second; } - - int count() const { return list.count(); } - - QList roles() const { return QList() << Name << Number; } - QString toString(int role) const { - switch (role) { - case Name: - return "name"; - case Number: - return "number"; - default: - return ""; - } - } - - QVariant data(int index, int role) const - { - if (role==0) - return list.at(index).first; - if (role==1) - return list.at(index).second; - return QVariant(); - } - QHash data(int index, const QList &roles) const { - QHash returnHash; - - for (int i = 0; i < roles.size(); ++i) { - int role = roles.at(i); - QVariant info; - switch (role) { - case Name: - info = list.at(index).first; - break; - case Number: - info = list.at(index).second; - break; - default: - break; - } - returnHash.insert(role, info); - } - return returnHash; - } - - void addItem(const QString &name, const QString &number) { - list.append(QPair(name, number)); - emit itemsInserted(list.count()-1, 1); - } - - void insertItem(int index, const QString &name, const QString &number) { - list.insert(index, QPair(name, number)); - emit itemsInserted(index, 1); - } - - void insertItems(int index, const QList > &items) { - for (int i=0; i(items[i].first, items[i].second)); - emit itemsInserted(index, items.count()); - } - - void removeItem(int index) { - list.removeAt(index); - emit itemsRemoved(index, 1); - } - - void removeItems(int index, int count) { - int c = count; - while (c--) - list.removeAt(index); - emit itemsRemoved(index, count); - } - - void moveItem(int from, int to) { - list.move(from, to); - emit itemsMoved(from, to, 1); - } - - void moveItems(int from, int to, int count) { - tst_qquicklistview_move(from, to, count, &list); - emit itemsMoved(from, to, count); - } - - void modifyItem(int index, const QString &name, const QString &number) { - list[index] = QPair(name, number); - emit itemsChanged(index, 1, roles()); - } - - void clear() { - int count = list.count(); - list.clear(); - emit itemsRemoved(0, count); - } - -private: - QList > list; -}; - - -class TestModel2 : public QAbstractListModel -{ -public: - enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; - - TestModel2(QObject *parent=0) : QAbstractListModel(parent) { - QHash roles; - roles[Name] = "name"; - roles[Number] = "number"; - setRoleNames(roles); - } - - int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } - QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { - QVariant rv; - if (role == Name) - rv = list.at(index.row()).first; - else if (role == Number) - rv = list.at(index.row()).second; - - return rv; - } - - int count() const { return rowCount(); } - QString name(int index) const { return list.at(index).first; } - QString number(int index) const { return list.at(index).second; } - - void addItem(const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), list.count(), list.count()); - list.append(QPair(name, number)); - emit endInsertRows(); - } - - void addItems(const QList > &items) { - emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); - for (int i=0; i(items[i].first, items[i].second)); - emit endInsertRows(); - } - - void insertItem(int index, const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), index, index); - list.insert(index, QPair(name, number)); - emit endInsertRows(); - } - - void insertItems(int index, const QList > &items) { - emit beginInsertRows(QModelIndex(), index, index+items.count()-1); - for (int i=0; i(items[i].first, items[i].second)); - emit endInsertRows(); - } - - void removeItem(int index) { - emit beginRemoveRows(QModelIndex(), index, index); - list.removeAt(index); - emit endRemoveRows(); - } - - void removeItems(int index, int count) { - emit beginRemoveRows(QModelIndex(), index, index+count-1); - while (count--) - list.removeAt(index); - emit endRemoveRows(); - } - - void moveItem(int from, int to) { - emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); - list.move(from, to); - emit endMoveRows(); - } - - void moveItems(int from, int to, int count) { - emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); - tst_qquicklistview_move(from, to, count, &list); - emit endMoveRows(); - } - - void modifyItem(int idx, const QString &name, const QString &number) { - list[idx] = QPair(name, number); - emit dataChanged(index(idx,0), index(idx,0)); - } - - void clear() { - int count = list.count(); - emit beginRemoveRows(QModelIndex(), 0, count-1); - list.clear(); - emit endRemoveRows(); - } - -private: - QList > list; -}; - -tst_QQuickListView::tst_QQuickListView() -{ -} - -template -void tst_QQuickListView::items() -{ - QQuickView *canvas = createView(); - - T model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); - - QTRY_VERIFY(listview->highlightItem() != 0); - QTRY_COMPARE(listview->count(), model.count()); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - // current item should be first item - QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); - - for (int i = 0; i < model.count(); ++i) { - QQuickText *name = findItem(contentItem, "textName", i); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(contentItem, "textNumber", i); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - // switch to other delegate - testObject->setAnimate(true); - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); - QTRY_VERIFY(listview->currentItem()); - - // set invalid highlight - testObject->setInvalidHighlight(true); - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); - QTRY_VERIFY(listview->currentItem()); - QTRY_VERIFY(listview->highlightItem() == 0); - - // back to normal highlight - testObject->setInvalidHighlight(false); - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QTRY_VERIFY(testObject->error() == false); - QTRY_VERIFY(listview->currentItem()); - QTRY_VERIFY(listview->highlightItem() != 0); - - // set an empty model and confirm that items are destroyed - T model2; - ctxt->setContextProperty("testModel", &model2); - - int itemCount = findItems(contentItem, "wrapper").count(); - QTRY_VERIFY(itemCount == 0); - - QTRY_COMPARE(listview->highlightResizeSpeed(), 1000.0); - QTRY_COMPARE(listview->highlightMoveSpeed(), 1000.0); - - delete canvas; - delete testObject; -} - - -template -void tst_QQuickListView::changed() -{ - QQuickView *canvas = createView(); - - T model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickFlickable *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.modifyItem(1, "Will", "9876"); - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - delete canvas; - delete testObject; -} - -template -void tst_QQuickListView::inserted() -{ - QQuickView *canvas = createView(); - canvas->show(); - - T model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.insertItem(1, "Will", "9876"); - - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - // Confirm items positioned correctly - for (int i = 0; i < model.count(); ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_COMPARE(item->y(), i*20.0); - } - - model.insertItem(0, "Foo", "1111"); // zero index, and current item - - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item - - name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - QTRY_COMPARE(listview->currentIndex(), 1); - - // Confirm items positioned correctly - for (int i = 0; i < model.count(); ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_COMPARE(item->y(), i*20.0); - } - - for (int i = model.count(); i < 30; ++i) - model.insertItem(i, "Hello", QString::number(i)); - - listview->setContentY(80); - - // Insert item outside visible area - model.insertItem(1, "Hello", "1324"); - - QTRY_VERIFY(listview->contentY() == 80); - - // Confirm items positioned correctly - for (int i = 5; i < 5+15; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.0 - 20.0); - } - -// QTRY_COMPARE(listview->contentItemHeight(), model.count() * 20.0); - - // QTBUG-19675 - model.clear(); - model.insertItem(0, "Hello", "1234"); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->y(), 0.); - QVERIFY(listview->contentY() == 0); - - delete canvas; - delete testObject; -} - -template -void tst_QQuickListView::inserted_more() -{ - QFETCH(qreal, contentY); - QFETCH(int, insertIndex); - QFETCH(int, insertCount); - QFETCH(qreal, itemsOffsetAfterMove); - - QQuickText *name; - QQuickText *number; - QQuickView *canvas = createView(); - canvas->show(); - - T model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - listview->setContentY(contentY); - - QList > newData; - for (int i=0; iproperty("count").toInt(), model.count()); - - // check visibleItems.first() is in correct position - QQuickItem *item0 = findItem(contentItem, "wrapper", 0); - QVERIFY(item0); - QCOMPARE(item0->y(), itemsOffsetAfterMove); - - QList items = findItems(contentItem, "wrapper"); - int firstVisibleIndex = -1; - for (int i=0; iy() >= contentY) { - QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - break; - } - } - QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::inserted_more_data() -{ - QTest::addColumn("contentY"); - QTest::addColumn("insertIndex"); - QTest::addColumn("insertCount"); - QTest::addColumn("itemsOffsetAfterMove"); - - QTest::newRow("add 1, before visible items") - << 80.0 // show 4-19 - << 3 << 1 - << -20.0; // insert above first visible i.e. 0 is at -20, first visible should not move - - QTest::newRow("add multiple, before visible") - << 80.0 // show 4-19 - << 3 << 3 - << -20.0 * 3; // again first visible should not move - - QTest::newRow("add 1, at start of visible, content at start") - << 0.0 - << 0 << 1 - << 0.0; - - QTest::newRow("add multiple, start of visible, content at start") - << 0.0 - << 0 << 3 - << 0.0; - - QTest::newRow("add 1, at start of visible, content not at start") - << 80.0 // show 4-19 - << 4 << 1 - << 0.0; - - QTest::newRow("add multiple, at start of visible, content not at start") - << 80.0 // show 4-19 - << 4 << 3 - << 0.0; - - - QTest::newRow("add 1, at end of visible, content at start") - << 0.0 - << 15 << 1 - << 0.0; - - QTest::newRow("add 1, at end of visible, content at start") - << 0.0 - << 15 << 3 - << 0.0; - - QTest::newRow("add 1, at end of visible, content not at start") - << 80.0 // show 4-19 - << 19 << 1 - << 0.0; - - QTest::newRow("add multiple, at end of visible, content not at start") - << 80.0 // show 4-19 - << 19 << 3 - << 0.0; - - - QTest::newRow("add 1, after visible, content at start") - << 0.0 - << 16 << 1 - << 0.0; - - QTest::newRow("add 1, after visible, content at start") - << 0.0 - << 16 << 3 - << 0.0; - - QTest::newRow("add 1, after visible, content not at start") - << 80.0 // show 4-19 - << 20 << 1 - << 0.0; - - QTest::newRow("add multiple, after visible, content not at start") - << 80.0 // show 4-19 - << 20 << 3 - << 0.0; -} - -void tst_QQuickListView::insertBeforeVisible() -{ - QFETCH(int, insertIndex); - QFETCH(int, insertCount); - QFETCH(int, cacheBuffer); - - QQuickText *name; - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - listview->setCacheBuffer(cacheBuffer); - - // trigger a refill (not just setting contentY) so that the visibleItems grid is updated - int firstVisibleIndex = 20; // move to an index where the top item is not visible - listview->setContentY(firstVisibleIndex * 20.0); - listview->setCurrentIndex(firstVisibleIndex); - qApp->processEvents(); - QTRY_COMPARE(listview->currentIndex(), firstVisibleIndex); - QQuickItem *item = findItem(contentItem, "wrapper", firstVisibleIndex); - QVERIFY(item); - QCOMPARE(item->y(), listview->contentY()); - - QList > newData; - for (int i=0; iproperty("count").toInt(), model.count()); - - // now, moving to the top of the view should position the inserted items correctly - int itemsOffsetAfterMove = -(insertCount * 20); - listview->setCurrentIndex(0); - QTRY_COMPARE(listview->currentIndex(), 0); - QTRY_COMPARE(listview->contentY(), 0.0 + itemsOffsetAfterMove); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::insertBeforeVisible_data() -{ - QTest::addColumn("insertIndex"); - QTest::addColumn("insertCount"); - QTest::addColumn("cacheBuffer"); - - QTest::newRow("insert 1 at 0, 0 buffer") << 0 << 1 << 0; - QTest::newRow("insert 1 at 0, 100 buffer") << 0 << 1 << 100; - QTest::newRow("insert 1 at 0, 500 buffer") << 0 << 1 << 500; - - QTest::newRow("insert 1 at 1, 0 buffer") << 1 << 1 << 0; - QTest::newRow("insert 1 at 1, 100 buffer") << 1 << 1 << 100; - QTest::newRow("insert 1 at 1, 500 buffer") << 1 << 1 << 500; - - QTest::newRow("insert multiple at 0, 0 buffer") << 0 << 3 << 0; - QTest::newRow("insert multiple at 0, 100 buffer") << 0 << 3 << 100; - QTest::newRow("insert multiple at 0, 500 buffer") << 0 << 3 << 500; - - QTest::newRow("insert multiple at 1, 0 buffer") << 1 << 3 << 0; - QTest::newRow("insert multiple at 1, 100 buffer") << 1 << 3 << 100; - QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 3 << 500; -} - -template -void tst_QQuickListView::removed(bool /* animated */) -{ - QQuickView *canvas = createView(); - - T model; - for (int i = 0; i < 50; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.removeItem(1); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - QQuickText *name = findItem(contentItem, "textName", 1); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(1)); - QQuickText *number = findItem(contentItem, "textNumber", 1); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(1)); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); - } - - // Remove first item (which is the current item); - model.removeItem(0); // post: top item starts at 20 - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(),i*20.0 + 20.0); - } - - // Remove items not visible - model.removeItem(18); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(),i*20.0+20.0); - } - - // Remove items before visible - listview->setContentY(80); - listview->setCurrentIndex(10); - - model.removeItem(1); // post: top item will be at 40 - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - // Confirm items positioned correctly - for (int i = 2; i < 18; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(),40+i*20.0); - } - - // Remove current index - QTRY_VERIFY(listview->currentIndex() == 9); - QQuickItem *oldCurrent = listview->currentItem(); - model.removeItem(9); - - QTRY_COMPARE(listview->currentIndex(), 9); - QTRY_VERIFY(listview->currentItem() != oldCurrent); - - listview->setContentY(40); // That's the top now - // let transitions settle. - QTest::qWait(300); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(),40+i*20.0); - } - - // remove current item beyond visible items. - listview->setCurrentIndex(20); - listview->setContentY(40); - model.removeItem(20); - - QTRY_COMPARE(listview->currentIndex(), 20); - QTRY_VERIFY(listview->currentItem() != 0); - - // remove item before current, but visible - listview->setCurrentIndex(8); - oldCurrent = listview->currentItem(); - model.removeItem(6); - - QTRY_COMPARE(listview->currentIndex(), 7); - QTRY_VERIFY(listview->currentItem() == oldCurrent); - - listview->setContentY(80); - QTest::qWait(300); - - // remove all visible items - model.removeItems(1, 18); - QTRY_COMPARE(listview->count() , model.count()); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i+1); - if (!item) qWarning() << "Item" << i+1 << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(),80+i*20.0); - } - - model.removeItems(1, 17); - QTRY_COMPARE(listview->count() , model.count()); - - model.removeItems(2, 1); - QTRY_COMPARE(listview->count() , model.count()); - - model.addItem("New", "1"); - QTRY_COMPARE(listview->count() , model.count()); - - QTRY_VERIFY(name = findItem(contentItem, "textName", model.count()-1)); - QCOMPARE(name->text(), QString("New")); - - // Add some more items so that we don't run out - model.clear(); - for (int i = 0; i < 50; i++) - model.addItem("Item" + QString::number(i), ""); - - // QTBUG-QTBUG-20575 - listview->setCurrentIndex(0); - listview->setContentY(30); - model.removeItem(0); - QTRY_VERIFY(name = findItem(contentItem, "textName", 0)); - - // QTBUG-19198 move to end and remove all visible items one at a time. - listview->positionViewAtEnd(); - for (int i = 0; i < 18; ++i) - model.removeItems(model.count() - 1, 1); - QTRY_VERIFY(findItems(contentItem, "wrapper").count() > 16); - - delete canvas; - delete testObject; -} - -template -void tst_QQuickListView::clear() -{ - QQuickView *canvas = createView(); - - T model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - model.clear(); - - QTRY_VERIFY(listview->count() == 0); - QTRY_VERIFY(listview->currentItem() == 0); - QTRY_VERIFY(listview->contentY() == 0); - QVERIFY(listview->currentIndex() == -1); - - // confirm sanity when adding an item to cleared list - model.addItem("New", "1"); - QTRY_VERIFY(listview->count() == 1); - QVERIFY(listview->currentItem() != 0); - QVERIFY(listview->currentIndex() == 0); - - delete canvas; - delete testObject; -} - -template -void tst_QQuickListView::moved() -{ - QFETCH(qreal, contentY); - QFETCH(int, from); - QFETCH(int, to); - QFETCH(int, count); - QFETCH(qreal, itemsOffsetAfterMove); - - QQuickText *name; - QQuickText *number; - QQuickView *canvas = createView(); - canvas->show(); - - T model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *currentItem = listview->currentItem(); - QTRY_VERIFY(currentItem != 0); - - listview->setContentY(contentY); - model.moveItems(from, to, count); - - // wait for items to move - QTest::qWait(100); - - QList items = findItems(contentItem, "wrapper"); - int firstVisibleIndex = -1; - for (int i=0; iy() >= contentY) { - QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); - firstVisibleIndex = e.evaluate().toInt(); - break; - } - } - QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); - - // Confirm items positioned correctly and indexes correct - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { - if (i >= firstVisibleIndex + 16) // index has moved out of view - continue; - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - - // current index should have been updated - if (item == currentItem) - QTRY_COMPARE(listview->currentIndex(), i); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::moved_data() -{ - QTest::addColumn("contentY"); - QTest::addColumn("from"); - QTest::addColumn("to"); - QTest::addColumn("count"); - QTest::addColumn("itemsOffsetAfterMove"); - - // model starts with 30 items, each 20px high, in area 320px high - // 16 items should be visible at a time - // itemsOffsetAfterMove should be > 0 whenever items above the visible pos have moved - - QTest::newRow("move 1 forwards, within visible items") - << 0.0 - << 1 << 4 << 1 - << 0.0; - - QTest::newRow("move 1 forwards, from non-visible -> visible") - << 80.0 // show 4-19 - << 1 << 18 << 1 - << 20.0; // removed 1 item above the first visible, so item 0 should drop down by 1 to minimize movement - - QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") - << 80.0 // show 4-19 - << 0 << 4 << 1 - << 20.0; // first item has moved to below item4, everything drops down by size of 1 item - - QTest::newRow("move 1 forwards, from visible -> non-visible") - << 0.0 - << 1 << 16 << 1 - << 0.0; - - QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)") - << 0.0 - << 0 << 16 << 1 - << 0.0; - - - QTest::newRow("move 1 backwards, within visible items") - << 0.0 - << 4 << 1 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, within visible items (to first index)") - << 0.0 - << 4 << 0 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from non-visible -> visible") - << 0.0 - << 20 << 4 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)") - << 0.0 - << 29 << 15 << 1 - << 0.0; - - QTest::newRow("move 1 backwards, from visible -> non-visible") - << 80.0 // show 4-19 - << 16 << 1 << 1 - << -20.0; // to minimize movement, item 0 moves to -20, and other items do not move - - QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)") - << 80.0 // show 4-19 - << 16 << 0 << 1 - << -20.0; // to minimize movement, item 16 (now at 0) moves to -20, and other items do not move - - - QTest::newRow("move multiple forwards, within visible items") - << 0.0 - << 0 << 5 << 3 - << 0.0; - - QTest::newRow("move multiple forwards, before visible items") - << 140.0 // show 7-22 - << 4 << 5 << 3 // 4,5,6 move to below 7 - << 20.0 * 3; // 4,5,6 moved down - - QTest::newRow("move multiple forwards, from non-visible -> visible") - << 80.0 // show 4-19 - << 1 << 5 << 3 - << 20.0 * 3; // moving 3 from above the content y should adjust y positions accordingly - - QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)") - << 80.0 // show 4-19 - << 0 << 5 << 3 - << 20.0 * 3; // moving 3 from above the content y should adjust y positions accordingly - - QTest::newRow("move multiple forwards, from visible -> non-visible") - << 0.0 - << 1 << 16 << 3 - << 0.0; - - QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)") - << 0.0 - << 0 << 16 << 3 - << 0.0; - - - QTest::newRow("move multiple backwards, within visible items") - << 0.0 - << 4 << 1 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, within visible items (move first item)") - << 0.0 - << 10 << 0 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from non-visible -> visible") - << 0.0 - << 20 << 4 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)") - << 0.0 - << 27 << 10 << 3 - << 0.0; - - QTest::newRow("move multiple backwards, from visible -> non-visible") - << 80.0 // show 4-19 - << 16 << 1 << 3 - << -20.0 * 3; // to minimize movement, 0 moves by -60, and other items do not move - - QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)") - << 80.0 // show 4-19 - << 16 << 0 << 3 - << -20.0 * 3; // to minimize movement, 16,17,18 move to above item 0, and other items do not move -} - - -struct ListChange { - enum { Inserted, Removed, Moved, SetCurrent } type; - int index; - int count; - int to; // Move - - static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; } - static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; } - static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; } - static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; } -}; -Q_DECLARE_METATYPE(QList) - -void tst_QQuickListView::multipleChanges() -{ - QFETCH(int, startCount); - QFETCH(QList, changes); - QFETCH(int, newCount); - QFETCH(int, newCurrentIndex); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < startCount; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - for (int i=0; i > items; - for (int j=changes[i].index; jsetCurrentIndex(changes[i].index); - break; - } - } - - QTRY_COMPARE(listview->count(), newCount); - QCOMPARE(listview->count(), model.count()); - QTRY_COMPARE(listview->currentIndex(), newCurrentIndex); - - QQuickText *name; - QQuickText *number; - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i=0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); - name = findItem(contentItem, "textName", i); - QVERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(i)); - number = findItem(contentItem, "textNumber", i); - QVERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(i)); - } - - delete testObject; - delete canvas; -} - -void tst_QQuickListView::multipleChanges_data() -{ - QTest::addColumn("startCount"); - QTest::addColumn >("changes"); - QTest::addColumn("newCount"); - QTest::addColumn("newCurrentIndex"); - - QList changes; - - for (int i=1; i<30; i++) - changes << ListChange::remove(0); - QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0; - - changes << ListChange::remove(0); - QTest::newRow("remove all") << 30 << changes << 0 << -1; - - changes.clear(); - changes << ListChange::setCurrent(29); - for (int i=29; i>0; i--) - changes << ListChange::remove(i); - QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0; - - QTest::newRow("remove then insert at 0") << 10 << (QList() - << ListChange::remove(0, 1) - << ListChange::insert(0, 1) - ) << 10 << 1; - - QTest::newRow("remove then insert at non-zero index") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::remove(2, 1) - << ListChange::insert(2, 1) - ) << 10 << 3; - - QTest::newRow("remove current then insert below it") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::remove(1, 3) - << ListChange::insert(2, 2) - ) << 9 << 1; - - QTest::newRow("remove current index then move it down") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::remove(1, 3) - << ListChange::move(1, 5, 1) - ) << 7 << 5; - - QTest::newRow("remove current index then move it up") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::remove(4, 3) - << ListChange::move(4, 1, 1) - ) << 7 << 1; - - - QTest::newRow("insert multiple times") << 0 << (QList() - << ListChange::insert(0, 2) - << ListChange::insert(0, 4) - << ListChange::insert(0, 6) - ) << 12 << 10; - - QTest::newRow("insert multiple times with current index changes") << 0 << (QList() - << ListChange::insert(0, 2) - << ListChange::insert(0, 4) - << ListChange::insert(0, 6) - << ListChange::setCurrent(3) - << ListChange::insert(3, 2) - ) << 14 << 5; - - QTest::newRow("insert and remove all") << 0 << (QList() - << ListChange::insert(0, 30) - << ListChange::remove(0, 30) - ) << 0 << -1; - - QTest::newRow("insert and remove current") << 30 << (QList() - << ListChange::insert(1) - << ListChange::setCurrent(1) - << ListChange::remove(1) - ) << 30 << 1; - - QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList() - << ListChange::insert(0, 10) - << ListChange::remove(5, 10) - ) << 10 << 5; - - QTest::newRow("insert multiple, then move new items to end") << 10 << (QList() - << ListChange::insert(0, 3) - << ListChange::move(0, 10, 3) - ) << 13 << 0; - - QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList() - << ListChange::insert(0, 3) - << ListChange::move(0, 8, 5) - ) << 13 << 11; - - QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList() - << ListChange::setCurrent(9) - << ListChange::insert(10, 3) - << ListChange::move(8, 0, 5) - ) << 13 << 1; - - - QTest::newRow("move back and forth to same index") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::move(1, 2, 2) - << ListChange::move(2, 1, 2) - ) << 10 << 1; - - QTest::newRow("move forwards then back") << 10 << (QList() - << ListChange::setCurrent(2) - << ListChange::move(1, 2, 3) - << ListChange::move(3, 0, 5) - ) << 10 << 0; - - QTest::newRow("move current, then remove it") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 0, 1) - << ListChange::remove(0) - ) << 9 << 0; - - QTest::newRow("move current, then insert before it") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 0, 1) - << ListChange::insert(0) - ) << 11 << 1; - - QTest::newRow("move multiple, then remove them") << 10 << (QList() - << ListChange::setCurrent(1) - << ListChange::move(5, 1, 3) - << ListChange::remove(1, 3) - ) << 7 << 1; - - QTest::newRow("move multiple, then insert before them") << 10 << (QList() - << ListChange::setCurrent(5) - << ListChange::move(5, 1, 3) - << ListChange::insert(1, 5) - ) << 15 << 6; - - QTest::newRow("move multiple, then insert after them") << 10 << (QList() - << ListChange::setCurrent(3) - << ListChange::move(0, 1, 2) - << ListChange::insert(3, 5) - ) << 15 << 8; - - - QTest::newRow("clear current") << 0 << (QList() - << ListChange::insert(0, 5) - << ListChange::setCurrent(-1) - << ListChange::remove(0, 5) - << ListChange::insert(0, 5) - ) << 5 << -1; -} - -void tst_QQuickListView::swapWithFirstItem() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - // ensure content position is stable - listview->setContentY(0); - model.moveItem(1, 0); - QTRY_VERIFY(listview->contentY() == 0); - - delete testObject; - delete canvas; -} - -void tst_QQuickListView::enforceRange() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0); - QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0); - QTRY_COMPARE(listview->highlightRangeMode(), QQuickListView::StrictlyEnforceRange); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // view should be positioned at the top of the range. - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QTRY_VERIFY(item); - QTRY_COMPARE(listview->contentY(), -100.0); - - QQuickText *name = findItem(contentItem, "textName", 0); - QTRY_VERIFY(name != 0); - QTRY_COMPARE(name->text(), model.name(0)); - QQuickText *number = findItem(contentItem, "textNumber", 0); - QTRY_VERIFY(number != 0); - QTRY_COMPARE(number->text(), model.number(0)); - - // Check currentIndex is updated when contentItem moves - listview->setContentY(20); - - QTRY_COMPARE(listview->currentIndex(), 6); - - // change model - TestModel model2; - for (int i = 0; i < 5; i++) - model2.addItem("Item" + QString::number(i), ""); - - ctxt->setContextProperty("testModel", &model2); - QCOMPARE(listview->count(), 5); - - delete canvas; -} - -void tst_QQuickListView::enforceRange_withoutHighlight() -{ - // QTBUG-20287 - // If no highlight is set but StrictlyEnforceRange is used, the content should still move - // to the correct position (i.e. to the next/previous item, not next/previous section) - // when moving up/down via incrementCurrentIndex() and decrementCurrentIndex() - - QQuickView *canvas = createView(); - canvas->show(); - QTest::qWait(200); - - TestModel model; - model.addItem("Item 0", "a"); - model.addItem("Item 1", "b"); - model.addItem("Item 2", "b"); - model.addItem("Item 3", "c"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange-nohighlight.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - qreal expectedPos = -100.0; - - expectedPos += 10.0; // scroll past 1st section's delegate (10px height) - QTRY_COMPARE(listview->contentY(), expectedPos); - - expectedPos += 20 + 10; // scroll past 1st section and section delegate of 2nd section - QTest::keyClick(canvas, Qt::Key_Down); - - QTRY_COMPARE(listview->contentY(), expectedPos); - - expectedPos += 20; // scroll past 1st item of 2nd section - QTest::keyClick(canvas, Qt::Key_Down); - QTRY_COMPARE(listview->contentY(), expectedPos); - - expectedPos += 20 + 10; // scroll past 2nd item of 2nd section and section delegate of 3rd section - QTest::keyClick(canvas, Qt::Key_Down); - QTRY_COMPARE(listview->contentY(), expectedPos); - - delete canvas; -} - -void tst_QQuickListView::spacing() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); - } - - listview->setSpacing(10); - QTRY_VERIFY(listview->spacing() == 10); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*30); - } - - listview->setSpacing(0); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.0); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::sections() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i/5)); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20 + ((i+4)/5) * 20)); - QQuickText *next = findItem(item, "nextSection"); - QCOMPARE(next->text().toInt(), (i+1)/5); - } - - QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged())); - - // Remove section boundary - model.removeItem(5); - QTRY_COMPARE(listview->count(), model.count()); - - // New section header created - QQuickItem *item = findItem(contentItem, "wrapper", 5); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 40.0); - - model.insertItem(3, "New Item", "0"); - QTRY_COMPARE(listview->count(), model.count()); - - // Section header moved - item = findItem(contentItem, "wrapper", 5); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 20.0); - - item = findItem(contentItem, "wrapper", 6); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 40.0); - - // insert item which will become a section header - model.insertItem(6, "Replace header", "1"); - QTRY_COMPARE(listview->count(), model.count()); - - item = findItem(contentItem, "wrapper", 6); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 40.0); - - item = findItem(contentItem, "wrapper", 7); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 20.0); - - QTRY_COMPARE(listview->currentSection(), QString("0")); - - listview->setContentY(140); - QTRY_COMPARE(listview->currentSection(), QString("1")); - - QTRY_COMPARE(currentSectionChangedSpy.count(), 1); - - listview->setContentY(20); - QTRY_COMPARE(listview->currentSection(), QString("0")); - - QTRY_COMPARE(currentSectionChangedSpy.count(), 2); - - item = findItem(contentItem, "wrapper", 1); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 20.0); - - // check that headers change when item changes - listview->setContentY(0); - model.modifyItem(0, "changed", "2"); - QTest::qWait(300); - - item = findItem(contentItem, "wrapper", 1); - QTRY_VERIFY(item); - QTRY_COMPARE(item->height(), 40.0); - - delete canvas; -} - -void tst_QQuickListView::sectionsDelegate() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i/5)); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20 + ((i+5)/5) * 20)); - QQuickText *next = findItem(item, "nextSection"); - QCOMPARE(next->text().toInt(), (i+1)/5); - } - - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, "sect_" + QString::number(i)); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*6)); - } - - model.modifyItem(0, "One", "aaa"); - model.modifyItem(1, "Two", "aaa"); - model.modifyItem(2, "Three", "aaa"); - model.modifyItem(3, "Four", "aaa"); - model.modifyItem(4, "Five", "aaa"); - QTest::qWait(300); - - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*6)); - } - - // remove section boundary - model.removeItem(5); - QTRY_COMPARE(listview->count(), model.count()); - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); - QVERIFY(item); - } - - // QTBUG-17606 - QList items = findItems(contentItem, "sect_1"); - QCOMPARE(items.count(), 1); - - // QTBUG-17759 - model.modifyItem(0, "One", "aaa"); - model.modifyItem(1, "One", "aaa"); - model.modifyItem(2, "One", "aaa"); - model.modifyItem(3, "Four", "aaa"); - model.modifyItem(4, "Four", "aaa"); - model.modifyItem(5, "Four", "aaa"); - model.modifyItem(6, "Five", "aaa"); - model.modifyItem(7, "Five", "aaa"); - model.modifyItem(8, "Five", "aaa"); - model.modifyItem(9, "Two", "aaa"); - model.modifyItem(10, "Two", "aaa"); - model.modifyItem(11, "Two", "aaa"); - QTRY_COMPARE(findItems(contentItem, "sect_aaa").count(), 1); - canvas->rootObject()->setProperty("sectionProperty", "name"); - // ensure view has settled. - QTRY_COMPARE(findItems(contentItem, "sect_Four").count(), 1); - for (int i = 0; i < 4; ++i) { - QQuickItem *item = findItem(contentItem, - "sect_" + model.name(i*3)); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*4)); - } - - // QTBUG-17769 - model.removeItems(10, 20); - // ensure view has settled. - QTRY_COMPARE(findItems(contentItem, "wrapper").count(), 10); - // Drag view up beyond bounds - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(20,20)); - { - QMouseEvent mv(QEvent::MouseMove, QPoint(20,0), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - } - { - QMouseEvent mv(QEvent::MouseMove, QPoint(20,-50), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - } - { - QMouseEvent mv(QEvent::MouseMove, QPoint(20,-200), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - } - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(20,-200)); - // view should settle back at 0 - QTRY_COMPARE(listview->contentY(), 0.0); - - delete canvas; -} - -void tst_QQuickListView::sectionsPositioning() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i/5)); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml"))); - qApp->processEvents(); - canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart | QQuickViewSection::NextLabelAtEnd))); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, "sect_" + QString::number(i)); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*6)); - } - - QQuickItem *topItem = findVisibleChild(contentItem, "sect_0"); // section header - QVERIFY(topItem); - QCOMPARE(topItem->y(), 0.); - - QQuickItem *bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer - QVERIFY(bottomItem); - QCOMPARE(bottomItem->y(), 300.); - - // move down a little and check that section header is at top - listview->setContentY(10); - QCOMPARE(topItem->y(), 0.); - - // push the top header up - listview->setContentY(110); - topItem = findVisibleChild(contentItem, "sect_0"); // section header - QVERIFY(topItem); - QCOMPARE(topItem->y(), 100.); - - QQuickItem *item = findVisibleChild(contentItem, "sect_1"); - QVERIFY(item); - QCOMPARE(item->y(), 120.); - - bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer - QVERIFY(bottomItem); - QCOMPARE(bottomItem->y(), 410.); - - // Move past section 0 - listview->setContentY(120); - topItem = findVisibleChild(contentItem, "sect_0"); // section header - QVERIFY(!topItem); - - // Push section footer down - listview->setContentY(70); - bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer - QVERIFY(bottomItem); - QCOMPARE(bottomItem->y(), 380.); - - // Change current section - listview->setContentY(10); - model.modifyItem(0, "One", "aaa"); - model.modifyItem(1, "Two", "aaa"); - model.modifyItem(2, "Three", "aaa"); - model.modifyItem(3, "Four", "aaa"); - model.modifyItem(4, "Five", "aaa"); - QTest::qWait(300); - - QTRY_COMPARE(listview->currentSection(), QString("aaa")); - - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*6)); - } - - topItem = findVisibleChild(contentItem, "sect_aaa"); // section header - QVERIFY(topItem); - QCOMPARE(topItem->y(), 10.); - - // remove section boundary - listview->setContentY(120); - model.removeItem(5); - QTRY_COMPARE(listview->count(), model.count()); - for (int i = 0; i < 3; ++i) { - QQuickItem *item = findItem(contentItem, - "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); - QVERIFY(item); - QTRY_COMPARE(item->y(), qreal(i*20*6)); - } - - QVERIFY(topItem = findVisibleChild(contentItem, "sect_1")); - QTRY_COMPARE(topItem->y(), 120.); - - // Change the next section - listview->setContentY(0); - bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer - QVERIFY(bottomItem); - QTRY_COMPARE(bottomItem->y(), 300.); - - model.modifyItem(14, "New", "new"); - - QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer - QTRY_COMPARE(bottomItem->y(), 300.); - - // Turn sticky footer off - listview->setContentY(40); - canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart))); - item = findVisibleChild(contentItem, "sect_new"); // inline label restored - QVERIFY(item); - QCOMPARE(item->y(), 360.); - - // Turn sticky header off - listview->setContentY(30); - canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels))); - item = findVisibleChild(contentItem, "sect_aaa"); // inline label restored - QVERIFY(item); - QCOMPARE(item->y(), 0.); - - delete canvas; -} - -void tst_QQuickListView::currentIndex_delayedItemCreation() -{ - QFETCH(bool, setCurrentToZero); - - QQuickView *canvas = createView(); - - TestModel model; - - // test currentIndexChanged() is emitted even if currentIndex = 0 on start up - // (since the currentItem will have changed and that shares the same index) - canvas->rootContext()->setContextProperty("setCurrentToZero", setCurrentToZero); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QSignalSpy spy(listview, SIGNAL(currentItemChanged())); - QCOMPARE(listview->currentIndex(), 0); - QTRY_COMPARE(spy.count(), 1); - - delete canvas; -} - -void tst_QQuickListView::currentIndex_delayedItemCreation_data() -{ - QTest::addColumn("setCurrentToZero"); - - QTest::newRow("set to 0") << true; - QTest::newRow("don't set to 0") << false; -} - -void tst_QQuickListView::currentIndex() -{ - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i)); - - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("testWrap", QVariant(false)); - - QString filename(TESTDATA("listview-initCurrent.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // current item should be 20th item at startup - // and current item should be in view - QCOMPARE(listview->currentIndex(), 20); - QCOMPARE(listview->contentY(), 100.0); - QCOMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 20)); - QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); - - // no wrap - listview->setCurrentIndex(0); - QCOMPARE(listview->currentIndex(), 0); - // confirm that the velocity is updated - QTRY_VERIFY(listview->verticalVelocity() != 0.0); - - listview->incrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 1); - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - // with wrap - ctxt->setContextProperty("testWrap", QVariant(true)); - QVERIFY(listview->isWrapEnabled()); - - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), model.count()-1); - - QTRY_COMPARE(listview->contentY(), 280.0); - - listview->incrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - QTRY_COMPARE(listview->contentY(), 0.0); - - - // footer should become visible if it is out of view, and then current index is set to count-1 - canvas->rootObject()->setProperty("showFooter", true); - QTRY_VERIFY(listview->footerItem()); - listview->setCurrentIndex(model.count()-2); - QTRY_VERIFY(listview->footerItem()->y() > listview->contentY() + listview->height()); - listview->setCurrentIndex(model.count()-1); - QTRY_COMPARE(listview->contentY() + listview->height(), (20.0 * model.count()) + listview->footerItem()->height()); - canvas->rootObject()->setProperty("showFooter", false); - - // header should become visible if it is out of view, and then current index is set to 0 - canvas->rootObject()->setProperty("showHeader", true); - QTRY_VERIFY(listview->headerItem()); - listview->setCurrentIndex(1); - QTRY_VERIFY(listview->headerItem()->y() + listview->headerItem()->height() < listview->contentY()); - listview->setCurrentIndex(0); - QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height()); - canvas->rootObject()->setProperty("showHeader", false); - - - // Test keys - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_VERIFY(qGuiApp->focusWindow() == canvas); - - listview->setCurrentIndex(0); - - QTest::keyClick(canvas, Qt::Key_Down); - QCOMPARE(listview->currentIndex(), 1); - - QTest::keyClick(canvas, Qt::Key_Up); - QCOMPARE(listview->currentIndex(), 0); - - // hold down Key_Down - for (int i=0; icurrentIndex(), i+1); - } - QTest::keyRelease(canvas, Qt::Key_Down); - QTRY_COMPARE(listview->currentIndex(), model.count()-1); - QTRY_COMPARE(listview->contentY(), 280.0); - - // hold down Key_Up - for (int i=model.count()-1; i > 0; i--) { - QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); - QTRY_COMPARE(listview->currentIndex(), i-1); - } - QTest::keyRelease(canvas, Qt::Key_Up); - QTRY_COMPARE(listview->currentIndex(), 0); - QTRY_COMPARE(listview->contentY(), 0.0); - - - // turn off auto highlight - listview->setHighlightFollowsCurrentItem(false); - QVERIFY(listview->highlightFollowsCurrentItem() == false); - - QVERIFY(listview->highlightItem()); - qreal hlPos = listview->highlightItem()->y(); - - listview->setCurrentIndex(4); - QTRY_COMPARE(listview->highlightItem()->y(), hlPos); - - // insert item before currentIndex - listview->setCurrentIndex(28); - model.insertItem(0, "Foo", "1111"); - QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); - - // check removing highlight by setting currentIndex to -1; - listview->setCurrentIndex(-1); - - QCOMPARE(listview->currentIndex(), -1); - QVERIFY(!listview->highlightItem()); - QVERIFY(!listview->currentItem()); - - delete canvas; -} - -void tst_QQuickListView::noCurrentIndex() -{ - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), QString::number(i)); - - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - QString filename(TESTDATA("listview-noCurrent.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // current index should be -1 at startup - // and we should not have a currentItem or highlightItem - QCOMPARE(listview->currentIndex(), -1); - QCOMPARE(listview->contentY(), 0.0); - QVERIFY(!listview->highlightItem()); - QVERIFY(!listview->currentItem()); - - listview->setCurrentIndex(2); - QCOMPARE(listview->currentIndex(), 2); - QVERIFY(listview->highlightItem()); - QVERIFY(listview->currentItem()); - - delete canvas; -} - -void tst_QQuickListView::itemList() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("itemlist.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "view"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickVisualItemModel *model = canvas->rootObject()->findChild("itemModel"); - QTRY_VERIFY(model != 0); - - QTRY_VERIFY(model->count() == 3); - QTRY_COMPARE(listview->currentIndex(), 0); - - QQuickItem *item = findItem(contentItem, "item1"); - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), 0.0); - QCOMPARE(item->height(), listview->height()); - - QQuickText *text = findItem(contentItem, "text1"); - QTRY_VERIFY(text); - QTRY_COMPARE(text->text(), QLatin1String("index: 0")); - - listview->setCurrentIndex(2); - - item = findItem(contentItem, "item3"); - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), 480.0); - - text = findItem(contentItem, "text3"); - QTRY_VERIFY(text); - QTRY_COMPARE(text->text(), QLatin1String("index: 2")); - - delete canvas; -} - -void tst_QQuickListView::cacheBuffer() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 90; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - QTRY_VERIFY(listview->delegate() != 0); - QTRY_VERIFY(listview->model() != 0); - QTRY_VERIFY(listview->highlight() != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); - } - - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - testObject->setCacheBuffer(200); - QTRY_VERIFY(listview->cacheBuffer() == 200); - - // items will be created one at a time - for (int i = itemCount; i < qMin(itemCount+10,model.count()); ++i) { - QVERIFY(findItem(listview, "wrapper", i) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(listview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - int newItemCount = 0; - newItemCount = findItems(contentItem, "wrapper").count(); - - // Confirm items positioned correctly - for (int i = 0; i < model.count() && i < newItemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); - } - - // move view and confirm items in view are visible immediately and outside are created async - listview->setContentY(300); - - for (int i = 15; i < 32; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QVERIFY(item); - QVERIFY(item->y() == i*20); - } - - QVERIFY(findItem(listview, "wrapper", 32) == 0); - - // ensure buffered items are created - for (int i = 32; i < qMin(41,model.count()); ++i) { - QQuickItem *item = 0; - while (!item) { - qGuiApp->processEvents(); // allow refill to happen - bool b = false; - controller.incubateWhile(&b); - item = findItem(listview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::positionViewAtIndex() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position on a currently visible item - listview->positionViewAtIndex(3, QQuickListView::Beginning); - QTRY_COMPARE(listview->contentY(), 60.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position on an item beyond the visible items - listview->positionViewAtIndex(22, QQuickListView::Beginning); - QTRY_COMPARE(listview->contentY(), 440.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position on an item that would leave empty space if positioned at the top - listview->positionViewAtIndex(28, QQuickListView::Beginning); - QTRY_COMPARE(listview->contentY(), 480.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position at the beginning again - listview->positionViewAtIndex(0, QQuickListView::Beginning); - QTRY_COMPARE(listview->contentY(), 0.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount-1; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position at End using last index - listview->positionViewAtIndex(model.count()-1, QQuickListView::End); - QTRY_COMPARE(listview->contentY(), 480.); - - // Confirm items positioned correctly - itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 24; i < model.count(); ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - // Position at End - listview->positionViewAtIndex(20, QQuickListView::End); - QTRY_COMPARE(listview->contentY(), 100.); - - // Position in Center - listview->positionViewAtIndex(15, QQuickListView::Center); - QTRY_COMPARE(listview->contentY(), 150.); - - // Ensure at least partially visible - listview->positionViewAtIndex(15, QQuickListView::Visible); - QTRY_COMPARE(listview->contentY(), 150.); - - listview->setContentY(302); - listview->positionViewAtIndex(15, QQuickListView::Visible); - QTRY_COMPARE(listview->contentY(), 302.); - - listview->setContentY(320); - listview->positionViewAtIndex(15, QQuickListView::Visible); - QTRY_COMPARE(listview->contentY(), 300.); - - listview->setContentY(85); - listview->positionViewAtIndex(20, QQuickListView::Visible); - QTRY_COMPARE(listview->contentY(), 85.); - - listview->setContentY(75); - listview->positionViewAtIndex(20, QQuickListView::Visible); - QTRY_COMPARE(listview->contentY(), 100.); - - // Ensure completely visible - listview->setContentY(120); - listview->positionViewAtIndex(20, QQuickListView::Contain); - QTRY_COMPARE(listview->contentY(), 120.); - - listview->setContentY(302); - listview->positionViewAtIndex(15, QQuickListView::Contain); - QTRY_COMPARE(listview->contentY(), 300.); - - listview->setContentY(85); - listview->positionViewAtIndex(20, QQuickListView::Contain); - QTRY_COMPARE(listview->contentY(), 100.); - - // positionAtBeginnging - listview->positionViewAtBeginning(); - QTRY_COMPARE(listview->contentY(), 0.); - - listview->setContentY(80); - canvas->rootObject()->setProperty("showHeader", true); - listview->positionViewAtBeginning(); - QTRY_COMPARE(listview->contentY(), -30.); - - // positionAtEnd - listview->positionViewAtEnd(); - QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320 - - listview->setContentY(80); - canvas->rootObject()->setProperty("showFooter", true); - listview->positionViewAtEnd(); - QTRY_COMPARE(listview->contentY(), 510.); - - // set current item to outside visible view, position at beginning - // and ensure highlight moves to current item - listview->setCurrentIndex(1); - listview->positionViewAtBeginning(); - QTRY_COMPARE(listview->contentY(), -30.); - QVERIFY(listview->highlightItem()); - QCOMPARE(listview->highlightItem()->y(), 20.); - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::resetModel() -{ - QQuickView *canvas = createView(); - - QStringList strings; - strings << "one" << "two" << "three"; - QStringListModel model(strings); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(listview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(contentItem, "displayText", i); - QTRY_VERIFY(display != 0); - QTRY_COMPARE(display->text(), strings.at(i)); - } - - strings.clear(); - strings << "four" << "five" << "six" << "seven"; - model.setStringList(strings); - - QTRY_COMPARE(listview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(contentItem, "displayText", i); - QTRY_VERIFY(display != 0); - QTRY_COMPARE(display->text(), strings.at(i)); - } - - delete canvas; -} - -void tst_QQuickListView::propertyChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickListView *listView = canvas->rootObject()->findChild("listView"); - QTRY_VERIFY(listView); - - QSignalSpy highlightFollowsCurrentItemSpy(listView, SIGNAL(highlightFollowsCurrentItemChanged())); - QSignalSpy preferredHighlightBeginSpy(listView, SIGNAL(preferredHighlightBeginChanged())); - QSignalSpy preferredHighlightEndSpy(listView, SIGNAL(preferredHighlightEndChanged())); - QSignalSpy highlightRangeModeSpy(listView, SIGNAL(highlightRangeModeChanged())); - QSignalSpy keyNavigationWrapsSpy(listView, SIGNAL(keyNavigationWrapsChanged())); - QSignalSpy cacheBufferSpy(listView, SIGNAL(cacheBufferChanged())); - QSignalSpy snapModeSpy(listView, SIGNAL(snapModeChanged())); - - QTRY_COMPARE(listView->highlightFollowsCurrentItem(), true); - QTRY_COMPARE(listView->preferredHighlightBegin(), 0.0); - QTRY_COMPARE(listView->preferredHighlightEnd(), 0.0); - QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::ApplyRange); - QTRY_COMPARE(listView->isWrapEnabled(), true); - QTRY_COMPARE(listView->cacheBuffer(), 10); - QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapToItem); - - listView->setHighlightFollowsCurrentItem(false); - listView->setPreferredHighlightBegin(1.0); - listView->setPreferredHighlightEnd(1.0); - listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); - listView->setWrapEnabled(false); - listView->setCacheBuffer(3); - listView->setSnapMode(QQuickListView::SnapOneItem); - - QTRY_COMPARE(listView->highlightFollowsCurrentItem(), false); - QTRY_COMPARE(listView->preferredHighlightBegin(), 1.0); - QTRY_COMPARE(listView->preferredHighlightEnd(), 1.0); - QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::StrictlyEnforceRange); - QTRY_COMPARE(listView->isWrapEnabled(), false); - QTRY_COMPARE(listView->cacheBuffer(), 3); - QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapOneItem); - - QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1); - QTRY_COMPARE(preferredHighlightBeginSpy.count(),1); - QTRY_COMPARE(preferredHighlightEndSpy.count(),1); - QTRY_COMPARE(highlightRangeModeSpy.count(),1); - QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); - QTRY_COMPARE(cacheBufferSpy.count(),1); - QTRY_COMPARE(snapModeSpy.count(),1); - - listView->setHighlightFollowsCurrentItem(false); - listView->setPreferredHighlightBegin(1.0); - listView->setPreferredHighlightEnd(1.0); - listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); - listView->setWrapEnabled(false); - listView->setCacheBuffer(3); - listView->setSnapMode(QQuickListView::SnapOneItem); - - QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1); - QTRY_COMPARE(preferredHighlightBeginSpy.count(),1); - QTRY_COMPARE(preferredHighlightEndSpy.count(),1); - QTRY_COMPARE(highlightRangeModeSpy.count(),1); - QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); - QTRY_COMPARE(cacheBufferSpy.count(),1); - QTRY_COMPARE(snapModeSpy.count(),1); - - delete canvas; -} - -void tst_QQuickListView::componentChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickListView *listView = canvas->rootObject()->findChild("listView"); - QTRY_VERIFY(listView); - - QDeclarativeComponent component(canvas->engine()); - component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); - - QDeclarativeComponent delegateComponent(canvas->engine()); - delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); - - QSignalSpy highlightSpy(listView, SIGNAL(highlightChanged())); - QSignalSpy delegateSpy(listView, SIGNAL(delegateChanged())); - QSignalSpy headerSpy(listView, SIGNAL(headerChanged())); - QSignalSpy footerSpy(listView, SIGNAL(footerChanged())); - - listView->setHighlight(&component); - listView->setHeader(&component); - listView->setFooter(&component); - listView->setDelegate(&delegateComponent); - - QTRY_COMPARE(listView->highlight(), &component); - QTRY_COMPARE(listView->header(), &component); - QTRY_COMPARE(listView->footer(), &component); - QTRY_COMPARE(listView->delegate(), &delegateComponent); - - QTRY_COMPARE(highlightSpy.count(),1); - QTRY_COMPARE(delegateSpy.count(),1); - QTRY_COMPARE(headerSpy.count(),1); - QTRY_COMPARE(footerSpy.count(),1); - - listView->setHighlight(&component); - listView->setHeader(&component); - listView->setFooter(&component); - listView->setDelegate(&delegateComponent); - - QTRY_COMPARE(highlightSpy.count(),1); - QTRY_COMPARE(delegateSpy.count(),1); - QTRY_COMPARE(headerSpy.count(),1); - QTRY_COMPARE(footerSpy.count(),1); - - delete canvas; -} - -void tst_QQuickListView::modelChanges() -{ - QQuickView *canvas = createView(); - QTRY_VERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); - - QQuickListView *listView = canvas->rootObject()->findChild("listView"); - QTRY_VERIFY(listView); - - QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); - QTRY_VERIFY(alternateModel); - QVariant modelVariant = QVariant::fromValue(alternateModel); - QSignalSpy modelSpy(listView, SIGNAL(modelChanged())); - - listView->setModel(modelVariant); - QTRY_COMPARE(listView->model(), modelVariant); - QTRY_COMPARE(modelSpy.count(),1); - - listView->setModel(modelVariant); - QTRY_COMPARE(modelSpy.count(),1); - - listView->setModel(QVariant()); - QTRY_COMPARE(modelSpy.count(),2); - - delete canvas; -} - -void tst_QQuickListView::QTBUG_9791() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("strictlyenforcerange.qml"))); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - QTRY_VERIFY(listview->delegate() != 0); - QTRY_VERIFY(listview->model() != 0); - - QMetaObject::invokeMethod(listview, "fillModel"); - qApp->processEvents(); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - QCOMPARE(itemCount, 3); - - for (int i = 0; i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), i*300.0); - } - - // check that view is positioned correctly - QTRY_COMPARE(listview->contentX(), 590.0); - - delete canvas; -} - -void tst_QQuickListView::manualHighlight() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - QString filename(TESTDATA("manual-highlight.qml")); - canvas->setSource(QUrl::fromLocalFile(filename)); - - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(listview->currentIndex(), 0); - QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); - QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); - - listview->setCurrentIndex(2); - - QTRY_COMPARE(listview->currentIndex(), 2); - QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); - - // QTBUG-15972 - listview->positionViewAtIndex(3, QQuickListView::Contain); - - QTRY_COMPARE(listview->currentIndex(), 2); - QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); - QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); - - delete canvas; -} - -void tst_QQuickListView::QTBUG_11105() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_VERIFY(item->y() == i*20); - } - - listview->positionViewAtIndex(20, QQuickListView::Beginning); - QCOMPARE(listview->contentY(), 280.); - - TestModel model2; - for (int i = 0; i < 5; i++) - model2.addItem("Item" + QString::number(i), ""); - - ctxt->setContextProperty("testModel", &model2); - - itemCount = findItems(contentItem, "wrapper").count(); - QCOMPARE(itemCount, 5); - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::header() -{ - QFETCH(QQuickListView::Orientation, orientation); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(QPointF, initialHeaderPos); - QFETCH(QPointF, firstDelegatePos); - QFETCH(QPointF, initialContentPos); - QFETCH(QPointF, changedHeaderPos); - QFETCH(QPointF, changedContentPos); - QFETCH(QPointF, resizeContentPos); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QQuickView *canvas = createView(); - canvas->rootContext()->setContextProperty("testModel", &model); - canvas->rootContext()->setContextProperty("initialViewWidth", 240); - canvas->rootContext()->setContextProperty("initialViewHeight", 320); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - listview->setOrientation(orientation); - listview->setLayoutDirection(layoutDirection); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *header = findItem(contentItem, "header"); - QVERIFY(header); - - QVERIFY(header == listview->headerItem()); - - QCOMPARE(header->width(), 100.); - QCOMPARE(header->height(), 30.); - QCOMPARE(header->pos(), initialHeaderPos); - QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); - - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - model.clear(); - QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is - - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QSignalSpy headerItemSpy(listview, SIGNAL(headerItemChanged())); - QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); - - QCOMPARE(headerItemSpy.count(), 1); - - header = findItem(contentItem, "header"); - QVERIFY(!header); - header = findItem(contentItem, "header2"); - QVERIFY(header); - - QVERIFY(header == listview->headerItem()); - - QCOMPARE(header->pos(), changedHeaderPos); - QCOMPARE(header->width(), 50.); - QCOMPARE(header->height(), 20.); - QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos); - QCOMPARE(item->pos(), firstDelegatePos); - - delete canvas; - - - // QTBUG-21207 header should become visible if view resizes from initial empty size - - canvas = createView(); - canvas->rootContext()->setContextProperty("testModel", &model); - canvas->rootContext()->setContextProperty("initialViewWidth", 0.0); - canvas->rootContext()->setContextProperty("initialViewHeight", 0.0); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); - - listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - listview->setOrientation(orientation); - listview->setLayoutDirection(layoutDirection); - - listview->setWidth(240); - listview->setHeight(320); - QTRY_COMPARE(listview->headerItem()->pos(), initialHeaderPos); - QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); - - - delete canvas; -} - -void tst_QQuickListView::header_data() -{ - QTest::addColumn("orientation"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("initialHeaderPos"); - QTest::addColumn("changedHeaderPos"); - QTest::addColumn("initialContentPos"); - QTest::addColumn("changedContentPos"); - QTest::addColumn("firstDelegatePos"); - QTest::addColumn("resizeContentPos"); - - // header1 = 100 x 30 - // header2 = 50 x 20 - // delegates = 240 x 20 - // view width = 240 - - // header above items, top left - QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, 0) - << QPointF(0, -10); - - // header above items, top right - QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, -30) - << QPointF(0, -20) - << QPointF(0, 0) - << QPointF(0, -10); - - // header to left of items - QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight - << QPointF(-100, 0) - << QPointF(-50, 0) - << QPointF(-100, 0) - << QPointF(-50, 0) - << QPointF(0, 0) - << QPointF(-40, 0); - - // header to right of items - QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(-240 + 100, 0) - << QPointF(-240 + 50, 0) - << QPointF(-240, 0) - << QPointF(-240 + 40, 0); -} - -void tst_QQuickListView::header_delayItemCreation() -{ - QQuickView *canvas = createView(); - - TestModel model; - - canvas->rootContext()->setContextProperty("setCurrentToZero", QVariant(false)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - QCOMPARE(listview->contentY(), -header->height()); - - model.clear(); - QTRY_COMPARE(header->y(), -header->height()); - - delete canvas; -} - -void tst_QQuickListView::footer() -{ - QFETCH(QQuickListView::Orientation, orientation); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(QPointF, initialFooterPos); - QFETCH(QPointF, firstDelegatePos); - QFETCH(QPointF, initialContentPos); - QFETCH(QPointF, changedFooterPos); - QFETCH(QPointF, changedContentPos); - QFETCH(QPointF, resizeContentPos); - - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 3; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - listview->setOrientation(orientation); - listview->setLayoutDirection(layoutDirection); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickText *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - - QVERIFY(footer == listview->footerItem()); - - QCOMPARE(footer->pos(), initialFooterPos); - QCOMPARE(footer->width(), 100.); - QCOMPARE(footer->height(), 30.); - QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); - - QQuickItem *item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - // remove one item - model.removeItem(1); - - if (orientation == QQuickListView::Vertical) { - QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20); // delegate height = 20 - } else { - QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ? - initialFooterPos.x() - 40 : initialFooterPos.x() + 40); // delegate width = 40 - } - - // remove all items - model.clear(); - - QPointF posWhenNoItems(0, 0); - if (orientation == QQuickListView::Horizontal && layoutDirection == Qt::RightToLeft) - posWhenNoItems.setX(-100); - QTRY_COMPARE(footer->pos(), posWhenNoItems); - - // if header is present, it's at a negative pos, so the footer should not move - canvas->rootObject()->setProperty("showHeader", true); - QTRY_COMPARE(footer->pos(), posWhenNoItems); - canvas->rootObject()->setProperty("showHeader", false); - - // add 30 items - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QSignalSpy footerItemSpy(listview, SIGNAL(footerItemChanged())); - QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); - - QCOMPARE(footerItemSpy.count(), 1); - - footer = findItem(contentItem, "footer"); - QVERIFY(!footer); - footer = findItem(contentItem, "footer2"); - QVERIFY(footer); - - QVERIFY(footer == listview->footerItem()); - - QCOMPARE(footer->pos(), changedFooterPos); - QCOMPARE(footer->width(), 50.); - QCOMPARE(footer->height(), 20.); - QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos); - - item = findItem(contentItem, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->pos(), firstDelegatePos); - - listview->positionViewAtEnd(); - footer->setHeight(10); - footer->setWidth(40); - QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos); - - delete canvas; -} - -void tst_QQuickListView::footer_data() -{ - QTest::addColumn("orientation"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("initialFooterPos"); - QTest::addColumn("changedFooterPos"); - QTest::addColumn("initialContentPos"); - QTest::addColumn("changedContentPos"); - QTest::addColumn("firstDelegatePos"); - QTest::addColumn("resizeContentPos"); - - // footer1 = 100 x 30 - // footer2 = 50 x 20 - // delegates = 40 x 20 - // view width = 240 - // view height = 320 - - // footer below items, bottom left - QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight - << QPointF(0, 3 * 20) - << QPointF(0, 30 * 20) // added 30 items - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 30 * 20 - 320 + 10); - - // footer below items, bottom right - QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft - << QPointF(0, 3 * 20) - << QPointF(0, 30 * 20) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 30 * 20 - 320 + 10); - - // footer to right of items - QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight - << QPointF(40 * 3, 0) - << QPointF(40 * 30, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(0, 0) - << QPointF(40 * 30 - 240 + 40, 0); - - // footer to left of items - QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft - << QPointF(-(40 * 3) - 100, 0) - << QPointF(-(40 * 30) - 50, 0) // 50 = new footer width - << QPointF(-240, 0) - << QPointF(-240, 0) - << QPointF(-40, 0) - << QPointF(-(40 * 30) - 40, 0); -} - -class LVAccessor : public QQuickListView -{ -public: - qreal minY() const { return minYExtent(); } - qreal maxY() const { return maxYExtent(); } - qreal minX() const { return minXExtent(); } - qreal maxX() const { return maxXExtent(); } -}; - -void tst_QQuickListView::headerFooter() -{ - { - // Vertical - QQuickView *canvas = createView(); - - TestModel model; - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->y(), -header->height()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->y(), 0.); - - QCOMPARE(static_cast(listview)->minY(), header->height()); - QCOMPARE(static_cast(listview)->maxY(), header->height()); - - delete canvas; - } - { - // Horizontal - QQuickView *canvas = createView(); - - TestModel model; - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); - canvas->rootObject()->setProperty("horizontal", true); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), -header->width()); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), 0.); - - QCOMPARE(static_cast(listview)->minX(), header->width()); - QCOMPARE(static_cast(listview)->maxX(), header->width()); - - delete canvas; - } - { - // Horizontal RTL - QQuickView *canvas = createView(); - - TestModel model; - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); - canvas->rootObject()->setProperty("horizontal", true); - canvas->rootObject()->setProperty("rtl", true); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickItem *header = findItem(contentItem, "header"); - QVERIFY(header); - QCOMPARE(header->x(), 0.); - - QQuickItem *footer = findItem(contentItem, "footer"); - QVERIFY(footer); - QCOMPARE(footer->x(), -footer->width()); - - QCOMPARE(static_cast(listview)->minX(), 240. - header->width()); - QCOMPARE(static_cast(listview)->maxX(), 240. - header->width()); - - delete canvas; - } -} - -void tst_QQuickListView::resizeView() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*20.); - } - - QVariant heightRatio; - QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); - QCOMPARE(heightRatio.toReal(), 0.4); - - listview->setHeight(200); - - QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); - QCOMPARE(heightRatio.toReal(), 0.25); - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::resizeViewAndRepaint() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - for (int i = 0; i < 40; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("initialHeight", 100); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // item at index 10 should not be currently visible - QVERIFY(!findItem(contentItem, "wrapper", 10)); - - listview->setHeight(320); - QTRY_VERIFY(findItem(contentItem, "wrapper", 10)); - - listview->setHeight(100); - QTRY_VERIFY(!findItem(contentItem, "wrapper", 10)); - - delete canvas; -} - -void tst_QQuickListView::sizeLessThan1() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("sizelessthan1.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // Confirm items positioned correctly - int itemCount = findItems(contentItem, "wrapper").count(); - for (int i = 0; i < model.count() && i < itemCount; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - if (!item) qWarning() << "Item" << i << "not found"; - QTRY_VERIFY(item); - QTRY_COMPARE(item->y(), i*0.5); - } - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::QTBUG_14821() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug14821.qml"))); - qApp->processEvents(); - - QQuickListView *listview = qobject_cast(canvas->rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - listview->decrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 99); - - listview->incrementCurrentIndex(); - QCOMPARE(listview->currentIndex(), 0); - - delete canvas; -} - -void tst_QQuickListView::resizeDelegate() -{ - QQuickView *canvas = createView(); - canvas->show(); - - QStringList strings; - for (int i = 0; i < 30; ++i) - strings << QString::number(i); - QStringListModel model(strings); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QCOMPARE(listview->count(), model.rowCount()); - - listview->setCurrentIndex(25); - listview->setContentY(0); - QTest::qWait(300); - - for (int i = 0; i < 16; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QCOMPARE(item->y(), i*20.0); - } - - QCOMPARE(listview->currentItem()->y(), 500.0); - QTRY_COMPARE(listview->highlightItem()->y(), 500.0); - - canvas->rootObject()->setProperty("delegateHeight", 30); - QTest::qWait(300); - - for (int i = 0; i < 11; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QTRY_COMPARE(item->y(), i*30.0); - } - - QTRY_COMPARE(listview->currentItem()->y(), 750.0); - QTRY_COMPARE(listview->highlightItem()->y(), 750.0); - - listview->setCurrentIndex(1); - listview->positionViewAtIndex(25, QQuickListView::Beginning); - listview->positionViewAtIndex(5, QQuickListView::Beginning); - - for (int i = 5; i < 16; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QCOMPARE(item->y(), i*30.0); - } - - QTRY_COMPARE(listview->currentItem()->y(), 30.0); - QTRY_COMPARE(listview->highlightItem()->y(), 30.0); - - canvas->rootObject()->setProperty("delegateHeight", 20); - QTest::qWait(300); - - for (int i = 5; i < 11; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QTRY_COMPARE(item->y(), 150 + (i-5)*20.0); - } - - QTRY_COMPARE(listview->currentItem()->y(), 70.0); - QTRY_COMPARE(listview->highlightItem()->y(), 70.0); - - delete canvas; -} - -void tst_QQuickListView::resizeFirstDelegate() -{ - // QTBUG-20712: Content Y jumps constantly if first delegate height == 0 - // and other delegates have height > 0 - - QSKIP("Test unstable - QTBUG-22872"); - - QQuickView *canvas = createView(); - canvas->show(); - - // bug only occurs when all items in the model are visible - TestModel model; - for (int i = 0; i < 10; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickItem *item = 0; - for (int i = 0; i < model.count(); ++i) { - item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QCOMPARE(item->y(), i*20.0); - } - - item = findItem(contentItem, "wrapper", 0); - item->setHeight(0); - - // check the content y has not jumped up and down - QCOMPARE(listview->contentY(), 0.0); - QSignalSpy spy(listview, SIGNAL(contentYChanged())); - QTest::qWait(100); - QCOMPARE(spy.count(), 0); - - for (int i = 1; i < model.count(); ++i) { - item = findItem(contentItem, "wrapper", i); - QVERIFY(item != 0); - QTRY_COMPARE(item->y(), (i-1)*20.0); - } - - - // QTBUG-22014: refill doesn't clear items scrolling off the top of the - // list if they follow a zero-sized delegate - - for (int i = 0; i < 10; i++) - model.addItem("Item" + QString::number(i), ""); - - item = findItem(contentItem, "wrapper", 1); - QVERIFY(item); - item->setHeight(0); - - listview->setCurrentIndex(19); - qApp->processEvents(); - - // items 0-2 should have been deleted - for (int i=0; i<3; i++) { - QTRY_VERIFY(!findItem(contentItem, "wrapper", i)); - } - - delete testObject; - delete canvas; -} - -void tst_QQuickListView::QTBUG_16037() -{ - QQuickView *canvas = createView(); - canvas->show(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug16037.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "listview"); - QTRY_VERIFY(listview != 0); - - QVERIFY(listview->contentHeight() <= 0.0); - - QMetaObject::invokeMethod(canvas->rootObject(), "setModel"); - - QTRY_COMPARE(listview->contentHeight(), 80.0); - - delete canvas; -} - -void tst_QQuickListView::indexAt() -{ - QQuickView *canvas = createView(); - - TestModel model; - for (int i = 0; i < 30; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QCOMPARE(listview->indexAt(0,0), 0); - QCOMPARE(listview->indexAt(0,19), 0); - QCOMPARE(listview->indexAt(239,19), 0); - QCOMPARE(listview->indexAt(0,20), 1); - QCOMPARE(listview->indexAt(240,20), -1); - - delete canvas; - delete testObject; -} - -void tst_QQuickListView::incrementalModel() -{ - QQuickView *canvas = createView(); - - IncrementalModel model; - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QTRY_COMPARE(listview->count(), 20); - - listview->positionViewAtIndex(10, QQuickListView::Beginning); - - QTRY_COMPARE(listview->count(), 25); - - delete canvas; -} - -void tst_QQuickListView::onAdd() -{ - QFETCH(int, initialItemCount); - QFETCH(int, itemsToAdd); - - const int delegateHeight = 10; - TestModel2 model; - - // these initial items should not trigger ListView.onAdd - for (int i=0; isetGeometry(0,0,200, delegateHeight * (initialItemCount + itemsToAdd)); - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("delegateHeight", delegateHeight); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); - - QObject *object = canvas->rootObject(); - object->setProperty("width", canvas->width()); - object->setProperty("height", canvas->height()); - qApp->processEvents(); - - QList > items; - for (int i=0; irootObject()->property("count").toInt(), model.count()); - - QVariantList result = object->property("addedDelegates").toList(); - QCOMPARE(result.count(), items.count()); - for (int i=0; i("initialItemCount"); - QTest::addColumn("itemsToAdd"); - - QTest::newRow("0, add 1") << 0 << 1; - QTest::newRow("0, add 2") << 0 << 2; - QTest::newRow("0, add 10") << 0 << 10; - - QTest::newRow("1, add 1") << 1 << 1; - QTest::newRow("1, add 2") << 1 << 2; - QTest::newRow("1, add 10") << 1 << 10; - - QTest::newRow("5, add 1") << 5 << 1; - QTest::newRow("5, add 2") << 5 << 2; - QTest::newRow("5, add 10") << 5 << 10; -} - -void tst_QQuickListView::onRemove() -{ - QFETCH(int, initialItemCount); - QFETCH(int, indexToRemove); - QFETCH(int, removeCount); - - const int delegateHeight = 10; - TestModel2 model; - for (int i=0; irootContext(); - ctxt->setContextProperty("testModel", &model); - ctxt->setContextProperty("delegateHeight", delegateHeight); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); - QObject *object = canvas->rootObject(); - - model.removeItems(indexToRemove, removeCount); - QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - - QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); - - delete canvas; -} - -void tst_QQuickListView::onRemove_data() -{ - QTest::addColumn("initialItemCount"); - QTest::addColumn("indexToRemove"); - QTest::addColumn("removeCount"); - - QTest::newRow("remove first") << 1 << 0 << 1; - QTest::newRow("two items, remove first") << 2 << 0 << 1; - QTest::newRow("two items, remove last") << 2 << 1 << 1; - QTest::newRow("two items, remove all") << 2 << 0 << 2; - - QTest::newRow("four items, remove first") << 4 << 0 << 1; - QTest::newRow("four items, remove 0-2") << 4 << 0 << 2; - QTest::newRow("four items, remove 1-3") << 4 << 1 << 2; - QTest::newRow("four items, remove 2-4") << 4 << 2 << 2; - QTest::newRow("four items, remove last") << 4 << 3 << 1; - QTest::newRow("four items, remove all") << 4 << 0 << 4; - - QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8; - QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5; - QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6; -} - -void tst_QQuickListView::rightToLeft() -{ - QQuickView *canvas = createView(); - canvas->setGeometry(0,0,640,320); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); - qApp->processEvents(); - - QVERIFY(canvas->rootObject() != 0); - QQuickListView *listview = findItem(canvas->rootObject(), "view"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QQuickVisualItemModel *model = canvas->rootObject()->findChild("itemModel"); - QTRY_VERIFY(model != 0); - - QTRY_VERIFY(model->count() == 3); - QTRY_COMPARE(listview->currentIndex(), 0); - - // initial position at first item, right edge aligned - QCOMPARE(listview->contentX(), -640.); - - QQuickItem *item = findItem(contentItem, "item1"); - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), -100.0); - QCOMPARE(item->height(), listview->height()); - - QQuickText *text = findItem(contentItem, "text1"); - QTRY_VERIFY(text); - QTRY_COMPARE(text->text(), QLatin1String("index: 0")); - - listview->setCurrentIndex(2); - - item = findItem(contentItem, "item3"); - QTRY_VERIFY(item); - QTRY_COMPARE(item->x(), -540.0); - - text = findItem(contentItem, "text3"); - QTRY_VERIFY(text); - QTRY_COMPARE(text->text(), QLatin1String("index: 2")); - - QCOMPARE(listview->contentX(), -640.); - - // Ensure resizing maintains position relative to right edge - qobject_cast(canvas->rootObject())->setWidth(600); - QTRY_COMPARE(listview->contentX(), -600.); - - delete canvas; -} - -void tst_QQuickListView::test_mirroring() -{ - QQuickView *canvasA = createView(); - canvasA->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); - QQuickListView *listviewA = findItem(canvasA->rootObject(), "view"); - QTRY_VERIFY(listviewA != 0); - - QQuickView *canvasB = createView(); - canvasB->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); - QQuickListView *listviewB = findItem(canvasB->rootObject(), "view"); - QTRY_VERIFY(listviewA != 0); - qApp->processEvents(); - - QList objectNames; - objectNames << "item1" << "item2"; // << "item3" - - listviewA->setProperty("layoutDirection", Qt::LeftToRight); - listviewB->setProperty("layoutDirection", Qt::RightToLeft); - QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection()); - - // LTR != RTL - foreach (const QString objectName, objectNames) - QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); - - listviewA->setProperty("layoutDirection", Qt::LeftToRight); - listviewB->setProperty("layoutDirection", Qt::LeftToRight); - - // LTR == LTR - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); - - QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection()); - QQuickItemPrivate::get(listviewB)->setLayoutMirror(true); - QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection()); - - // LTR != LTR+mirror - foreach (const QString objectName, objectNames) - QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); - - listviewA->setProperty("layoutDirection", Qt::RightToLeft); - - // RTL == LTR+mirror - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); - - listviewB->setProperty("layoutDirection", Qt::RightToLeft); - - // RTL != RTL+mirror - foreach (const QString objectName, objectNames) - QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); - - listviewA->setProperty("layoutDirection", Qt::LeftToRight); - - // LTR == RTL+mirror - foreach (const QString objectName, objectNames) - QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); - - delete canvasA; - delete canvasB; -} - -void tst_QQuickListView::margins() -{ - QQuickView *canvas = createView(); - - TestModel2 model; - for (int i = 0; i < 50; i++) - model.addItem("Item" + QString::number(i), ""); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - QCOMPARE(listview->contentY(), -30.); - QCOMPARE(listview->yOrigin(), 0.); - - // check end bound - listview->positionViewAtEnd(); - qreal pos = listview->contentY(); - listview->setContentY(pos + 80); - listview->returnToBounds(); - QTRY_COMPARE(listview->contentY(), pos + 50); - - // remove item before visible and check that top margin is maintained - // and yOrigin is updated - listview->setContentY(100); - model.removeItem(1); - QTest::qWait(100); - listview->setContentY(-50); - listview->returnToBounds(); - QCOMPARE(listview->yOrigin(), 20.); - QTRY_COMPARE(listview->contentY(), -10.); - - // reduce top margin - listview->setTopMargin(20); - QCOMPARE(listview->yOrigin(), 20.); - QTRY_COMPARE(listview->contentY(), 0.); - - // check end bound - listview->positionViewAtEnd(); - pos = listview->contentY(); - listview->setContentY(pos + 80); - listview->returnToBounds(); - QTRY_COMPARE(listview->contentY(), pos + 50); - - // reduce bottom margin - pos = listview->contentY(); - listview->setBottomMargin(40); - QCOMPARE(listview->yOrigin(), 20.); - QTRY_COMPARE(listview->contentY(), pos-10); - - delete canvas; -} - -void tst_QQuickListView::snapToItem_data() -{ - QTest::addColumn("orientation"); - QTest::addColumn("layoutDirection"); - QTest::addColumn("highlightRangeMode"); - QTest::addColumn("flickStart"); - QTest::addColumn("flickEnd"); - QTest::addColumn("snapAlignment"); - QTest::addColumn("endExtent"); - QTest::addColumn("startExtent"); - - QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) - << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; - - QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) - << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; - - QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) - << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0; - - QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; - - QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; - - QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) - << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0; -} - -void tst_QQuickListView::snapToItem() -{ - QFETCH(QQuickListView::Orientation, orientation); - QFETCH(Qt::LayoutDirection, layoutDirection); - QFETCH(int, highlightRangeMode); - QFETCH(QPoint, flickStart); - QFETCH(QPoint, flickEnd); - QFETCH(qreal, snapAlignment); - QFETCH(qreal, endExtent); - QFETCH(qreal, startExtent); - - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToItem.qml"))); - canvas->show(); - qApp->processEvents(); - - QQuickListView *listview = findItem(canvas->rootObject(), "list"); - QTRY_VERIFY(listview != 0); - - listview->setOrientation(orientation); - listview->setLayoutDirection(layoutDirection); - listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); - - QQuickItem *contentItem = listview->contentItem(); - QTRY_VERIFY(contentItem != 0); - - // confirm that a flick hits an item boundary - flick(canvas, flickStart, flickEnd, 180); - QTRY_VERIFY(listview->isMoving() == false); // wait until it stops - if (orientation == QQuickListView::Vertical) - QCOMPARE(qreal(fmod(listview->contentY(),80.0)), snapAlignment); - else - QCOMPARE(qreal(fmod(listview->contentX(),80.0)), snapAlignment); - - // flick to end - do { - flick(canvas, flickStart, flickEnd, 180); - QTRY_VERIFY(listview->isMoving() == false); // wait until it stops - } while (orientation == QQuickListView::Vertical - ? !listview->isAtYEnd() - : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning()); - - if (orientation == QQuickListView::Vertical) - QCOMPARE(listview->contentY(), endExtent); - else - QCOMPARE(listview->contentX(), endExtent); - - // flick to start - do { - flick(canvas, flickEnd, flickStart, 180); - QTRY_VERIFY(listview->isMoving() == false); // wait until it stops - } while (orientation == QQuickListView::Vertical - ? !listview->isAtYBeginning() - : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd()); - - if (orientation == QQuickListView::Vertical) - QCOMPARE(listview->contentY(), startExtent); - else - QCOMPARE(listview->contentX(), startExtent); - - delete canvas; -} - -void tst_QQuickListView::qListModelInterface_items() -{ - items(); -} - -void tst_QQuickListView::qAbstractItemModel_items() -{ - items(); -} - -void tst_QQuickListView::qListModelInterface_changed() -{ - changed(); -} - -void tst_QQuickListView::qAbstractItemModel_changed() -{ - changed(); -} - -void tst_QQuickListView::qListModelInterface_inserted() -{ - inserted(); -} - -void tst_QQuickListView::qListModelInterface_inserted_more() -{ - inserted_more(); -} - -void tst_QQuickListView::qListModelInterface_inserted_more_data() -{ - inserted_more_data(); -} - -void tst_QQuickListView::qAbstractItemModel_inserted() -{ - inserted(); -} - -void tst_QQuickListView::qAbstractItemModel_inserted_more() -{ - inserted_more(); -} - -void tst_QQuickListView::qAbstractItemModel_inserted_more_data() -{ - inserted_more_data(); -} - -void tst_QQuickListView::qListModelInterface_removed() -{ - removed(false); - removed(true); -} - -void tst_QQuickListView::qAbstractItemModel_removed() -{ - removed(false); - removed(true); -} - -void tst_QQuickListView::qListModelInterface_moved() -{ - moved(); -} - -void tst_QQuickListView::qListModelInterface_moved_data() -{ - moved_data(); -} - -void tst_QQuickListView::qAbstractItemModel_moved() -{ - moved(); -} - -void tst_QQuickListView::qAbstractItemModel_moved_data() -{ - moved_data(); -} - -void tst_QQuickListView::qListModelInterface_clear() -{ - clear(); -} - -void tst_QQuickListView::qAbstractItemModel_clear() -{ - clear(); -} - -void tst_QQuickListView::creationContext() -{ - QQuickView canvas; - canvas.setGeometry(0,0,240,320); - canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); - qApp->processEvents(); - - QQuickItem *rootItem = qobject_cast(canvas.rootObject()); - QVERIFY(rootItem); - QVERIFY(rootItem->property("count").toInt() > 0); - - QQuickItem *item; - QVERIFY(item = rootItem->findChild("listItem")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); - QVERIFY(item = rootItem->findChild("header")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); - QVERIFY(item = rootItem->findChild("footer")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); - QVERIFY(item = rootItem->findChild("section")); - QCOMPARE(item->property("text").toString(), QString("Hello!")); -} - -void tst_QQuickListView::QTBUG_21742() -{ - QQuickView canvas; - canvas.setGeometry(0,0,200,200); - canvas.setSource(QUrl::fromLocalFile(TESTDATA("qtbug-21742.qml"))); - qApp->processEvents(); - - QQuickItem *rootItem = qobject_cast(canvas.rootObject()); - QVERIFY(rootItem); - QCOMPARE(rootItem->property("count").toInt(), 1); -} - -QQuickView *tst_QQuickListView::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - return canvas; -} - -void tst_QQuickListView::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) -{ - const int pointCount = 5; - QPoint diff = to - from; - - // send press, five equally spaced moves, and release. - QTest::mousePress(canvas, Qt::LeftButton, 0, from); - - for (int i = 0; i < pointCount; ++i) { - QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - QTest::qWait(duration/pointCount); - QCoreApplication::processEvents(); - } - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); -} - -void tst_QQuickListView::asynchronous() -{ - QQuickView *canvas = createView(); - canvas->show(); - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - canvas->setSource(TESTDATA("asyncloader.qml")); - - QQuickItem *rootObject = qobject_cast(canvas->rootObject()); - QVERIFY(rootObject); - - QQuickListView *listview = 0; - while (!listview) { - bool b = false; - controller.incubateWhile(&b); - listview = rootObject->findChild("view"); - } - - // items will be created one at a time - for (int i = 0; i < 8; ++i) { - QVERIFY(findItem(listview, "wrapper", i) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(listview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - // verify positioning - QQuickItem *contentItem = listview->contentItem(); - for (int i = 0; i < 8; ++i) { - QQuickItem *item = findItem(contentItem, "wrapper", i); - QTRY_COMPARE(item->y(), i*50.0); - } - - delete canvas; -} - -QQuickItem *tst_QQuickListView::findVisibleChild(QQuickItem *parent, const QString &objectName) -{ - QQuickItem *item = 0; - QList items = parent->findChildren(objectName); - for (int i = 0; i < items.count(); ++i) { - if (items.at(i)->isVisible()) { - item = items.at(i); - break; - } - } - return item; -} -/* - Find an item with the specified objectName. If index is supplied then the - item must also evaluate the {index} expression equal to index -*/ -template -T *tst_QQuickListView::findItem(QQuickItem *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast(item); - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -template -QList tst_QQuickListView::findItems(QQuickItem *parent, const QString &objectName) -{ - QList items; - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item || !item->isVisible()) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) - items.append(static_cast(item)); - items += findItems(item, objectName); - } - - return items; -} - -void tst_QQuickListView::dumpTree(QQuickItem *parent, int depth) -{ - static QString padding(" "); - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - qDebug() << padding.left(depth*2) << item; - dumpTree(item, depth+1); - } -} - -QTEST_MAIN(tst_QQuickListView) - -#include "tst_qquicklistview.moc" - diff --git a/tests/auto/declarative/qquickloader/data/ActiveComponent.qml b/tests/auto/declarative/qquickloader/data/ActiveComponent.qml deleted file mode 100644 index 24c6f7ad91..0000000000 --- a/tests/auto/declarative/qquickloader/data/ActiveComponent.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Item { - id: behaviorCounter - property int behaviorCount: 0 - property int canary: 0 - - Behavior on canary { - NumberAnimation { target: behaviorCounter; property: "behaviorCount"; to: (behaviorCounter.behaviorCount + 1); duration: 0 } - } -} diff --git a/tests/auto/declarative/qquickloader/data/AnchoredLoader.qml b/tests/auto/declarative/qquickloader/data/AnchoredLoader.qml deleted file mode 100644 index 1a2a620d7f..0000000000 --- a/tests/auto/declarative/qquickloader/data/AnchoredLoader.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 300 - height: 200 - color: "blue" - Loader { - objectName: "loader" - anchors.fill: parent - sourceComponent: Component { - Rectangle { color: "red"; objectName: "sourceElement" } - } - } -} diff --git a/tests/auto/declarative/qquickloader/data/BigComponent.qml b/tests/auto/declarative/qquickloader/data/BigComponent.qml deleted file mode 100644 index df92532c43..0000000000 --- a/tests/auto/declarative/qquickloader/data/BigComponent.qml +++ /dev/null @@ -1,5015 +0,0 @@ -import QtQuick 2.0 - -Item { - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} - Item {} -} diff --git a/tests/auto/declarative/qquickloader/data/BlueRect.qml b/tests/auto/declarative/qquickloader/data/BlueRect.qml deleted file mode 100644 index e96ac00f21..0000000000 --- a/tests/auto/declarative/qquickloader/data/BlueRect.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - objectName: "blue" - width: 100 - height: 100 - color: "blue" -} diff --git a/tests/auto/declarative/qquickloader/data/CreationContextLoader.qml b/tests/auto/declarative/qquickloader/data/CreationContextLoader.qml deleted file mode 100644 index 4dd73e797c..0000000000 --- a/tests/auto/declarative/qquickloader/data/CreationContextLoader.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Loader { - id: myLoader - property int testProperty: 1912 - sourceComponent: loaderComponent - Component { - id: loaderComponent - Item { - Component.onCompleted: { - test = (myLoader.testProperty == 1912); - } - } - } -} diff --git a/tests/auto/declarative/qquickloader/data/GraphicsWidget250x250.qml b/tests/auto/declarative/qquickloader/data/GraphicsWidget250x250.qml deleted file mode 100644 index dae8e3fbbb..0000000000 --- a/tests/auto/declarative/qquickloader/data/GraphicsWidget250x250.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -QGraphicsWidget { - size: "250x250" -} diff --git a/tests/auto/declarative/qquickloader/data/GreenRect.qml b/tests/auto/declarative/qquickloader/data/GreenRect.qml deleted file mode 100644 index 99cefaf176..0000000000 --- a/tests/auto/declarative/qquickloader/data/GreenRect.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 100; height: 100 - color: "green" - Component.onCompleted: myLoader.source = "BlueRect.qml" -} diff --git a/tests/auto/declarative/qquickloader/data/InitialPropertyValuesComponent.qml b/tests/auto/declarative/qquickloader/data/InitialPropertyValuesComponent.qml deleted file mode 100644 index 24c6f7ad91..0000000000 --- a/tests/auto/declarative/qquickloader/data/InitialPropertyValuesComponent.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Item { - id: behaviorCounter - property int behaviorCount: 0 - property int canary: 0 - - Behavior on canary { - NumberAnimation { target: behaviorCounter; property: "behaviorCount"; to: (behaviorCounter.behaviorCount + 1); duration: 0 } - } -} diff --git a/tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml b/tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml deleted file mode 100644 index 7efa4a5f61..0000000000 --- a/tests/auto/declarative/qquickloader/data/InvalidSourceComponent.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Item { - RandomError -} diff --git a/tests/auto/declarative/qquickloader/data/NoResize.qml b/tests/auto/declarative/qquickloader/data/NoResize.qml deleted file mode 100644 index 9b3ea6410b..0000000000 --- a/tests/auto/declarative/qquickloader/data/NoResize.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 200; height: 80 - Loader { - source: "Rect120x60.qml" - } -} diff --git a/tests/auto/declarative/qquickloader/data/NoResizeGraphicsWidget.qml b/tests/auto/declarative/qquickloader/data/NoResizeGraphicsWidget.qml deleted file mode 100644 index c0f51d8c35..0000000000 --- a/tests/auto/declarative/qquickloader/data/NoResizeGraphicsWidget.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 200 - height: 80 - Loader { - source: "GraphicsWidget250x250.qml" - } -} diff --git a/tests/auto/declarative/qquickloader/data/QTBUG_16928.qml b/tests/auto/declarative/qquickloader/data/QTBUG_16928.qml deleted file mode 100644 index 903d7f0812..0000000000 --- a/tests/auto/declarative/qquickloader/data/QTBUG_16928.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "green" - width: loader.implicitWidth+50 - height: loader.implicitHeight+50 - - Loader { - id: loader - sourceComponent: Item { - anchors.centerIn: parent - - implicitWidth: 200 - implicitHeight: 200 - Rectangle { - color: "red" - anchors.fill: parent - } - } - anchors.fill: parent - anchors.margins: 15 - } -} diff --git a/tests/auto/declarative/qquickloader/data/QTBUG_17114.qml b/tests/auto/declarative/qquickloader/data/QTBUG_17114.qml deleted file mode 100644 index 7402037553..0000000000 --- a/tests/auto/declarative/qquickloader/data/QTBUG_17114.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property real loaderWidth: loader.width - property real loaderHeight: loader.height - width: 200 - height: 200 - - Loader { - id: loader - sourceComponent: Item { - property real iwidth: 32 - property real iheight: 32 - width: iwidth - height: iheight - } - } -} diff --git a/tests/auto/declarative/qquickloader/data/Rect120x60.qml b/tests/auto/declarative/qquickloader/data/Rect120x60.qml deleted file mode 100644 index fc9e447e69..0000000000 --- a/tests/auto/declarative/qquickloader/data/Rect120x60.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 120 - height:60 -} diff --git a/tests/auto/declarative/qquickloader/data/SetSourceComponent.qml b/tests/auto/declarative/qquickloader/data/SetSourceComponent.qml deleted file mode 100644 index 83cc358f7d..0000000000 --- a/tests/auto/declarative/qquickloader/data/SetSourceComponent.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Item { - function clear() { - loader.sourceComponent = undefined - } - Component { id: comp; Rectangle { width: 100; height: 50 } } - Loader { id: loader; sourceComponent: comp } -} diff --git a/tests/auto/declarative/qquickloader/data/SizeGraphicsWidgetToLoader.qml b/tests/auto/declarative/qquickloader/data/SizeGraphicsWidgetToLoader.qml deleted file mode 100644 index 2a63b4d34f..0000000000 --- a/tests/auto/declarative/qquickloader/data/SizeGraphicsWidgetToLoader.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Loader { - width: 200 - height: 80 - source: "GraphicsWidget250x250.qml" -} diff --git a/tests/auto/declarative/qquickloader/data/SizeLoaderToGraphicsWidget.qml b/tests/auto/declarative/qquickloader/data/SizeLoaderToGraphicsWidget.qml deleted file mode 100644 index a9875d8e21..0000000000 --- a/tests/auto/declarative/qquickloader/data/SizeLoaderToGraphicsWidget.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Loader { - source: "GraphicsWidget250x250.qml" -} diff --git a/tests/auto/declarative/qquickloader/data/SizeToItem.qml b/tests/auto/declarative/qquickloader/data/SizeToItem.qml deleted file mode 100644 index 866365754f..0000000000 --- a/tests/auto/declarative/qquickloader/data/SizeToItem.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Loader { - source: "Rect120x60.qml" -} diff --git a/tests/auto/declarative/qquickloader/data/SizeToLoader.qml b/tests/auto/declarative/qquickloader/data/SizeToLoader.qml deleted file mode 100644 index dad18c6939..0000000000 --- a/tests/auto/declarative/qquickloader/data/SizeToLoader.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Loader { - width: 200; height: 80 - source: "Rect120x60.qml" -} diff --git a/tests/auto/declarative/qquickloader/data/VmeError.qml b/tests/auto/declarative/qquickloader/data/VmeError.qml deleted file mode 100644 index 0443aa9054..0000000000 --- a/tests/auto/declarative/qquickloader/data/VmeError.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 100; height: 100; color: "red" - signal somethingHappened - onSomethingHappened: QtObject {} -} diff --git a/tests/auto/declarative/qquickloader/data/active.1.qml b/tests/auto/declarative/qquickloader/data/active.1.qml deleted file mode 100644 index 2dbd1a0887..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.1.qml +++ /dev/null @@ -1,31 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - active: false - } - - Component { - id: inlineTestComponent - Item { - id: inlineTestItem - property int someProperty: 5 - } - } - - function doSetSource() { - loader.source = "ActiveComponent.qml"; - } - - function doSetSourceComponent() { - loader.sourceComponent = inlineTestComponent; - } - - function doSetActive() { - loader.active = true; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.2.qml b/tests/auto/declarative/qquickloader/data/active.2.qml deleted file mode 100644 index e561744c63..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.2.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - source: "ActiveComponent.qml"; - - property int statusChangedCount: 0 - onStatusChanged: statusChangedCount = statusChangedCount + 1 - } - - function doSetInactive() { - loader.active = false; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.3.qml b/tests/auto/declarative/qquickloader/data/active.3.qml deleted file mode 100644 index 0fbba959bb..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.3.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - source: "ActiveComponent.qml"; - - property int sourceChangedCount: 0 - onSourceChanged: sourceChangedCount = sourceChangedCount + 1 - } - - function doSetInactive() { - loader.active = false; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.4.qml b/tests/auto/declarative/qquickloader/data/active.4.qml deleted file mode 100644 index 63fd46e2da..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.4.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Component { - id: inlineTestComponent - Item { - id: inlineTestItem - property int someProperty: 5 - } - } - - Loader { - id: loader - objectName: "loader" - sourceComponent: inlineTestComponent - - property int sourceComponentChangedCount: 0 - onSourceComponentChanged: sourceComponentChangedCount = sourceComponentChangedCount + 1 - } - - function doSetInactive() { - loader.active = false; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.5.qml b/tests/auto/declarative/qquickloader/data/active.5.qml deleted file mode 100644 index 903f458a41..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.5.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - source: "ActiveComponent.qml"; - - property int itemChangedCount: 0 - onItemChanged: itemChangedCount = itemChangedCount + 1 - } - - function doSetInactive() { - loader.active = false; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.6.qml b/tests/auto/declarative/qquickloader/data/active.6.qml deleted file mode 100644 index f769a4e184..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.6.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - - property int activeChangedCount: 0 - onActiveChanged: activeChangedCount = activeChangedCount + 1 - } - - function doSetActive() { - loader.active = true; - } - - function doSetInactive() { - loader.active = false; - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.7.qml b/tests/auto/declarative/qquickloader/data/active.7.qml deleted file mode 100644 index a29e932f5e..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.7.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: root - color: "blue" - width: 100; height: 100 - property bool success: true - - Loader { - active: false - anchors.fill: parent - sourceComponent: Rectangle { color: "red" } - onLoaded: { root.success = false; } // shouldn't be triggered if active is false - } -} diff --git a/tests/auto/declarative/qquickloader/data/active.8.qml b/tests/auto/declarative/qquickloader/data/active.8.qml deleted file mode 100644 index 3a66d3e99a..0000000000 --- a/tests/auto/declarative/qquickloader/data/active.8.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: root - color: "blue" - width: 100; height: 100 - property bool success: false - - Loader { - anchors.fill: parent - sourceComponent: Rectangle { color: "red" } - onLoaded: { root.success = true; } // should be triggered since active is true by default - } -} diff --git a/tests/auto/declarative/qquickloader/data/asynchronous.qml b/tests/auto/declarative/qquickloader/data/asynchronous.qml deleted file mode 100644 index 29570525ad..0000000000 --- a/tests/auto/declarative/qquickloader/data/asynchronous.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400 - - property string comp - function loadComponent() { - loader.source = comp - } - - Loader { - id: loader - objectName: "loader" - asynchronous: true - } -} diff --git a/tests/auto/declarative/qquickloader/data/crash.qml b/tests/auto/declarative/qquickloader/data/crash.qml deleted file mode 100644 index e6ddc33a10..0000000000 --- a/tests/auto/declarative/qquickloader/data/crash.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - function setLoaderSource() { - myLoader.source = "GreenRect.qml" - } - - Loader { - id: myLoader - } -} diff --git a/tests/auto/declarative/qquickloader/data/creationContext.qml b/tests/auto/declarative/qquickloader/data/creationContext.qml deleted file mode 100644 index 17a596cc74..0000000000 --- a/tests/auto/declarative/qquickloader/data/creationContext.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -Item { - property bool test: false - - CreationContextLoader { - } -} diff --git a/tests/auto/declarative/qquickloader/data/differentorigin.qml b/tests/auto/declarative/qquickloader/data/differentorigin.qml deleted file mode 100644 index 56a3034fe0..0000000000 --- a/tests/auto/declarative/qquickloader/data/differentorigin.qml +++ /dev/null @@ -1,3 +0,0 @@ -import QtQuick 2.0 - -Loader { source: "http://evil.place/evil.qml" } diff --git a/tests/auto/declarative/qquickloader/data/implicitSize.qml b/tests/auto/declarative/qquickloader/data/implicitSize.qml deleted file mode 100644 index 5c8c8348ed..0000000000 --- a/tests/auto/declarative/qquickloader/data/implicitSize.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property real implWidth: 0 - property real implHeight: 0 - color: "green" - width: loader.implicitWidth+50 - height: loader.implicitHeight+50 - - Loader { - id: loader - sourceComponent: Item { - anchors.centerIn: parent - - implicitWidth: 100 - implicitHeight: 100 - Rectangle { - color: "red" - anchors.fill: parent - } - } - - anchors.fill: parent - anchors.margins: 50 - onImplicitWidthChanged: implWidth = implicitWidth - onImplicitHeightChanged: implHeight = loader.implicitHeight - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.1.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.1.qml deleted file mode 100644 index ae371797ce..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.1.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - - onLoaded: { - loader.item.canary = 1; // will trigger the behavior, setting behaviorCount -> 1 - } - } - - Component.onCompleted: { - loader.source = "InitialPropertyValuesComponent.qml"; - root.initialValue = loader.item.canary; // should be one, since onLoaded will have triggered by now - root.behaviorCount = loader.item.behaviorCount; // should be one, since onLoaded will have triggered by now - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.2.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.2.qml deleted file mode 100644 index 76c7bc2fd6..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.2.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - onLoaded: { - root.initialValue = loader.item.canary; // should be two - root.behaviorCount = loader.item.behaviorCount; // should be zero - } - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 2}); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.3.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.3.qml deleted file mode 100644 index 3b08e6ee42..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.3.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - active: false - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 3}); - root.initialValue = loader.item.canary; // error - item should not yet exist. - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.4.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.4.qml deleted file mode 100644 index e8310044e8..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.4.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - active: false - onLoaded: { - root.initialValue = loader.item.canary; // should be four - root.behaviorCount = loader.item.behaviorCount; // should be zero - } - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 4}); - loader.active = true - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.5.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.5.qml deleted file mode 100644 index 03ee599aba..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.5.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - onLoaded: { - root.initialValue = loader.item.canary; // should be zero, but no error - root.behaviorCount = loader.item.behaviorCount; // should be zero - } - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml"); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.6.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.6.qml deleted file mode 100644 index 66452b512b..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.6.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - property int behaviorCount: 0 - - Loader { - id: loader - objectName: "loader" - onLoaded: { - root.initialValue = loader.item.canary; // should be six - root.behaviorCount = loader.item.behaviorCount; // should be zero - } - } - - Item { - id: child - property int bindable: 6 - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": child.bindable}); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.7.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.7.qml deleted file mode 100644 index 02349f7ddf..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.7.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int loaderValue: 0 - property int createObjectValue: 0 - - Loader { - id: loader - objectName: "loader" - onLoaded: { - root.loaderValue = loader.item.canary; // should still be one - } - } - - Item { - id: child - property int bindable: 1; - } - - property InitialPropertyValuesComponent ipvc - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": child.bindable}); - var dynComp = Qt.createComponent("InitialPropertyValuesComponent.qml"); - ipvc = dynComp.createObject(root, {"canary": child.bindable}); - child.bindable = 7; // won't cause re-evaluation, since not used in a binding. - root.createObjectValue = ipvc.canary; // should still be one - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.8.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.8.qml deleted file mode 100644 index 79e9264d4a..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.8.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int initialValue: 0 - - Loader { - id: loader - objectName: "loader" - active: false - onLoaded: { - root.initialValue = loader.item.canary; // should be six - } - } - - Component.onCompleted: { - loader.setSource("http://127.0.0.1:14450/InitialPropertyValuesComponent.qml", {"canary": 6}); - loader.active = true; - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.binding.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.binding.qml deleted file mode 100644 index e0df50a74a..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.binding.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - property InitialPropertyValuesComponent testInstance - testInstance: loader.item - - property int bindable: 1 - property int canaryValue: testInstance.canary - property int behaviorCount: testInstance.behaviorCount - - Loader { - id: loader - objectName: "loader" - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", {"canary": (function() { return root.bindable })}); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.1.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.1.qml deleted file mode 100644 index f324dbddac..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.1.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", 3); // invalid initial properties object - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.2.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.2.qml deleted file mode 100644 index 89aba313c7..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.2.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - } - - Component.onCompleted: { - loader.setSource("NonexistentSourceComponent.qml", {"canary":3}); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.3.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.3.qml deleted file mode 100644 index c862007402..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.3.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - - Loader { - id: loader - objectName: "loader" - } - - Component.onCompleted: { - loader.setSource("InvalidSourceComponent.qml", {"canary":3}); - } -} diff --git a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.4.qml b/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.4.qml deleted file mode 100644 index 9a80b2156d..0000000000 --- a/tests/auto/declarative/qquickloader/data/initialPropertyValues.error.4.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int canary: loader.item.canary - - Loader { - id: loader - objectName: "loader" - } - - Component.onCompleted: { - loader.setSource("InitialPropertyValuesComponent.qml", 3); // invalid initial properties object - } -} diff --git a/tests/auto/declarative/qquickloader/data/nonItem.qml b/tests/auto/declarative/qquickloader/data/nonItem.qml deleted file mode 100644 index 8cfa0d8efb..0000000000 --- a/tests/auto/declarative/qquickloader/data/nonItem.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Loader { - sourceComponent: QtObject {} -} diff --git a/tests/auto/declarative/qquickloader/data/parented.qml b/tests/auto/declarative/qquickloader/data/parented.qml deleted file mode 100644 index 1c19d4d1a5..0000000000 --- a/tests/auto/declarative/qquickloader/data/parented.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - width: 300; height: 300 - - Component { - id: comp - Rectangle { - objectName: "comp" - parent: root - anchors.fill: parent - color: "blue" - } - } - - Loader { - width: 200; height: 200 - sourceComponent: comp - } -} diff --git a/tests/auto/declarative/qquickloader/data/qmldir b/tests/auto/declarative/qquickloader/data/qmldir deleted file mode 100644 index bf42b507c0..0000000000 --- a/tests/auto/declarative/qquickloader/data/qmldir +++ /dev/null @@ -1 +0,0 @@ -# For tst_QDeclarativeLoader::networkRequestUrl; no types needed though. diff --git a/tests/auto/declarative/qquickloader/data/sameorigin-load.qml b/tests/auto/declarative/qquickloader/data/sameorigin-load.qml deleted file mode 100644 index 3332500be6..0000000000 --- a/tests/auto/declarative/qquickloader/data/sameorigin-load.qml +++ /dev/null @@ -1,3 +0,0 @@ -import QtQuick 2.0 - -Item { } diff --git a/tests/auto/declarative/qquickloader/data/sameorigin.qml b/tests/auto/declarative/qquickloader/data/sameorigin.qml deleted file mode 100644 index 84846b6aba..0000000000 --- a/tests/auto/declarative/qquickloader/data/sameorigin.qml +++ /dev/null @@ -1,3 +0,0 @@ -import QtQuick 2.0 - -Loader { source: "sameorigin-load.qml" } diff --git a/tests/auto/declarative/qquickloader/data/vmeErrors.qml b/tests/auto/declarative/qquickloader/data/vmeErrors.qml deleted file mode 100644 index 8e6c89dc8e..0000000000 --- a/tests/auto/declarative/qquickloader/data/vmeErrors.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Loader { - source: "VmeError.qml" -} - diff --git a/tests/auto/declarative/qquickloader/qquickloader.pro b/tests/auto/declarative/qquickloader/qquickloader.pro deleted file mode 100644 index 9ccecce478..0000000000 --- a/tests/auto/declarative/qquickloader/qquickloader.pro +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickloader -macx:CONFIG -= app_bundle - -INCLUDEPATH += ../shared/ -HEADERS += ../shared/testhttpserver.h -SOURCES += tst_qquickloader.cpp \ - ../shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickloader/tst_qquickloader.cpp b/tests/auto/declarative/qquickloader/tst_qquickloader.cpp deleted file mode 100644 index 96d0d88a84..0000000000 --- a/tests/auto/declarative/qquickloader/tst_qquickloader.cpp +++ /dev/null @@ -1,969 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include - -#include - -#include -#include -#include -#include -#include "testhttpserver.h" -#include "../shared/util.h" - -#define SERVER_PORT 14450 - -inline QUrl TEST_FILE(const QString &filename) -{ - return QUrl::fromLocalFile(TESTDATA(filename)); -} - -class PeriodicIncubationController : public QObject, - public QDeclarativeIncubationController -{ -public: - PeriodicIncubationController() { - startTimer(16); - } - -protected: - virtual void timerEvent(QTimerEvent *) { - incubateFor(15); - } -}; - -class tst_QQuickLoader : public QObject - -{ - Q_OBJECT -public: - tst_QQuickLoader(); - -private slots: - void sourceOrComponent(); - void sourceOrComponent_data(); - void clear(); - void urlToComponent(); - void componentToUrl(); - void anchoredLoader(); - void sizeLoaderToItem(); - void sizeItemToLoader(); - void noResize(); - void networkRequestUrl(); - void failNetworkRequest(); -// void networkComponent(); - void active(); - void initialPropertyValues_data(); - void initialPropertyValues(); - void initialPropertyValuesBinding(); - void initialPropertyValuesError_data(); - void initialPropertyValuesError(); - - void deleteComponentCrash(); - void nonItem(); - void vmeErrors(); - void creationContext(); - void QTBUG_16928(); - void implicitSize(); - void QTBUG_17114(); - void asynchronous_data(); - void asynchronous(); - void asynchronous_clear(); - - void parented(); - -private: - QDeclarativeEngine engine; -}; - - -tst_QQuickLoader::tst_QQuickLoader() -{ -} - -void tst_QQuickLoader::sourceOrComponent() -{ - QFETCH(QString, sourceOrComponent); - QFETCH(QString, sourceDefinition); - QFETCH(QUrl, sourceUrl); - QFETCH(QString, errorString); - - bool error = !errorString.isEmpty(); - if (error) - QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData()); - - QDeclarativeComponent component(&engine); - component.setData(QByteArray( - "import QtQuick 2.0\n" - "Loader {\n" - " property int onItemChangedCount: 0\n" - " property int onSourceChangedCount: 0\n" - " property int onSourceComponentChangedCount: 0\n" - " property int onStatusChangedCount: 0\n" - " property int onProgressChangedCount: 0\n" - " property int onLoadedCount: 0\n") - + sourceDefinition.toUtf8() - + QByteArray( - " onItemChanged: onItemChangedCount += 1\n" - " onSourceChanged: onSourceChangedCount += 1\n" - " onSourceComponentChanged: onSourceComponentChangedCount += 1\n" - " onStatusChanged: onStatusChangedCount += 1\n" - " onProgressChanged: onProgressChangedCount += 1\n" - " onLoaded: onLoadedCount += 1\n" - "}") - , TEST_FILE("")); - - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - QCOMPARE(loader->item() == 0, error); - QCOMPARE(loader->source(), sourceUrl); - QCOMPARE(loader->progress(), 1.0); - - QCOMPARE(loader->status(), error ? QQuickLoader::Error : QQuickLoader::Ready); - QCOMPARE(static_cast(loader)->childItems().count(), error ? 0: 1); - - if (!error) { - bool sourceComponentIsChildOfLoader = false; - for (int ii = 0; ii < loader->children().size(); ++ii) { - QDeclarativeComponent *c = qobject_cast(loader->children().at(ii)); - if (c && c == loader->sourceComponent()) { - sourceComponentIsChildOfLoader = true; - } - } - QVERIFY(sourceComponentIsChildOfLoader); - } - - if (sourceOrComponent == "component") { - QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 1); - QCOMPARE(loader->property("onSourceChangedCount").toInt(), 0); - } else { - QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 0); - QCOMPARE(loader->property("onSourceChangedCount").toInt(), 1); - } - QCOMPARE(loader->property("onStatusChangedCount").toInt(), 1); - QCOMPARE(loader->property("onProgressChangedCount").toInt(), 1); - - QCOMPARE(loader->property("onItemChangedCount").toInt(), error ? 0 : 1); - QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1); - - delete loader; -} - -void tst_QQuickLoader::sourceOrComponent_data() -{ - QTest::addColumn("sourceOrComponent"); - QTest::addColumn("sourceDefinition"); - QTest::addColumn("sourceUrl"); - QTest::addColumn("errorString"); - - QTest::newRow("source") << "source" << "source: 'Rect120x60.qml'\n" << QUrl::fromLocalFile(TESTDATA("Rect120x60.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" << QUrl::fromLocalFile(TESTDATA("IDontExist.qml")) - << QString(QUrl::fromLocalFile(TESTDATA("IDontExist.qml")).toString() + ": File not found"); -} - -void tst_QQuickLoader::clear() -{ - { - QDeclarativeComponent component(&engine); - component.setData(QByteArray( - "import QtQuick 2.0\n" - " Loader { id: loader\n" - " source: 'Rect120x60.qml'\n" - " Timer { interval: 200; running: true; onTriggered: loader.source = '' }\n" - " }") - , TEST_FILE("")); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - - QTRY_VERIFY(loader->item() == 0); - QCOMPARE(loader->progress(), 0.0); - QCOMPARE(loader->status(), QQuickLoader::Null); - QCOMPARE(static_cast(loader)->childItems().count(), 0); - - delete loader; - } - { - QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); - QVERIFY(loader); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - - loader->setSourceComponent(0); - - QVERIFY(loader->item() == 0); - QCOMPARE(loader->progress(), 0.0); - QCOMPARE(loader->status(), QQuickLoader::Null); - QCOMPARE(static_cast(loader)->childItems().count(), 0); - - delete item; - } - { - QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); - QVERIFY(loader); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - - QMetaObject::invokeMethod(item, "clear"); - - QVERIFY(loader->item() == 0); - QCOMPARE(loader->progress(), 0.0); - QCOMPARE(loader->status(), QQuickLoader::Null); - QCOMPARE(static_cast(loader)->childItems().count(), 0); - - delete item; - } -} - -void tst_QQuickLoader::urlToComponent() -{ - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\n" - "Loader {\n" - " id: loader\n" - " Component { id: myComp; Rectangle { width: 10; height: 10 } }\n" - " source: \"Rect120x60.qml\"\n" - " Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp }\n" - "}" ) - , TEST_FILE("")); - QQuickLoader *loader = qobject_cast(component.create()); - QTest::qWait(200); - QTRY_VERIFY(loader != 0); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - QCOMPARE(loader->width(), 10.0); - QCOMPARE(loader->height(), 10.0); - - delete loader; -} - -void tst_QQuickLoader::componentToUrl() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); - QVERIFY(loader); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - - loader->setSource(TEST_FILE("/Rect120x60.qml")); - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - QCOMPARE(loader->width(), 120.0); - QCOMPARE(loader->height(), 60.0); - - delete item; -} - -void tst_QQuickLoader::anchoredLoader() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/AnchoredLoader.qml")); - QQuickItem *rootItem = qobject_cast(component.create()); - QVERIFY(rootItem != 0); - QQuickItem *loader = rootItem->findChild("loader"); - QQuickItem *sourceElement = rootItem->findChild("sourceElement"); - - QVERIFY(loader != 0); - QVERIFY(sourceElement != 0); - - QCOMPARE(rootItem->width(), 300.0); - QCOMPARE(rootItem->height(), 200.0); - - QCOMPARE(loader->width(), 300.0); - QCOMPARE(loader->height(), 200.0); - - QCOMPARE(sourceElement->width(), 300.0); - QCOMPARE(sourceElement->height(), 200.0); -} - -void tst_QQuickLoader::sizeLoaderToItem() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/SizeToItem.qml")); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - QCOMPARE(loader->width(), 120.0); - QCOMPARE(loader->height(), 60.0); - - // Check resize - QQuickItem *rect = qobject_cast(loader->item()); - QVERIFY(rect); - rect->setWidth(150); - rect->setHeight(45); - QCOMPARE(loader->width(), 150.0); - QCOMPARE(loader->height(), 45.0); - - // Check explicit width - loader->setWidth(200.0); - QCOMPARE(loader->width(), 200.0); - QCOMPARE(rect->width(), 200.0); - rect->setWidth(100.0); // when rect changes ... - QCOMPARE(rect->width(), 100.0); // ... it changes - QCOMPARE(loader->width(), 200.0); // ... but loader stays the same - - // Check explicit height - loader->setHeight(200.0); - QCOMPARE(loader->height(), 200.0); - QCOMPARE(rect->height(), 200.0); - rect->setHeight(100.0); // when rect changes ... - QCOMPARE(rect->height(), 100.0); // ... it changes - QCOMPARE(loader->height(), 200.0); // ... but loader stays the same - - // Switch mode - loader->setWidth(180); - loader->setHeight(30); - QCOMPARE(rect->width(), 180.0); - QCOMPARE(rect->height(), 30.0); - - delete loader; -} - -void tst_QQuickLoader::sizeItemToLoader() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/SizeToLoader.qml")); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - QCOMPARE(loader->width(), 200.0); - QCOMPARE(loader->height(), 80.0); - - QQuickItem *rect = qobject_cast(loader->item()); - QVERIFY(rect); - QCOMPARE(rect->width(), 200.0); - QCOMPARE(rect->height(), 80.0); - - // Check resize - loader->setWidth(180); - loader->setHeight(30); - QCOMPARE(rect->width(), 180.0); - QCOMPARE(rect->height(), 30.0); - - // Switch mode - loader->resetWidth(); // reset explicit size - loader->resetHeight(); - rect->setWidth(160); - rect->setHeight(45); - QCOMPARE(loader->width(), 160.0); - QCOMPARE(loader->height(), 45.0); - - delete loader; -} - -void tst_QQuickLoader::noResize() -{ - QDeclarativeComponent component(&engine, TEST_FILE("/NoResize.qml")); - QQuickItem* item = qobject_cast(component.create()); - QVERIFY(item != 0); - QCOMPARE(item->width(), 200.0); - QCOMPARE(item->height(), 80.0); - - delete item; -} - -void tst_QQuickLoader::networkRequestUrl() -{ - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: signalCount += 1 }"), QUrl::fromLocalFile(TESTDATA("../dummy.qml"))); - if (component.isError()) - qDebug() << component.errors(); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - - QTRY_VERIFY(loader->status() == QQuickLoader::Ready); - - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->property("signalCount").toInt(), 1); - QCOMPARE(static_cast(loader)->childItems().count(), 1); - - delete loader; -} - -/* XXX Component waits until all dependencies are loaded. Is this actually possible? -void tst_QQuickLoader::networkComponent() -{ - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory("slowdata", TestHTTPServer::Delay); - - QDeclarativeComponent component(&engine); - component.setData(QByteArray( - "import QtQuick 2.0\n" - "import \"http://127.0.0.1:14450/\" as NW\n" - "Item {\n" - " Component { id: comp; NW.SlowRect {} }\n" - " Loader { sourceComponent: comp } }") - , TEST_FILE("")); - - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QQuickLoader *loader = qobject_cast(item->QQuickItem::children().at(1)); - QVERIFY(loader); - QTRY_VERIFY(loader->status() == QQuickLoader::Ready); - - QVERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QQuickLoader::Ready); - QCOMPARE(static_cast(loader)->children().count(), 1); - - delete loader; -} -*/ - -void tst_QQuickLoader::failNetworkRequest() -{ - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found"); - - QDeclarativeComponent component(&engine); - component.setData(QByteArray("import QtQuick 2.0\nLoader { property int did_load: 123; source: \"http://127.0.0.1:14450/IDontExist.qml\"; onLoaded: did_load=456 }"), QUrl::fromLocalFile("http://127.0.0.1:14450/dummy.qml")); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader != 0); - - QTRY_VERIFY(loader->status() == QQuickLoader::Error); - - QVERIFY(loader->item() == 0); - QCOMPARE(loader->progress(), 0.0); - QCOMPARE(loader->property("did_load").toInt(), 123); - QCOMPARE(static_cast(loader)->childItems().count(), 0); - - delete loader; -} - -void tst_QQuickLoader::active() -{ - // check that the item isn't instantiated until active is set to true - { - QDeclarativeComponent component(&engine, TEST_FILE("active.1.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == false); // set manually to false - QVERIFY(loader->item() == 0); - QMetaObject::invokeMethod(object, "doSetSourceComponent"); - QVERIFY(loader->item() == 0); - QMetaObject::invokeMethod(object, "doSetSource"); - QVERIFY(loader->item() == 0); - QMetaObject::invokeMethod(object, "doSetActive"); - QVERIFY(loader->item() != 0); - - delete object; - } - - // check that the status is Null if active is set to false - { - QDeclarativeComponent component(&engine, TEST_FILE("active.2.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == true); // active is true by default - QCOMPARE(loader->status(), QQuickLoader::Ready); - int currStatusChangedCount = loader->property("statusChangedCount").toInt(); - QMetaObject::invokeMethod(object, "doSetInactive"); - QCOMPARE(loader->status(), QQuickLoader::Null); - QCOMPARE(loader->property("statusChangedCount").toInt(), (currStatusChangedCount+1)); - - delete object; - } - - // check that the source is not cleared if active is set to false - { - QDeclarativeComponent component(&engine, TEST_FILE("active.3.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == true); // active is true by default - QVERIFY(!loader->source().isEmpty()); - int currSourceChangedCount = loader->property("sourceChangedCount").toInt(); - QMetaObject::invokeMethod(object, "doSetInactive"); - QVERIFY(!loader->source().isEmpty()); - QCOMPARE(loader->property("sourceChangedCount").toInt(), currSourceChangedCount); - - delete object; - } - - // check that the sourceComponent is not cleared if active is set to false - { - QDeclarativeComponent component(&engine, TEST_FILE("active.4.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == true); // active is true by default - QVERIFY(loader->sourceComponent() != 0); - int currSourceComponentChangedCount = loader->property("sourceComponentChangedCount").toInt(); - QMetaObject::invokeMethod(object, "doSetInactive"); - QVERIFY(loader->sourceComponent() != 0); - QCOMPARE(loader->property("sourceComponentChangedCount").toInt(), currSourceComponentChangedCount); - - delete object; - } - - // check that the item is released if active is set to false - { - QDeclarativeComponent component(&engine, TEST_FILE("active.5.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == true); // active is true by default - QVERIFY(loader->item() != 0); - int currItemChangedCount = loader->property("itemChangedCount").toInt(); - QMetaObject::invokeMethod(object, "doSetInactive"); - QVERIFY(loader->item() == 0); - QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1)); - - delete object; - } - - // check that the activeChanged signal is emitted correctly - { - QDeclarativeComponent component(&engine, TEST_FILE("active.6.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - - QVERIFY(loader->active() == true); // active is true by default - loader->setActive(true); // no effect - QCOMPARE(loader->property("activeChangedCount").toInt(), 0); - loader->setActive(false); // change signal should be emitted - QCOMPARE(loader->property("activeChangedCount").toInt(), 1); - loader->setActive(false); // no effect - QCOMPARE(loader->property("activeChangedCount").toInt(), 1); - loader->setActive(true); // change signal should be emitted - QCOMPARE(loader->property("activeChangedCount").toInt(), 2); - loader->setActive(false); // change signal should be emitted - QCOMPARE(loader->property("activeChangedCount").toInt(), 3); - QMetaObject::invokeMethod(object, "doSetActive"); - QCOMPARE(loader->property("activeChangedCount").toInt(), 4); - QMetaObject::invokeMethod(object, "doSetActive"); - QCOMPARE(loader->property("activeChangedCount").toInt(), 4); - QMetaObject::invokeMethod(object, "doSetInactive"); - QCOMPARE(loader->property("activeChangedCount").toInt(), 5); - loader->setActive(true); // change signal should be emitted - QCOMPARE(loader->property("activeChangedCount").toInt(), 6); - - delete object; - } - - // check that the component isn't loaded until active is set to true - { - QDeclarativeComponent component(&engine, TEST_FILE("active.7.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QCOMPARE(object->property("success").toBool(), true); - delete object; - } - - // check that the component is loaded if active is not set (true by default) - { - QDeclarativeComponent component(&engine, TEST_FILE("active.8.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - QCOMPARE(object->property("success").toBool(), true); - delete object; - } -} - -void tst_QQuickLoader::initialPropertyValues_data() -{ - QTest::addColumn("qmlFile"); - QTest::addColumn("expectedWarnings"); - QTest::addColumn("propertyNames"); - QTest::addColumn("propertyValues"); - - QTest::newRow("source url with value set in onLoaded, initially active = true") << TEST_FILE("initialPropertyValues.1.qml") - << QStringList() - << (QStringList() << "initialValue" << "behaviorCount") - << (QVariantList() << 1 << 1); - - QTest::newRow("set source with initial property values specified, active = true") << TEST_FILE("initialPropertyValues.2.qml") - << QStringList() - << (QStringList() << "initialValue" << "behaviorCount") - << (QVariantList() << 2 << 0); - - QTest::newRow("set source with initial property values specified, active = false") << TEST_FILE("initialPropertyValues.3.qml") - << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("initialPropertyValues.3.qml").toLocalFile() + QLatin1String(":16: TypeError: Cannot read property 'canary' of null"))) - << (QStringList()) - << (QVariantList()); - - QTest::newRow("set source with initial property values specified, active = false, with active set true later") << TEST_FILE("initialPropertyValues.4.qml") - << QStringList() - << (QStringList() << "initialValue" << "behaviorCount") - << (QVariantList() << 4 << 0); - - QTest::newRow("set source without initial property values specified, active = true") << TEST_FILE("initialPropertyValues.5.qml") - << QStringList() - << (QStringList() << "initialValue" << "behaviorCount") - << (QVariantList() << 0 << 0); - - QTest::newRow("set source with initial property values specified with binding, active = true") << TEST_FILE("initialPropertyValues.6.qml") - << QStringList() - << (QStringList() << "initialValue" << "behaviorCount") - << (QVariantList() << 6 << 0); - - QTest::newRow("ensure initial property value semantics mimic createObject") << TEST_FILE("initialPropertyValues.7.qml") - << QStringList() - << (QStringList() << "loaderValue" << "createObjectValue") - << (QVariantList() << 1 << 1); - - QTest::newRow("ensure initial property values aren't disposed prior to component completion") << TEST_FILE("initialPropertyValues.8.qml") - << QStringList() - << (QStringList() << "initialValue") - << (QVariantList() << 6); -} - -void tst_QQuickLoader::initialPropertyValues() -{ - QFETCH(QUrl, qmlFile); - QFETCH(QStringList, expectedWarnings); - QFETCH(QStringList, propertyNames); - QFETCH(QVariantList, propertyValues); - - TestHTTPServer server(SERVER_PORT); - QVERIFY(server.isValid()); - server.serveDirectory(TESTDATA("")); - - foreach (const QString &warning, expectedWarnings) - QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData()); - - QDeclarativeComponent component(&engine, qmlFile); - QObject *object = component.create(); - QVERIFY(object != 0); - qApp->processEvents(); - QTest::qWait(50); - - for (int i = 0; i < propertyNames.size(); ++i) - QCOMPARE(object->property(propertyNames.at(i).toAscii().constData()), propertyValues.at(i)); - - delete object; -} - -void tst_QQuickLoader::initialPropertyValuesBinding() -{ - QDeclarativeComponent component(&engine, TEST_FILE("initialPropertyValues.binding.qml")); - QObject *object = component.create(); - QVERIFY(object != 0); - - QVERIFY(object->setProperty("bindable", QVariant(8))); - QCOMPARE(object->property("canaryValue").toInt(), 8); - - delete object; -} - -void tst_QQuickLoader::initialPropertyValuesError_data() -{ - QTest::addColumn("qmlFile"); - QTest::addColumn("expectedWarnings"); - - QTest::newRow("invalid initial property values object") << TEST_FILE("initialPropertyValues.error.1.qml") - << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object")); - - QTest::newRow("nonexistent source url") << TEST_FILE("initialPropertyValues.error.2.qml") - << (QStringList() << QString(TEST_FILE("NonexistentSourceComponent.qml").toString() + ": File not found")); - - QTest::newRow("invalid source url") << TEST_FILE("initialPropertyValues.error.3.qml") - << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); - - QTest::newRow("invalid initial property values object with invalid property access") << TEST_FILE("initialPropertyValues.error.4.qml") - << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":7:5: QML Loader: setSource: value is not an object") - << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":5: TypeError: Cannot read property 'canary' of null")); -} - -void tst_QQuickLoader::initialPropertyValuesError() -{ - QFETCH(QUrl, qmlFile); - QFETCH(QStringList, expectedWarnings); - - foreach (const QString &warning, expectedWarnings) - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData()); - - QDeclarativeComponent component(&engine, qmlFile); - QObject *object = component.create(); - QVERIFY(object != 0); - QQuickLoader *loader = object->findChild("loader"); - QVERIFY(loader != 0); - QVERIFY(loader->item() == 0); - delete object; -} - -// QTBUG-9241 -void tst_QQuickLoader::deleteComponentCrash() -{ - QDeclarativeComponent component(&engine, TEST_FILE("crash.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - item->metaObject()->invokeMethod(item, "setLoaderSource"); - - QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); - QVERIFY(loader); - QVERIFY(loader->item()); - QCOMPARE(loader->item()->objectName(), QLatin1String("blue")); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QQuickLoader::Ready); - qApp->processEvents(QEventLoop::DeferredDeletion); - QTRY_COMPARE(static_cast(loader)->childItems().count(), 1); - QVERIFY(loader->source() == QUrl::fromLocalFile(TESTDATA("BlueRect.qml"))); - - delete item; -} - -void tst_QQuickLoader::nonItem() -{ - QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml")); - QString err = QUrl::fromLocalFile(TESTDATA("nonItem.qml")).toString() + ":3:1: QML Loader: Loader does not support loading non-visual elements."; - - QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader); - QVERIFY(loader->item() == 0); - - delete loader; -} - -void tst_QQuickLoader::vmeErrors() -{ - QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml")); - QString err = QUrl::fromLocalFile(TESTDATA("VmeError.qml")).toString() + ":6: Cannot assign object type QObject with no default method"; - QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); - QQuickLoader *loader = qobject_cast(component.create()); - QVERIFY(loader); - QVERIFY(loader->item() == 0); - - delete loader; -} - -// QTBUG-13481 -void tst_QQuickLoader::creationContext() -{ - QDeclarativeComponent component(&engine, TEST_FILE("creationContext.qml")); - - QObject *o = component.create(); - QVERIFY(o != 0); - - QCOMPARE(o->property("test").toBool(), true); - - delete o; -} - -void tst_QQuickLoader::QTBUG_16928() -{ - QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_16928.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QCOMPARE(item->width(), 250.); - QCOMPARE(item->height(), 250.); - - delete item; -} - -void tst_QQuickLoader::implicitSize() -{ - QDeclarativeComponent component(&engine, TEST_FILE("implicitSize.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QCOMPARE(item->width(), 150.); - QCOMPARE(item->height(), 150.); - - QCOMPARE(item->property("implHeight").toReal(), 100.); - QCOMPARE(item->property("implWidth").toReal(), 100.); - - delete item; -} - -void tst_QQuickLoader::QTBUG_17114() -{ - QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_17114.qml")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - - QCOMPARE(item->property("loaderWidth").toReal(), 32.); - QCOMPARE(item->property("loaderHeight").toReal(), 32.); - - delete item; -} - -void tst_QQuickLoader::asynchronous_data() -{ - QTest::addColumn("qmlFile"); - QTest::addColumn("expectedWarnings"); - - QTest::newRow("Valid component") << TEST_FILE("BigComponent.qml") - << QStringList(); - - QTest::newRow("Non-existant component") << TEST_FILE("IDoNotExist.qml") - << (QStringList() << QString(TEST_FILE("IDoNotExist.qml").toString() + ": File not found")); - - QTest::newRow("Invalid component") << TEST_FILE("InvalidSourceComponent.qml") - << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); -} - -void tst_QQuickLoader::asynchronous() -{ - QFETCH(QUrl, qmlFile); - QFETCH(QStringList, expectedWarnings); - - if (!engine.incubationController()) - engine.setIncubationController(new PeriodicIncubationController); - QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml")); - QQuickItem *root = qobject_cast(component.create()); - QVERIFY(root); - - QQuickLoader *loader = root->findChild("loader"); - QVERIFY(loader); - - foreach (const QString &warning, expectedWarnings) - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData()); - - QVERIFY(!loader->item()); - root->setProperty("comp", qmlFile.toString()); - QMetaObject::invokeMethod(root, "loadComponent"); - QVERIFY(!loader->item()); - - if (expectedWarnings.isEmpty()) { - QCOMPARE(loader->status(), QQuickLoader::Loading); - QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); - - QTRY_VERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QQuickLoader::Ready); - } else { - QCOMPARE(loader->progress(), 1.0); - QTRY_COMPARE(loader->status(), QQuickLoader::Error); - } - - delete root; -} - -void tst_QQuickLoader::asynchronous_clear() -{ - if (!engine.incubationController()) - engine.setIncubationController(new PeriodicIncubationController); - QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml")); - QQuickItem *root = qobject_cast(component.create()); - QVERIFY(root); - - QQuickLoader *loader = root->findChild("loader"); - QVERIFY(loader); - - QVERIFY(!loader->item()); - root->setProperty("comp", "BigComponent.qml"); - QMetaObject::invokeMethod(root, "loadComponent"); - QVERIFY(!loader->item()); - - QCOMPARE(loader->status(), QQuickLoader::Loading); - QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); - - // clear before component created - root->setProperty("comp", ""); - QMetaObject::invokeMethod(root, "loadComponent"); - QVERIFY(!loader->item()); - QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0); - - QCOMPARE(loader->progress(), 0.0); - QCOMPARE(loader->status(), QQuickLoader::Null); - QCOMPARE(static_cast(loader)->childItems().count(), 0); - - // check loading component - root->setProperty("comp", "Rect120x60.qml"); - QMetaObject::invokeMethod(root, "loadComponent"); - QVERIFY(!loader->item()); - - QCOMPARE(loader->status(), QQuickLoader::Loading); - QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); - - QTRY_VERIFY(loader->item()); - QCOMPARE(loader->progress(), 1.0); - QCOMPARE(loader->status(), QQuickLoader::Ready); - QCOMPARE(static_cast(loader)->childItems().count(), 1); -} - -void tst_QQuickLoader::parented() -{ - QDeclarativeComponent component(&engine, TEST_FILE("parented.qml")); - QQuickItem *root = qobject_cast(component.create()); - QVERIFY(root); - - QQuickItem *item = root->findChild("comp"); - QVERIFY(item); - - QVERIFY(item->parentItem() == root); - - QCOMPARE(item->width(), 300.); - QCOMPARE(item->height(), 300.); - - delete root; -} - - -QTEST_MAIN(tst_QQuickLoader) - -#include "tst_qquickloader.moc" diff --git a/tests/auto/declarative/qquickmousearea/data/clickThrough.qml b/tests/auto/declarative/qquickmousearea/data/clickThrough.qml deleted file mode 100644 index 3c03161faa..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/clickThrough.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Item{ - width: 200 - height: 200 - property int doubleClicks: 0 - property int clicks: 0 - property int pressAndHolds: 0 - property int presses: 0 - MouseArea{ - z: 0 - anchors.fill: parent - propagateComposedEvents: true - onPressed: presses++ - onClicked: clicks++ - onPressAndHold: pressAndHolds++ - onDoubleClicked: doubleClicks++ - } - MouseArea{ - z: 1 - propagateComposedEvents: true - enabled: true - anchors.fill: parent - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml b/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml deleted file mode 100644 index 2624108225..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/clickThrough2.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.0 - -Item{ - width: 300 - height: 300 - property int doubleClicks: 0 - property int clicks: 0 - property int pressAndHolds: 0 - property int presses: 0 - property bool letThrough: false - property bool noPropagation: false - Rectangle{ - z: 0 - color: "lightsteelblue" - width: 150 - height: 150 - MouseArea{ - anchors.fill: parent - propagateComposedEvents: true - onPressed: presses++ - onClicked: clicks++ - onPressAndHold: pressAndHolds++ - onDoubleClicked: doubleClicks++ - } - } - MouseArea{ - z: 1 - enabled: true - anchors.fill: parent - propagateComposedEvents: !noPropagation - onClicked: mouse.accepted = !letThrough; - onDoubleClicked: mouse.accepted = !letThrough; - onPressAndHold: mouse.accepted = !letThrough; - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/clickandhold.qml b/tests/auto/declarative/qquickmousearea/data/clickandhold.qml deleted file mode 100644 index 5e4e48f6db..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/clickandhold.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property bool clicked: false - property bool held: false - - MouseArea { - width: 200; height: 200 - onClicked: { root.clicked = true } - onPressAndHold: { root.held = true } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/clicktwice.qml b/tests/auto/declarative/qquickmousearea/data/clicktwice.qml deleted file mode 100644 index 002d1b9047..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/clicktwice.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int clicked: 0 - property int pressed: 0 - property int released: 0 - - MouseArea { - width: 200; height: 200 - onPressed: { root.pressed++ } - onClicked: { root.clicked++ } - onReleased: { root.released++ } - } -} - diff --git a/tests/auto/declarative/qquickmousearea/data/doubleclick.qml b/tests/auto/declarative/qquickmousearea/data/doubleclick.qml deleted file mode 100644 index 1030d0c33e..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/doubleclick.qml +++ /dev/null @@ -1,16 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property int clicked: 0 - property int doubleClicked: 0 - property int released: 0 - - MouseArea { - width: 200; height: 200 - onClicked: { root.clicked++ } - onDoubleClicked: { root.doubleClicked++ } - onReleased: { root.released++ } - } -} - diff --git a/tests/auto/declarative/qquickmousearea/data/dragging.qml b/tests/auto/declarative/qquickmousearea/data/dragging.qml deleted file mode 100644 index d9b6ac4083..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/dragging.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: whiteRect - width: 200 - height: 200 - color: "white" - Rectangle { - id: blackRect - objectName: "blackrect" - color: "black" - y: 50 - x: 50 - width: 100 - height: 100 - opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 - Text { text: blackRect.opacity} - MouseArea { - objectName: "mouseregion" - anchors.fill: parent - drag.target: blackRect - drag.axis: Drag.XandYAxis - drag.minimumX: 0 - drag.maximumX: whiteRect.width-blackRect.width - drag.minimumY: 0 - drag.maximumY: whiteRect.height-blackRect.height - } - } - } diff --git a/tests/auto/declarative/qquickmousearea/data/dragproperties.qml b/tests/auto/declarative/qquickmousearea/data/dragproperties.qml deleted file mode 100644 index 421dfe26b7..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/dragproperties.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: whiteRect - width: 200 - height: 200 - color: "white" - Rectangle { - id: blackRect - objectName: "blackrect" - color: "black" - y: 50 - x: 50 - width: 100 - height: 100 - opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 - Text { text: blackRect.opacity} - MouseArea { - objectName: "mouseregion" - anchors.fill: parent - drag.target: blackRect - drag.axis: Drag.XandYAxis - drag.minimumX: 0 - drag.maximumX: whiteRect.width-blackRect.width - drag.minimumY: 0 - drag.maximumY: whiteRect.height-blackRect.height - } - } - } diff --git a/tests/auto/declarative/qquickmousearea/data/dragreset.qml b/tests/auto/declarative/qquickmousearea/data/dragreset.qml deleted file mode 100644 index d7949f9139..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/dragreset.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: whiteRect - width: 200 - height: 200 - color: "white" - Rectangle { - id: blackRect - objectName: "blackrect" - color: "black" - y: 50 - x: 50 - width: 100 - height: 100 - opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 - Text { text: blackRect.opacity} - MouseArea { - objectName: "mouseregion" - anchors.fill: parent - drag.target: haveTarget ? blackRect : undefined - drag.axis: Drag.XandYAxis - drag.minimumX: 0 - drag.maximumX: whiteRect.width-blackRect.width - drag.minimumY: 0 - drag.maximumY: whiteRect.height-blackRect.height - } - } - } diff --git a/tests/auto/declarative/qquickmousearea/data/hoverPosition.qml b/tests/auto/declarative/qquickmousearea/data/hoverPosition.qml deleted file mode 100644 index 834f91ff29..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/hoverPosition.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400; height: 400; - - property real mouseX: mousetracker.mouseX - property real mouseY: mousetracker.mouseY - - Rectangle { - width: 100; height: 100; - MouseArea { - id: mousetracker; - anchors.fill: parent; - hoverEnabled: true - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/hoverPropagation.qml b/tests/auto/declarative/qquickmousearea/data/hoverPropagation.qml deleted file mode 100644 index c47c794132..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/hoverPropagation.qml +++ /dev/null @@ -1,54 +0,0 @@ -import QtQuick 2.0 - -Item{ - width: 400 - height: 200 - property bool point1: ma2.containsMouse && !ma1.containsMouse - property bool point2: ma3.containsMouse && ma4.containsMouse - Rectangle{ - width: 200 - height: 200 - color: ma1.containsMouse ? "red" : "white" - MouseArea{ - id: ma1 - hoverEnabled: true - anchors.fill: parent - } - Rectangle{ - width: 100 - height: 100 - color: ma2.containsMouse ? "blue" : "white" - MouseArea{ - id: ma2 - hoverEnabled: true - anchors.fill: parent - } - } - } - - Item{ - x:200 - Rectangle{ - width: 200 - height: 200 - color: ma3.containsMouse ? "yellow" : "white" - Rectangle{ - width: 100 - height: 100 - color: ma4.containsMouse ? "green" : "white" - } - } - MouseArea{ - id: ma3 - hoverEnabled: true - width: 200 - height: 200 - MouseArea{ - id: ma4 - width: 100 - height: 100 - hoverEnabled: true - } - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/noclickandhold.qml b/tests/auto/declarative/qquickmousearea/data/noclickandhold.qml deleted file mode 100644 index 6647de001d..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/noclickandhold.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property bool clicked: false - - MouseArea { - width: 200; height: 200 - onClicked: { root.clicked = true } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/pressedCanceled.qml b/tests/auto/declarative/qquickmousearea/data/pressedCanceled.qml deleted file mode 100644 index 231436d0f2..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/pressedCanceled.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - color: "#ffffff" - width: 320; height: 240 - property bool pressed:mouse.pressed - property bool canceled: false - property bool released: false - - MouseArea { - id: mouse - anchors.fill: parent - onPressed: { root.canceled = false } - onCanceled: {root.canceled = true} - onReleased: {root.released = true; root.canceled = false} - } -} \ No newline at end of file diff --git a/tests/auto/declarative/qquickmousearea/data/pressedOrdering.qml b/tests/auto/declarative/qquickmousearea/data/pressedOrdering.qml deleted file mode 100644 index 7aa3098100..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/pressedOrdering.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property string value: "base" - - MouseArea { - id: mouseArea - width: 200; height: 200 - onClicked: toggleState.state = "toggled" - } - - StateGroup { - states: State { - name: "pressed" - when: mouseArea.pressed - PropertyChanges { target: root; value: "pressed" } - } - } - - StateGroup { - id: toggleState - states: State { - name: "toggled" - PropertyChanges { target: root; value: "toggled" } - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/preventstealing.qml b/tests/auto/declarative/qquickmousearea/data/preventstealing.qml deleted file mode 100644 index fb0d6955c1..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/preventstealing.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Flickable { - property bool stealing: true - width: 200 - height: 200 - contentWidth: 400 - contentHeight: 400 - Rectangle { - color: "black" - width: 400 - height: 400 - Rectangle { - x: 50; y: 50 - width: 100; height: 100 - color: "steelblue" - MouseArea { - objectName: "mousearea" - anchors.fill: parent - preventStealing: stealing - } - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/rejectEvent.qml b/tests/auto/declarative/qquickmousearea/data/rejectEvent.qml deleted file mode 100644 index 816fc76fac..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/rejectEvent.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - color: "#ffffff" - width: 320; height: 240 - property bool mr1_pressed: false - property bool mr1_released: false - property bool mr1_canceled: false - property bool mr2_pressed: false - property bool mr2_released: false - property bool mr2_canceled: false - - MouseArea { - id: mouseRegion1 - anchors.fill: parent - onPressed: { root.mr1_pressed = true } - onReleased: { root.mr1_released = true } - onCanceled: { root.mr1_canceled = true } - } - MouseArea { - id: mouseRegion2 - width: 120; height: 120 - onPressed: { root.mr2_pressed = true; mouse.accepted = false } - onReleased: { root.mr2_released = true } - onCanceled: { root.mr2_canceled = true } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/updateMousePosOnClick.qml b/tests/auto/declarative/qquickmousearea/data/updateMousePosOnClick.qml deleted file mode 100644 index 7377a2e86c..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/updateMousePosOnClick.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "#ffffff" - width: 320; height: 240 - MouseArea { - id: mouseRegion - objectName: "mouseregion" - anchors.fill: parent - Rectangle { - id: ball - objectName: "ball" - width: 20; height: 20 - radius: 10 - color: "#0000ff" - x: { mouseRegion.mouseX } - y: mouseRegion.mouseY - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/data/updateMousePosOnResize.qml b/tests/auto/declarative/qquickmousearea/data/updateMousePosOnResize.qml deleted file mode 100644 index 55af864060..0000000000 --- a/tests/auto/declarative/qquickmousearea/data/updateMousePosOnResize.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - color: "#ffffff" - width: 320; height: 240 - Rectangle { - id: brother - objectName: "brother" - color: "lightgreen" - x: 200; y: 100 - width: 120; height: 120 - } - MouseArea { - id: mouseRegion - objectName: "mouseregion" - - property int x1 - property int y1 - property int x2 - property int y2 - property bool emitPositionChanged: false - property bool mouseMatchesPos: true - - anchors.fill: brother - onPressed: { - if (mouse.x != mouseX || mouse.y != mouseY) - mouseMatchesPos = false - x1 = mouseX; y1 = mouseY - anchors.fill = parent - } - onPositionChanged: { emitPositionChanged = true } - onMouseXChanged: { - if (mouse.x != mouseX || mouse.y != mouseY) - mouseMatchesPos = false - x2 = mouseX; y2 = mouseY - } - onMouseYChanged: { - if (mouse.x != mouseX || mouse.y != mouseY) - mouseMatchesPos = false - x2 = mouseX; y2 = mouseY - } - } -} diff --git a/tests/auto/declarative/qquickmousearea/qquickmousearea.pro b/tests/auto/declarative/qquickmousearea/qquickmousearea.pro deleted file mode 100644 index 3581a7b9c9..0000000000 --- a/tests/auto/declarative/qquickmousearea/qquickmousearea.pro +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickmousearea -macx:CONFIG -= app_bundle - -HEADERS += ../shared/testhttpserver.h -SOURCES += tst_qquickmousearea.cpp ../shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp deleted file mode 100644 index ac1eea7a41..0000000000 --- a/tests/auto/declarative/qquickmousearea/tst_qquickmousearea.cpp +++ /dev/null @@ -1,824 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -//#define OLDWAY - -class tst_QQuickMouseArea: public QObject -{ - Q_OBJECT -private slots: - void initTestCase(); - void cleanupTestCase(); - void dragProperties(); - void resetDrag(); - void dragging(); - void updateMouseAreaPosOnClick(); - void updateMouseAreaPosOnResize(); - void noOnClickedWithPressAndHold(); - void onMousePressRejected(); - void pressedCanceledOnWindowDeactivate(); - void doubleClick(); - void clickTwice(); - void pressedOrdering(); - void preventStealing(); - void clickThrough(); - void testQtQuick11Attributes(); - void testQtQuick11Attributes_data(); - void hoverPosition(); - void hoverPropagation(); - -private: - QQuickView *createView(); -}; - -void tst_QQuickMouseArea::initTestCase() -{ - -} - -void tst_QQuickMouseArea::cleanupTestCase() -{ - -} - -void tst_QQuickMouseArea::dragProperties() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); - QQuickDrag *drag = mouseRegion->drag(); - QVERIFY(mouseRegion != 0); - QVERIFY(drag != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); - QQuickItem *rootItem = qobject_cast(canvas->rootObject()); - QVERIFY(rootItem != 0); - QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); - drag->setTarget(rootItem); - QCOMPARE(targetSpy.count(),1); - drag->setTarget(rootItem); - QCOMPARE(targetSpy.count(),1); - - // axis - QCOMPARE(drag->axis(), QQuickDrag::XandYAxis); - QSignalSpy axisSpy(drag, SIGNAL(axisChanged())); - drag->setAxis(QQuickDrag::XAxis); - QCOMPARE(drag->axis(), QQuickDrag::XAxis); - QCOMPARE(axisSpy.count(),1); - drag->setAxis(QQuickDrag::XAxis); - QCOMPARE(axisSpy.count(),1); - - // minimum and maximum properties - QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged())); - QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged())); - QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged())); - QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged())); - - QCOMPARE(drag->xmin(), 0.0); - QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width()); - QCOMPARE(drag->ymin(), 0.0); - QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height()); - - drag->setXmin(10); - drag->setXmax(10); - drag->setYmin(10); - drag->setYmax(10); - - QCOMPARE(drag->xmin(), 10.0); - QCOMPARE(drag->xmax(), 10.0); - QCOMPARE(drag->ymin(), 10.0); - QCOMPARE(drag->ymax(), 10.0); - - QCOMPARE(xminSpy.count(),1); - QCOMPARE(xmaxSpy.count(),1); - QCOMPARE(yminSpy.count(),1); - QCOMPARE(ymaxSpy.count(),1); - - drag->setXmin(10); - drag->setXmax(10); - drag->setYmin(10); - drag->setYmax(10); - - QCOMPARE(xminSpy.count(),1); - QCOMPARE(xmaxSpy.count(),1); - QCOMPARE(yminSpy.count(),1); - QCOMPARE(ymaxSpy.count(),1); - - // filterChildren - QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged())); - - drag->setFilterChildren(true); - - QVERIFY(drag->filterChildren()); - QCOMPARE(filterChildrenSpy.count(), 1); - - drag->setFilterChildren(true); - QCOMPARE(filterChildrenSpy.count(), 1); - - delete canvas; -} - -void tst_QQuickMouseArea::resetDrag() -{ - QQuickView *canvas = createView(); - - canvas->rootContext()->setContextProperty("haveTarget", QVariant(true)); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); - QQuickDrag *drag = mouseRegion->drag(); - QVERIFY(mouseRegion != 0); - QVERIFY(drag != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); - QQuickItem *rootItem = qobject_cast(canvas->rootObject()); - QVERIFY(rootItem != 0); - QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); - QVERIFY(drag->target() != 0); - canvas->rootContext()->setContextProperty("haveTarget", QVariant(false)); - QCOMPARE(targetSpy.count(),1); - QVERIFY(drag->target() == 0); - - delete canvas; -} - - -void tst_QQuickMouseArea::dragging() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWait(20); - QVERIFY(canvas->rootObject() != 0); - - QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); - QQuickDrag *drag = mouseRegion->drag(); - QVERIFY(mouseRegion != 0); - QVERIFY(drag != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - QVERIFY(blackRect == drag->target()); - - QVERIFY(!drag->active()); - -#ifdef OLDWAY - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); -#else - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); -#endif - - QVERIFY(!drag->active()); - QCOMPARE(blackRect->x(), 50.0); - QCOMPARE(blackRect->y(), 50.0); - - // First move event triggers drag, second is acted upon. - // This is due to possibility of higher stacked area taking precedence. - - QTest::mouseMove(canvas, QPoint(111,111)); - QTest::qWait(50); - QTest::mouseMove(canvas, QPoint(122,122)); - QTest::qWait(50); - - QVERIFY(drag->active()); - QCOMPARE(blackRect->x(), 72.0); - QCOMPARE(blackRect->y(), 72.0); - -#ifdef OLDWAY - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); -#else - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122)); - QTest::qWait(50); -#endif - - QVERIFY(!drag->active()); - QCOMPARE(blackRect->x(), 72.0); - QCOMPARE(blackRect->y(), 72.0); - - delete canvas; -} - -QQuickView *tst_QQuickMouseArea::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setBaseSize(QSize(240,320)); - - return canvas; -} - -void tst_QQuickMouseArea::updateMouseAreaPosOnClick() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); - QVERIFY(mouseRegion != 0); - - QQuickRectangle *rect = canvas->rootObject()->findChild("ball"); - QVERIFY(rect != 0); - - QCOMPARE(mouseRegion->mouseX(), rect->x()); - QCOMPARE(mouseRegion->mouseY(), rect->y()); - - QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &event); - - QCOMPARE(mouseRegion->mouseX(), 100.0); - QCOMPARE(mouseRegion->mouseY(), 100.0); - - QCOMPARE(mouseRegion->mouseX(), rect->x()); - QCOMPARE(mouseRegion->mouseY(), rect->y()); - - delete canvas; -} - -void tst_QQuickMouseArea::updateMouseAreaPosOnResize() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); - QVERIFY(mouseRegion != 0); - - QQuickRectangle *rect = canvas->rootObject()->findChild("brother"); - QVERIFY(rect != 0); - - QCOMPARE(mouseRegion->mouseX(), 0.0); - QCOMPARE(mouseRegion->mouseY(), 0.0); - - QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &event); - - QVERIFY(!mouseRegion->property("emitPositionChanged").toBool()); - QVERIFY(mouseRegion->property("mouseMatchesPos").toBool()); - - QCOMPARE(mouseRegion->property("x1").toReal(), 0.0); - QCOMPARE(mouseRegion->property("y1").toReal(), 0.0); - - QCOMPARE(mouseRegion->property("x2").toReal(), rect->x()); - QCOMPARE(mouseRegion->property("y2").toReal(), rect->y()); - - QCOMPARE(mouseRegion->mouseX(), rect->x()); - QCOMPARE(mouseRegion->mouseY(), rect->y()); - - delete canvas; -} - -void tst_QQuickMouseArea::noOnClickedWithPressAndHold() -{ - { - // We handle onPressAndHold, therefore no onClicked - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QVERIFY(!canvas->rootObject()->property("clicked").toBool()); - QVERIFY(!canvas->rootObject()->property("held").toBool()); - - QTest::qWait(1000); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QVERIFY(!canvas->rootObject()->property("clicked").toBool()); - QVERIFY(canvas->rootObject()->property("held").toBool()); - - delete canvas; - } - - { - // We do not handle onPressAndHold, therefore we get onClicked - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QVERIFY(!canvas->rootObject()->property("clicked").toBool()); - - QTest::qWait(1000); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QVERIFY(canvas->rootObject()->property("clicked").toBool()); - - delete canvas; - } -} - -void tst_QQuickMouseArea::onMousePressRejected() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - QVERIFY(canvas->rootObject()->property("enabled").toBool()); - - QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("mr1_released").toBool()); - QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); - QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool()); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("mr1_released").toBool()); - QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); - QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); - QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool()); - - QTest::qWait(200); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QVERIFY(canvas->rootObject()->property("mr1_released").toBool()); - QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); - - delete canvas; -} -void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - QVERIFY(!canvas->rootObject()->property("pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("released").toBool()); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QVERIFY(canvas->rootObject()->property("pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("released").toBool()); - - QTest::qWait(200); - - QEvent windowDeactivateEvent(QEvent::WindowDeactivate); - QApplication::sendEvent(canvas, &windowDeactivateEvent); - QVERIFY(!canvas->rootObject()->property("pressed").toBool()); - QVERIFY(canvas->rootObject()->property("canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("released").toBool()); - - QTest::qWait(200); - - //press again - QApplication::sendEvent(canvas, &pressEvent); - QVERIFY(canvas->rootObject()->property("pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("canceled").toBool()); - QVERIFY(!canvas->rootObject()->property("released").toBool()); - - QTest::qWait(200); - - //release - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - QVERIFY(!canvas->rootObject()->property("pressed").toBool()); - QVERIFY(!canvas->rootObject()->property("canceled").toBool()); - QVERIFY(canvas->rootObject()->property("released").toBool()); - - delete canvas; -} -void tst_QQuickMouseArea::doubleClick() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QCOMPARE(canvas->rootObject()->property("released").toInt(), 1); - - pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QApplication::sendEvent(canvas, &releaseEvent); - - QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("released").toInt(), 2); - - delete canvas; -} - -// QTBUG-14832 -void tst_QQuickMouseArea::clickTwice() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("released").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1); - - pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QApplication::sendEvent(canvas, &pressEvent); - QApplication::sendEvent(canvas, &releaseEvent); - - QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2); - QCOMPARE(canvas->rootObject()->property("released").toInt(), 2); - QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2); - - delete canvas; -} - -void tst_QQuickMouseArea::pressedOrdering() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base")); - - QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &pressEvent); - - QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); - - QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); - QApplication::sendEvent(canvas, &releaseEvent); - - QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled")); - - QApplication::sendEvent(canvas, &pressEvent); - - QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); - - delete canvas; -} - -void tst_QQuickMouseArea::preventStealing() -{ - QQuickView *canvas = createView(); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); - QVERIFY(flickable != 0); - - QQuickMouseArea *mouseArea = canvas->rootObject()->findChild("mousearea"); - QVERIFY(mouseArea != 0); - - QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*))); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80)); - - // Without preventStealing, mouse movement over MouseArea would - // cause the Flickable to steal mouse and trigger content movement. - - QTest::mouseMove(canvas,QPoint(69,69)); - QTest::mouseMove(canvas,QPoint(58,58)); - QTest::mouseMove(canvas,QPoint(47,47)); - - // We should have received all three move events - QCOMPARE(mousePositionSpy.count(), 3); - QVERIFY(mouseArea->pressed()); - - // Flickable content should not have moved. - QCOMPARE(flickable->contentX(), 0.); - QCOMPARE(flickable->contentY(), 0.); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47)); - - // Now allow stealing and confirm Flickable does its thing. - canvas->rootObject()->setProperty("stealing", false); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80)); - - // Without preventStealing, mouse movement over MouseArea would - // cause the Flickable to steal mouse and trigger content movement. - - QTest::mouseMove(canvas,QPoint(69,69)); - QTest::mouseMove(canvas,QPoint(58,58)); - QTest::mouseMove(canvas,QPoint(47,47)); - - // We should only have received the first move event - QCOMPARE(mousePositionSpy.count(), 4); - // Our press should be taken away - QVERIFY(!mouseArea->pressed()); - - // Flickable content should have moved. - - QCOMPARE(flickable->contentX(), 11.); - QCOMPARE(flickable->contentY(), 11.); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50)); - - delete canvas; -} - -void tst_QQuickMouseArea::clickThrough() -{ - //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - - QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); - - QTest::qWait(800); // to avoid generating a double click. - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(1000); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - - QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); - QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); - - QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); - QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); - - delete canvas; - - //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored - canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough2.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); - - QTest::qWait(800); // to avoid generating a double click. - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(1000); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0); - - QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0); - - canvas->rootObject()->setProperty("letThrough", QVariant(true)); - - QTest::qWait(800); // to avoid generating a double click. - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); - - QTest::qWait(800); // to avoid generating a double click. - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(1000); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); - - QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); - QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); - - canvas->rootObject()->setProperty("noPropagation", QVariant(true)); - - QTest::qWait(800); // to avoid generating a double click. - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - - QTest::qWait(800); // to avoid generating a double click. - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(1000); - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); - QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); - QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); - QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); - - delete canvas; -} - -void tst_QQuickMouseArea::testQtQuick11Attributes() -{ - QFETCH(QString, code); - QFETCH(QString, warning); - QFETCH(QString, error); - - QDeclarativeEngine engine; - QObject *obj; - - QDeclarativeComponent valid(&engine); - valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl("")); - obj = valid.create(); - QVERIFY(obj); - QVERIFY(valid.errorString().isEmpty()); - delete obj; - - QDeclarativeComponent invalid(&engine); - invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl("")); - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); - obj = invalid.create(); - QCOMPARE(invalid.errorString(), error); - delete obj; -} - -void tst_QQuickMouseArea::testQtQuick11Attributes_data() -{ - QTest::addColumn("code"); - QTest::addColumn("warning"); - QTest::addColumn("error"); - - QTest::newRow("preventStealing") << "preventStealing: true" - << "QDeclarativeComponent: Component is not ready" - << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n"; -} - -void tst_QQuickMouseArea::hoverPosition() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml"))); - - QQuickItem *root = canvas->rootObject(); - QVERIFY(root != 0); - - QCOMPARE(root->property("mouseX").toReal(), qreal(0)); - QCOMPARE(root->property("mouseY").toReal(), qreal(0)); - - QTest::mouseMove(canvas,QPoint(10,32)); - - - QCOMPARE(root->property("mouseX").toReal(), qreal(10)); - QCOMPARE(root->property("mouseY").toReal(), qreal(32)); - - delete canvas; -} - -void tst_QQuickMouseArea::hoverPropagation() -{ - //QTBUG-18175, to behave like GV did. - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml"))); - - QQuickItem *root = canvas->rootObject(); - QVERIFY(root != 0); - - QCOMPARE(root->property("point1").toBool(), false); - QCOMPARE(root->property("point2").toBool(), false); - - QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0); - QApplication::sendEvent(canvas, &moveEvent); - - QCOMPARE(root->property("point1").toBool(), true); - QCOMPARE(root->property("point2").toBool(), false); - - QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0); - QApplication::sendEvent(canvas, &moveEvent2); - QCOMPARE(root->property("point1").toBool(), false); - QCOMPARE(root->property("point2").toBool(), true); - - delete canvas; -} - -QTEST_MAIN(tst_QQuickMouseArea) - -#include "tst_qquickmousearea.moc" diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml deleted file mode 100644 index 53a2bf87f9..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/data/inFlickable.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -Flickable { - width: 240 - height: 320 - - contentWidth: width - contentHeight: height * 2 - - MultiPointTouchArea { - anchors.fill: parent - minimumTouchPoints: 2 - maximumTouchPoints: 2 - onGestureStarted: { - if ((Math.abs(point2.x - point2.startX) > gesture.dragThreshold/2) && (Math.abs(point1.x - point1.startX) > gesture.dragThreshold/2)) { - gesture.grab() - } - } - touchPoints: [ - TouchPoint { id: point1; objectName: "point1" }, - TouchPoint { id: point2; objectName: "point2" } - ] - } -} - diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml deleted file mode 100644 index 37b8820aa0..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/data/nested.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -MultiPointTouchArea { - width: 240 - height: 320 - - property bool grabInnerArea: true - - minimumTouchPoints: 2 - maximumTouchPoints: 3 - touchPoints: [ - TouchPoint { objectName: "point11" }, - TouchPoint { objectName: "point12" } - ] - - MultiPointTouchArea { - anchors.fill: parent - minimumTouchPoints: 3 - maximumTouchPoints: 3 - onGestureStarted: if (grabInnerArea) gesture.grab() - touchPoints: [ - TouchPoint { objectName: "point21" }, - TouchPoint { objectName: "point22" }, - TouchPoint { objectName: "point23" } - ] - } -} diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml deleted file mode 100644 index 039607e26c..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/data/nonOverlapping.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - - MultiPointTouchArea { - width: parent.width - height: 160 - minimumTouchPoints: 2 - maximumTouchPoints: 2 - onGestureStarted: gesture.grab() - touchPoints: [ - TouchPoint { objectName: "point11" }, - TouchPoint { objectName: "point12" } - ] - } - - MultiPointTouchArea { - width: parent.width - height: 160 - y: 160 - minimumTouchPoints: 3 - maximumTouchPoints: 3 - onGestureStarted: gesture.grab() - touchPoints: [ - TouchPoint { objectName: "point21" }, - TouchPoint { objectName: "point22" }, - TouchPoint { objectName: "point23" } - ] - } -} diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml deleted file mode 100644 index 98ef1a9cbe..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/data/properties.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -MultiPointTouchArea { - width: 240 - height: 320 - - minimumTouchPoints: 2 - maximumTouchPoints: 4 - touchPoints: [ - TouchPoint {}, - TouchPoint {}, - TouchPoint {}, - TouchPoint {} - ] -} diff --git a/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml b/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml deleted file mode 100644 index 3a6aa86a1c..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/data/signalTest.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -MultiPointTouchArea { - width: 240 - height: 320 - - function clearCounts() { - touchPointPressCount = 0; - touchPointUpdateCount = 0; - touchPointReleaseCount = 0; - touchCount = 0; - } - - property int touchPointPressCount: 0 - property int touchPointUpdateCount: 0 - property int touchPointReleaseCount: 0 - property int touchCount: 0 - - maximumTouchPoints: 5 - - onTouchPointsPressed: { touchPointPressCount = touchPoints.length } - onTouchPointsUpdated: { touchPointUpdateCount = touchPoints.length } - onTouchPointsReleased: { touchPointReleaseCount = touchPoints.length } - onTouchUpdated: { touchCount = touchPoints.length } -} diff --git a/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro deleted file mode 100644 index 8be4b1f1fd..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/qquickmultipointtoucharea.pro +++ /dev/null @@ -1,11 +0,0 @@ -TARGET = tst_qquickmultipointtoucharea -CONFIG += testcase -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickmultipointtoucharea.cpp - -importFiles.files = data -importFiles.path = . -DEPLOYMENT += importFiles - -QT += core-private gui-private declarative-private testlib diff --git a/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp deleted file mode 100644 index 9acef50645..0000000000 --- a/tests/auto/declarative/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -class tst_QQuickMultiPointTouchArea: public QObject -{ - Q_OBJECT -private slots: - void initTestCase() {} - void cleanupTestCase() {} - - void properties(); - void signalTest(); - void nonOverlapping(); - void nested(); - void inFlickable(); - -private: - QQuickView *createAndShowView(const QString &file); -}; - -void tst_QQuickMultiPointTouchArea::properties() -{ - QQuickView *canvas = createAndShowView("properties.qml"); - QVERIFY(canvas->rootObject() != 0); - - QQuickMultiPointTouchArea *area = qobject_cast(canvas->rootObject()); - QVERIFY(area != 0); - - QCOMPARE(area->minimumTouchPoints(), 2); - QCOMPARE(area->maximumTouchPoints(), 4); - - QDeclarativeListReference ref(area, "touchPoints"); - QCOMPARE(ref.count(), 4); - - delete canvas; -} - -void tst_QQuickMultiPointTouchArea::signalTest() -{ - QQuickView *canvas = createAndShowView("signalTest.qml"); - QVERIFY(canvas->rootObject() != 0); - - QQuickMultiPointTouchArea *area = qobject_cast(canvas->rootObject()); - QVERIFY(area != 0); - - QPoint p1(20,100); - QPoint p2(40,100); - QPoint p3(60,100); - QPoint p4(80,100); - QPoint p5(100,100); - - QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); - - sequence.press(0, p1).press(1, p2).commit(); - - QCOMPARE(area->property("touchPointPressCount").toInt(), 2); - QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); - QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); - QCOMPARE(area->property("touchCount").toInt(), 2); - QMetaObject::invokeMethod(area, "clearCounts"); - - sequence.stationary(0).stationary(1).press(2, p3).commit(); - - QCOMPARE(area->property("touchPointPressCount").toInt(), 1); - QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); - QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); - QCOMPARE(area->property("touchCount").toInt(), 3); - QMetaObject::invokeMethod(area, "clearCounts"); - - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - sequence.move(0, p1).move(1, p2).stationary(2).commit(); - - QCOMPARE(area->property("touchPointPressCount").toInt(), 0); - QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2); - QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); - QCOMPARE(area->property("touchCount").toInt(), 3); - QMetaObject::invokeMethod(area, "clearCounts"); - - p3 += QPoint(10,10); - sequence.release(0, p1).release(1, p2) - .move(2, p3).press(3, p4).press(4, p5).commit(); - - QCOMPARE(area->property("touchPointPressCount").toInt(), 2); - QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1); - QCOMPARE(area->property("touchPointReleaseCount").toInt(), 2); - QCOMPARE(area->property("touchCount").toInt(), 3); - QMetaObject::invokeMethod(area, "clearCounts"); - - sequence.release(2, p3).release(3, p4).release(4, p5).commit(); - - QCOMPARE(area->property("touchPointPressCount").toInt(), 0); - QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); - QCOMPARE(area->property("touchPointReleaseCount").toInt(), 3); - QCOMPARE(area->property("touchCount").toInt(), 0); - QMetaObject::invokeMethod(area, "clearCounts"); - - delete canvas; -} - -void tst_QQuickMultiPointTouchArea::nonOverlapping() -{ - QQuickView *canvas = createAndShowView("nonOverlapping.qml"); - QVERIFY(canvas->rootObject() != 0); - - QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point11"); - QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point12"); - QQuickTouchPoint *point21 = canvas->rootObject()->findChild("point21"); - QQuickTouchPoint *point22 = canvas->rootObject()->findChild("point22"); - QQuickTouchPoint *point23 = canvas->rootObject()->findChild("point23"); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QPoint p1(20,100); - QPoint p2(40,100); - QPoint p3(60,180); - QPoint p4(80,180); - QPoint p5(100,180); - - QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); - - sequence.press(0, p1).commit(); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - sequence.stationary(0).press(1, p2).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); - QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); - - p1 += QPoint(0,10); - p2 += QPoint(5,0); - sequence.move(0, p1).move(1, p2).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - - sequence.stationary(0).stationary(1).press(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - QCOMPARE(point21->x(), qreal(60)); QCOMPARE(point21->y(), qreal(20)); - QCOMPARE(point22->x(), qreal(80)); QCOMPARE(point22->y(), qreal(20)); - QCOMPARE(point23->x(), qreal(100)); QCOMPARE(point23->y(), qreal(20)); - - p1 += QPoint(4,10); - p2 += QPoint(17,17); - p3 += QPoint(3,0); - p4 += QPoint(1,-1); - p5 += QPoint(-7,10); - sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); - QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); - QCOMPARE(point21->x(), qreal(63)); QCOMPARE(point21->y(), qreal(20)); - QCOMPARE(point22->x(), qreal(81)); QCOMPARE(point22->y(), qreal(19)); - QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30)); - - sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit(); - - //points remain valid immediately after release - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - delete canvas; -} - -void tst_QQuickMultiPointTouchArea::nested() -{ - QQuickView *canvas = createAndShowView("nested.qml"); - QVERIFY(canvas->rootObject() != 0); - - QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point11"); - QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point12"); - QQuickTouchPoint *point21 = canvas->rootObject()->findChild("point21"); - QQuickTouchPoint *point22 = canvas->rootObject()->findChild("point22"); - QQuickTouchPoint *point23 = canvas->rootObject()->findChild("point23"); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QPoint p1(20,100); - QPoint p2(40,100); - QPoint p3(60,180); - - QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); - - sequence.press(0, p1).commit(); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - sequence.stationary(0).press(1, p2).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); - QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); - - p1 += QPoint(0,10); - p2 += QPoint(5,0); - sequence.move(0, p1).move(1, p2).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - - sequence.stationary(0).stationary(1).press(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - //point11 should be same as point21, point12 same as point22 - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); - QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); - QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); - - sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - //new touch points should be ignored (have no impact on our existing touch points) - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); - QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); - QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); - - sequence.stationary(0).stationary(1).stationary(2).release(3, QPoint(80,180)).release(4, QPoint(100,180)).commit(); - - p1 += QPoint(4,10); - p2 += QPoint(17,17); - p3 += QPoint(3,0); - sequence.move(0, p1).move(1, p2).move(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); - QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); - QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); - QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); - QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); - - p1 += QPoint(4,10); - p2 += QPoint(17,17); - p3 += QPoint(3,0); - sequence.move(0, p1).move(1, p2).move(2, p3).commit(); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - //first two remain the same (touches now grabbed by inner touch area) - QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); - QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); - QCOMPARE(point21->x(), qreal(28)); QCOMPARE(point21->y(), qreal(130)); - QCOMPARE(point22->x(), qreal(79)); QCOMPARE(point22->y(), qreal(134)); - QCOMPARE(point23->x(), qreal(66)); QCOMPARE(point23->y(), qreal(180)); - - sequence.release(0, p1).release(1, p2).release(2, p3).commit(); - - sequence.press(0, p1).commit(); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - QCOMPARE(point21->isValid(), false); - QCOMPARE(point22->isValid(), false); - QCOMPARE(point23->isValid(), false); - - sequence.release(0, p1).commit(); - - //test with grabbing turned off - canvas->rootObject()->setProperty("grabInnerArea", false); - - sequence.press(0, p1).press(1, p2).press(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - p1 -= QPoint(4,10); - p2 -= QPoint(17,17); - p3 -= QPoint(3,0); - sequence.move(0, p1).move(1, p2).move(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); - QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); - QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); - QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); - QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); - - p1 -= QPoint(4,10); - p2 -= QPoint(17,17); - p3 -= QPoint(3,0); - sequence.move(0, p1).move(1, p2).move(2, p3).commit(); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - QCOMPARE(point21->isValid(), true); - QCOMPARE(point22->isValid(), true); - QCOMPARE(point23->isValid(), true); - - //all change (touches not grabbed by inner touch area) - QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); - QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); - QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); - QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); - QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); - - sequence.release(0, p1).release(1, p2).release(2, p3).commit(); - - delete canvas; -} - -void tst_QQuickMultiPointTouchArea::inFlickable() -{ - QQuickView *canvas = createAndShowView("inFlickable.qml"); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); - QVERIFY(flickable != 0); - - QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point1"); - QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point2"); - - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - - QPoint p1(20,100); - QPoint p2(40,100); - - //moving one point vertically - QTest::touchEvent(canvas).press(0, p1); - QTest::mousePress(canvas, Qt::LeftButton, 0, p1); - - p1 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1); - QTest::mouseMove(canvas, p1); - - QVERIFY(flickable->contentY() < 0); - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - - QTest::touchEvent(canvas).release(0, p1); - QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); - QTest::qWait(50); - - QTRY_VERIFY(!flickable->isMoving()); - - //moving two points vertically - p1 = QPoint(20,100); - QTest::touchEvent(canvas).press(0, p1).press(1, p2); - QTest::mousePress(canvas, Qt::LeftButton, 0, p1); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - QVERIFY(flickable->contentY() < 0); - QCOMPARE(point11->isValid(), false); - QCOMPARE(point12->isValid(), false); - - QTest::touchEvent(canvas).release(0, p1).release(1, p2); - QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); - QTest::qWait(50); - - QTRY_VERIFY(!flickable->isMoving()); - - //moving two points horizontally, then one point vertically - p1 = QPoint(20,100); - p2 = QPoint(40,100); - QTest::touchEvent(canvas).press(0, p1).press(1, p2); - QTest::mousePress(canvas, Qt::LeftButton, 0, p1); - - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - - p1 += QPoint(15,0); p2 += QPoint(15,0); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(15,0); p2 += QPoint(15,0); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(15,0); p2 += QPoint(15,0); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(15,0); p2 += QPoint(15,0); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - p1 += QPoint(0,15); p2 += QPoint(0,15); - QTest::touchEvent(canvas).move(0, p1).move(1, p2); - QTest::mouseMove(canvas, p1); - - QVERIFY(flickable->contentY() == 0); - QCOMPARE(point11->isValid(), true); - QCOMPARE(point12->isValid(), true); - - QTest::touchEvent(canvas).release(0, p1).release(1, p2); - QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); - QTest::qWait(50); - - delete canvas; -} - -QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file) -{ - QQuickView *canvas = new QQuickView(0); - canvas->setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QLatin1String("/data/") + file)); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - - return canvas; -} - -QTEST_MAIN(tst_QQuickMultiPointTouchArea) - -#include "tst_qquickmultipointtoucharea.moc" diff --git a/tests/auto/declarative/qquickpathview/data/ComponentView.qml b/tests/auto/declarative/qquickpathview/data/ComponentView.qml deleted file mode 100644 index b61033d375..0000000000 --- a/tests/auto/declarative/qquickpathview/data/ComponentView.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: view - - property string title - - width: 100; height: 100; - - model: 1 - delegate: Text { objectName: "listItem"; text: view.title } - - path: Path { - startX: 25; startY: 25; - PathLine { x: 75; y: 75 } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/asyncloader.qml b/tests/auto/declarative/qquickpathview/data/asyncloader.qml deleted file mode 100644 index 94f560f3e7..0000000000 --- a/tests/auto/declarative/qquickpathview/data/asyncloader.qml +++ /dev/null @@ -1,71 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - property real delegateWidth: 60 - property real delegateHeight: 20 - property real delegateScale: 1.0 - width: 240 - height: 320 - color: "#ffffff" - - Loader { - asynchronous: true - sourceComponent: viewComponent - anchors.fill: parent - } - - Component { - id: adelegate - Rectangle { - objectName: "wrapper" - property bool onPath: PathView.onPath - height: root.delegateHeight - width: root.delegateWidth - scale: root.delegateScale - color: PathView.isCurrentItem ? "lightsteelblue" : "white" - border.color: "black" - Text { - text: index - } - } - } - Component { - id: viewComponent - PathView { - id: view - objectName: "view" - width: 240 - height: 320 - model: 5 - delegate: adelegate - highlight: Rectangle { - width: 60 - height: 20 - color: "yellow" - } - path: Path { - startY: 120 - startX: 160 - PathQuad { - y: 120 - x: 80 - controlY: 330 - controlX: 100 - } - PathLine { - y: 160 - x: 20 - } - PathCubic { - y: 120 - x: 160 - control1Y: 0 - control1X: 100 - control2Y: 0 - control2X: 200 - } - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/closedPath.qml b/tests/auto/declarative/qquickpathview/data/closedPath.qml deleted file mode 100644 index 3ca34056c8..0000000000 --- a/tests/auto/declarative/qquickpathview/data/closedPath.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Path { - startY: 120 - startX: 160 - PathQuad { - y: 120 - x: 80 - controlY: 330 - controlX: 100 - } - PathLine { - y: 160 - x: 20 - } - PathCubic { - y: 120 - x: 160 - control1Y: 0 - control1X: 100 - control2Y: 000 - control2X: 200 - } -} diff --git a/tests/auto/declarative/qquickpathview/data/creationContext.qml b/tests/auto/declarative/qquickpathview/data/creationContext.qml deleted file mode 100644 index 79a682788b..0000000000 --- a/tests/auto/declarative/qquickpathview/data/creationContext.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -ComponentView { - title: "Hello!" -} diff --git a/tests/auto/declarative/qquickpathview/data/datamodel.qml b/tests/auto/declarative/qquickpathview/data/datamodel.qml deleted file mode 100644 index 44f2aecc0a..0000000000 --- a/tests/auto/declarative/qquickpathview/data/datamodel.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: pathview - property int viewCount: count - objectName: "pathview" - width: 240; height: 320 - pathItemCount: testObject.pathItemCount - - function checkProperties() { - testObject.error = false; - if (testObject.useModel && pathview.model != testData) { - console.log("model property incorrect"); - testObject.error = true; - } - } - - model: testObject.useModel ? testData : 0 - - delegate: Component { - id: myDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - property bool onPath: PathView.onPath - width: 20; height: 20; color: name - Text { - objectName: "myText" - text: name - } - } - } - - path: Path { - startX: 120; startY: 20; - PathLine { x: 120; y: 300 } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/displaypath.qml b/tests/auto/declarative/qquickpathview/data/displaypath.qml deleted file mode 100644 index af0f381fc4..0000000000 --- a/tests/auto/declarative/qquickpathview/data/displaypath.qml +++ /dev/null @@ -1,59 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: delegate - Rectangle { - id: wrapper - objectName: "wrapper" - height: 20 - width: 60 - color: "white" - border.color: "black" - Text { - text: index - } - Text { - x: 20 - id: displayText - objectName: "displayText" - text: display - } - } - } - ] - PathView { - id: view - objectName: "view" - width: 240 - height: 320 - model: testModel - delegate: delegate - path: Path { - startY: 120 - startX: 160 - PathQuad { - y: 120 - x: 80 - controlY: 330 - controlX: 100 - } - PathLine { - y: 160 - x: 20 - } - PathCubic { - y: 120 - x: 160 - control1Y: 0 - control1X: 100 - control2Y: 000 - control2X: 200 - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/dragpath.qml b/tests/auto/declarative/qquickpathview/data/dragpath.qml deleted file mode 100644 index f9c6615b04..0000000000 --- a/tests/auto/declarative/qquickpathview/data/dragpath.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -PathView { - width: 400 - height: 200 - model: 100 - pathItemCount: 20 - path: Path { - startX: 0; startY: 100 - PathLine { x: 400; y: 100 } - } - delegate: Rectangle { objectName: "wrapper"; height: 100; width: 2; color: PathView.isCurrentItem?"red" : "black" } - dragMargin: 100 - preferredHighlightBegin: 0.5 - preferredHighlightEnd: 0.5 - Text { - text: "current index: " + parent.currentIndex - } -} diff --git a/tests/auto/declarative/qquickpathview/data/emptymodel.qml b/tests/auto/declarative/qquickpathview/data/emptymodel.qml deleted file mode 100644 index eb4d3006f4..0000000000 --- a/tests/auto/declarative/qquickpathview/data/emptymodel.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -PathView { - model: emptyModel -} diff --git a/tests/auto/declarative/qquickpathview/data/missingPercent.qml b/tests/auto/declarative/qquickpathview/data/missingPercent.qml deleted file mode 100644 index 97af8e8982..0000000000 --- a/tests/auto/declarative/qquickpathview/data/missingPercent.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Path { - startY: 0 - startX: 0 - PathLine { x: 0; y: 50 } - PathPercent { value: .5 } - PathLine { x: 50; y: 50 } -} diff --git a/tests/auto/declarative/qquickpathview/data/openPath.qml b/tests/auto/declarative/qquickpathview/data/openPath.qml deleted file mode 100644 index 1bd8375d9e..0000000000 --- a/tests/auto/declarative/qquickpathview/data/openPath.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Path { - startY: 120 - startX: 160 - PathLine { - y: 160 - x: 20 - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathUpdate.qml b/tests/auto/declarative/qquickpathview/data/pathUpdate.qml deleted file mode 100644 index e729291025..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathUpdate.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 400 - height: 400 - - PathView { - id: view - objectName: "pathView" - anchors.fill: parent - model: 10 - delegate: Rectangle { objectName: "wrapper"; color: "green"; width: 100; height: 100 } - path: Path { - startX: view.width/2; startY: 0 - PathLine { x: view.width/2; y: view.height } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathUpdateOnStartChanged.qml b/tests/auto/declarative/qquickpathview/data/pathUpdateOnStartChanged.qml deleted file mode 100644 index 89084b2a37..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathUpdateOnStartChanged.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 800 - height: 480 - color: "black" - resources: [ - ListModel { - id: appModel - ListElement { color: "green" } - }, - Component { - id: appDelegate - Rectangle { - id: wrapper - objectName: "wrapper" - color: "green" - width: 100 - height: 100 - } - } - ] - PathView { - id: pathView - objectName: "pathView" - model: appModel - anchors.fill: parent - - transformOrigin: "Top" - delegate: appDelegate - path: Path { - objectName: "path" - startX: pathView.width / 2 // startX: 400 <- this works as expected - startY: 300 - PathLine { x: 400; y: 120 } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathline.qml b/tests/auto/declarative/qquickpathview/data/pathline.qml deleted file mode 100644 index 4c1c785bce..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathline.qml +++ /dev/null @@ -1,48 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: app - width: 360 - height: 360 - - PathView { - id: pathView - objectName: "view" - x: (app.width-pathView.width)/2 - y: 100 - width: 240 - height: 100 - - model: testModel - - Rectangle { - anchors.fill: parent - color: "white" - border.color: "black" - } - preferredHighlightBegin: 0.5 - preferredHighlightEnd: 0.5 - - delegate: Rectangle { - objectName: "wrapper" - width: 100 - height: 100 - color: PathView.isCurrentItem ? "red" : "yellow" - Text { - text: index - anchors.centerIn: parent - } - z: (PathView.isCurrentItem?1:0) - } - path: Path { - id: path - startX: -100+pathView.width/2 - startY: pathView.height/2 - PathLine { - id: line - x: 100+pathView.width/2 - y: pathView.height/2 - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathtest.qml b/tests/auto/declarative/qquickpathview/data/pathtest.qml deleted file mode 100644 index 736d58d2a9..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathtest.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -Path { - startX: 120; startY: 100 - - PathAttribute { name: "scale"; value: 1.0 } - PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } - PathPercent { value: 0.3 } - PathLine { x: 120; y: 100 } - PathCubic { - x: 180; y: 0; control1X: -10; control1Y: 90 - control2X: 210; control2Y: 90 - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathview0.qml b/tests/auto/declarative/qquickpathview/data/pathview0.qml deleted file mode 100644 index 8b9378163f..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathview0.qml +++ /dev/null @@ -1,85 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: root - property int count: view.count - property int currentA: -1 - property int currentB: -1 - property real delegateWidth: 60 - property real delegateHeight: 20 - property real delegateScale: 1.0 - width: 240 - height: 320 - color: "#ffffff" - resources: [ - Component { - id: delegate - Rectangle { - id: wrapper - objectName: "wrapper" - property bool onPath: PathView.onPath - height: root.delegateHeight - width: root.delegateWidth - scale: root.delegateScale - color: PathView.isCurrentItem ? "lightsteelblue" : "white" - border.color: "black" - Text { - text: index - } - Text { - x: 20 - id: textName - objectName: "textName" - text: name - } - Text { - x: 40 - id: textNumber - objectName: "textNumber" - text: number - } - PathView.onCurrentItemChanged: { - if (PathView.isCurrentItem) { - root.currentA = index; - root.currentB = wrapper.PathView.view.currentIndex; - } - } - } - } - ] - PathView { - id: view - objectName: "view" - width: 240 - height: 320 - model: testModel - delegate: delegate - highlight: Rectangle { - width: 60 - height: 20 - color: "yellow" - } - path: Path { - startY: 120 - startX: 160 - PathQuad { - y: 120 - x: 80 - controlY: 330 - controlX: 100 - } - PathLine { - y: 160 - x: 20 - } - PathCubic { - y: 120 - x: 160 - control1Y: 0 - control1X: 100 - control2Y: 000 - control2X: 200 - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathview1.qml b/tests/auto/declarative/qquickpathview/data/pathview1.qml deleted file mode 100644 index 53d375e596..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathview1.qml +++ /dev/null @@ -1,4 +0,0 @@ -import QtQuick 2.0 - -PathView { -} diff --git a/tests/auto/declarative/qquickpathview/data/pathview2.qml b/tests/auto/declarative/qquickpathview/data/pathview2.qml deleted file mode 100644 index 1d279c42a0..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathview2.qml +++ /dev/null @@ -1,57 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: photoPathView - y: 100; width: 800; height: 330; pathItemCount: 10; z: 1 - - path: Path { - startX: -50; startY: 40; - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: -45 } - - PathCubic { - x: 400; y: 220 - control1X: 140; control1Y: 40 - control2X: 210; control2Y: 220 - } - - PathAttribute { name: "scale"; value: 1.2 } - PathAttribute { name: "angle"; value: 0 } - - PathCubic { - x: 850; y: 40 - control2X: 660; control2Y: 40 - control1X: 590; control1Y: 220 - } - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: 45 } - } - - model: ListModel { - id: rssModel - ListElement { lColor: "red" } - ListElement { lColor: "green" } - ListElement { lColor: "yellow" } - ListElement { lColor: "blue" } - ListElement { lColor: "purple" } - ListElement { lColor: "gray" } - ListElement { lColor: "brown" } - ListElement { lColor: "thistle" } - } - - delegate: Component { - id: photoDelegate - Rectangle { - id: wrapper - width: 85; height: 85; color: lColor - scale: wrapper.PathView.scale - - transform: Rotation { - id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 - axis.y: 1; axis.z: 0; angle: wrapper.PathView.angle - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathview3.qml b/tests/auto/declarative/qquickpathview/data/pathview3.qml deleted file mode 100644 index ded5a3911c..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathview3.qml +++ /dev/null @@ -1,59 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: photoPathView - y: 100; width: 800; height: 330; pathItemCount: 4; offset: 1 - dragMargin: 24 - preferredHighlightBegin: 0.50 - preferredHighlightEnd: 0.50 - - path: Path { - startX: -50; startY: 40; - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: -45 } - - PathCubic { - x: 400; y: 220 - control1X: 140; control1Y: 40 - control2X: 210; control2Y: 220 - } - - PathAttribute { name: "scale"; value: 1.2 } - PathAttribute { name: "angle"; value: 0 } - - PathCubic { - x: 850; y: 40 - control2X: 660; control2Y: 40 - control1X: 590; control1Y: 220 - } - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: 45 } - } - - model: ListModel { - id: rssModel - ListElement { lColor: "red" } - ListElement { lColor: "green" } - ListElement { lColor: "yellow" } - ListElement { lColor: "blue" } - ListElement { lColor: "purple" } - ListElement { lColor: "gray" } - ListElement { lColor: "brown" } - ListElement { lColor: "thistle" } - } - - delegate: Component { - id: photoDelegate - Rectangle { - id: wrapper - width: 85; height: 85; color: lColor - - transform: Rotation { - id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 - axis.y: 1; axis.z: 0 - } - } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/pathview_package.qml b/tests/auto/declarative/qquickpathview/data/pathview_package.qml deleted file mode 100644 index 2af57e6bb1..0000000000 --- a/tests/auto/declarative/qquickpathview/data/pathview_package.qml +++ /dev/null @@ -1,88 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 800; height: 600 - Component { - id: photoDelegate - Package { - Item { id: pathItem; objectName: "pathItem"; Package.name: 'path'; width: 85; height: 85; scale: pathItem.PathView.scale } - Item { id: linearItem; Package.name: 'linear'; width: 85; height: 85 } - Rectangle { - id: wrapper - width: 85; height: 85; color: lColor - - transform: Rotation { - id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 - axis.y: 1; axis.z: 0 - } - state: 'path' - states: [ - State { - name: 'path' - ParentChange { target: wrapper; parent: pathItem; x: 0; y: 0 } - PropertyChanges { target: wrapper; opacity: pathItem.PathView.onPath ? 1.0 : 0 } - } - ] - } - } - } - ListModel { - id: rssModel - ListElement { lColor: "red" } - ListElement { lColor: "green" } - ListElement { lColor: "yellow" } - ListElement { lColor: "blue" } - ListElement { lColor: "purple" } - ListElement { lColor: "gray" } - ListElement { lColor: "brown" } - ListElement { lColor: "thistle" } - } - VisualDataModel { id: visualModel; model: rssModel; delegate: photoDelegate } - - PathView { - id: photoPathView - objectName: "photoPathView" - width: 800; height: 330; pathItemCount: 4; offset: 1 - dragMargin: 24 - preferredHighlightBegin: 0.50 - preferredHighlightEnd: 0.50 - - path: Path { - startX: -50; startY: 40; - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: -45 } - - PathCubic { - x: 400; y: 220 - control1X: 140; control1Y: 40 - control2X: 210; control2Y: 220 - } - - PathAttribute { name: "scale"; value: 1.2 } - PathAttribute { name: "angle"; value: 0 } - - PathCubic { - x: 850; y: 40 - control2X: 660; control2Y: 40 - control1X: 590; control1Y: 220 - } - - PathAttribute { name: "scale"; value: 0.5 } - PathAttribute { name: "angle"; value: 45 } - } - - model: visualModel.parts.path - } - - PathView { - y: 400; width: 800; height: 330; pathItemCount: 8 - - path: Path { - startX: 0; startY: 40; - PathLine { x: 800; y: 40 } - } - - model: visualModel.parts.linear - } -} diff --git a/tests/auto/declarative/qquickpathview/data/propertychanges.qml b/tests/auto/declarative/qquickpathview/data/propertychanges.qml deleted file mode 100644 index 09b309f86f..0000000000 --- a/tests/auto/declarative/qquickpathview/data/propertychanges.qml +++ /dev/null @@ -1,116 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 350; height: 220; color: "white" - Component { - id: myDelegate - Item { - id: wrapper - width: 180; height: 40; - opacity: PathView.opacity - Column { - x: 5; y: 5 - Text { text: 'Name: ' + name } - Text { text: 'Number: ' + number } - } - } - } - - PathView { - preferredHighlightBegin: 0.1 - preferredHighlightEnd: 0.1 - dragMargin: 5.0 - id: pathView - objectName: "pathView" - anchors.fill: parent - model: listModel - delegate: myDelegate - focus: true - path: Path { - id: myPath - objectName: "path" - startX: 220; startY: 200 - PathAttribute { name: "opacity"; value: 1.0; objectName: "pathAttribute"; } - PathQuad { x: 220; y: 25; controlX: 260; controlY: 75 } - PathAttribute { name: "opacity"; value: 0.3 } - PathQuad { x: 220; y: 200; controlX: -20; controlY: 75 } - } - Timer { - interval: 2000; running: true; repeat: true - onTriggered: { - if (pathView.path == alternatePath) - pathView.path = myPath; - else - pathView.path = alternatePath; - } - } - } - - data:[ - ListModel { - id: listModel - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - ListElement { - name: "Bill Smith" - number: "555 3264" - } - ListElement { - name: "John Brown" - number: "555 8426" - } - ListElement { - name: "Sam Wise" - number: "555 0473" - } - }, - ListModel { - objectName: "alternateModel" - ListElement { - name: "Jack" - number: "555 8426" - } - ListElement { - name: "Mary" - number: "555 3264" - } - }, - Path { - id: alternatePath - objectName: "alternatePath" - startX: 100; startY: 40 - PathAttribute { name: "opacity"; value: 0.0 } - PathLine { x: 100; y: 160 } - PathAttribute { name: "opacity"; value: 0.2 } - PathLine { x: 300; y: 160 } - PathAttribute { name: "opacity"; value: 0.0 } - PathLine { x: 300; y: 40 } - PathAttribute { name: "opacity"; value: 0.2 } - PathLine { x: 100; y: 40 } - } - ] -} - - diff --git a/tests/auto/declarative/qquickpathview/data/treemodel.qml b/tests/auto/declarative/qquickpathview/data/treemodel.qml deleted file mode 100644 index fcf6922d00..0000000000 --- a/tests/auto/declarative/qquickpathview/data/treemodel.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -PathView { - width: 320 - height: 240 - function setRoot(index) { - vdm.rootIndex = vdm.modelIndex(index); - } - model: VisualDataModel { - id: vdm - model: myModel - delegate: Text { objectName: "wrapper"; text: display } - } - - path: Path { - startX: 0; startY: 120 - PathLine { x: 320; y: 120 } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/undefinedpath.qml b/tests/auto/declarative/qquickpathview/data/undefinedpath.qml deleted file mode 100644 index 674e7cca8d..0000000000 --- a/tests/auto/declarative/qquickpathview/data/undefinedpath.qml +++ /dev/null @@ -1,17 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: pathView - width: 240; height: 200 - path: Path { - startX: pathView.undef/2.0; startY: 0 - PathLine { x: pathView.undef/2.0; y: 0 } - } - - delegate: Text { text: value } - model: ListModel { - ListElement { value: "one" } - ListElement { value: "two" } - ListElement { value: "three" } - } -} diff --git a/tests/auto/declarative/qquickpathview/data/vdm.qml b/tests/auto/declarative/qquickpathview/data/vdm.qml deleted file mode 100644 index 839393d9bd..0000000000 --- a/tests/auto/declarative/qquickpathview/data/vdm.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -PathView { - id: pathView - width: 240; height: 320 - - pathItemCount: 4 - preferredHighlightBegin : 0.5 - preferredHighlightEnd : 0.5 - - path: Path { - startX: 120; startY: 20; - PathLine { x: 120; y: 300 } - } - - ListModel { - id: mo - ListElement { value: "one" } - ListElement { value: "two" } - ListElement { value: "three" } - } - - model: VisualDataModel { - delegate: Text { text: model.value } - model : mo - } -} - diff --git a/tests/auto/declarative/qquickpathview/qquickpathview.pro b/tests/auto/declarative/qquickpathview/qquickpathview.pro deleted file mode 100644 index d03cd4eec7..0000000000 --- a/tests/auto/declarative/qquickpathview/qquickpathview.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickpathview -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickpathview.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private widgets testlib diff --git a/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp b/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp deleted file mode 100644 index b0efc5838d..0000000000 --- a/tests/auto/declarative/qquickpathview/tst_qquickpathview.cpp +++ /dev/null @@ -1,1629 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../shared/util.h" - -static void initStandardTreeModel(QStandardItemModel *model) -{ - QStandardItem *item; - item = new QStandardItem(QLatin1String("Row 1 Item")); - model->insertRow(0, item); - - item = new QStandardItem(QLatin1String("Row 2 Item")); - item->setCheckable(true); - model->insertRow(1, item); - - QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item")); - item->setChild(0, childItem); - - item = new QStandardItem(QLatin1String("Row 3 Item")); - item->setIcon(QIcon()); - model->insertRow(2, item); -} - - -class tst_QQuickPathView : public QObject -{ - Q_OBJECT -public: - tst_QQuickPathView(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void initValues(); - void items(); - void dataModel(); - void pathview2(); - void pathview3(); - void insertModel_data(); - void insertModel(); - void removeModel_data(); - void removeModel(); - void moveModel_data(); - void moveModel(); - void path(); - void pathMoved(); - void setCurrentIndex(); - void resetModel(); - void propertyChanges(); - void pathChanges(); - void componentChanges(); - void modelChanges(); - void pathUpdateOnStartChanged(); - void package(); - void emptyModel(); - void closed(); - void pathUpdate(); - void visualDataModel(); - void undefinedPath(); - void mouseDrag(); - void treeModel(); - void changePreferredHighlight(); - void missingPercent(); - void creationContext(); - void currentOffsetOnInsertion(); - void asynchronous(); - -private: - QQuickView *createView(); - template - T *findItem(QQuickItem *parent, const QString &objectName, int index=-1); - template - QList findItems(QQuickItem *parent, const QString &objectName); -}; - -void tst_QQuickPathView::initTestCase() -{ -} - -void tst_QQuickPathView::cleanupTestCase() -{ - -} - -class TestObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool error READ error WRITE setError) - Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged) - Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged) - -public: - TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {} - - bool error() const { return mError; } - void setError(bool err) { mError = err; } - - bool useModel() const { return mUseModel; } - void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); } - - int pathItemCount() const { return mPathItemCount; } - void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); } - -signals: - void useModelChanged(); - void pathItemCountChanged(); - -private: - bool mError; - bool mUseModel; - int mPathItemCount; -}; - -class TestModel : public QAbstractListModel -{ -public: - enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; - - TestModel(QObject *parent=0) : QAbstractListModel(parent) { - QHash roles; - roles[Name] = "name"; - roles[Number] = "number"; - setRoleNames(roles); - } - - int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } - QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { - QVariant rv; - if (role == Name) - rv = list.at(index.row()).first; - else if (role == Number) - rv = list.at(index.row()).second; - - return rv; - } - - int count() const { return rowCount(); } - QString name(int index) const { return list.at(index).first; } - QString number(int index) const { return list.at(index).second; } - - void addItem(const QString &name, const QString &number) { - beginInsertRows(QModelIndex(), list.count(), list.count()); - list.append(QPair(name, number)); - endInsertRows(); - } - - void insertItem(int index, const QString &name, const QString &number) { - beginInsertRows(QModelIndex(), index, index); - list.insert(index, QPair(name, number)); - endInsertRows(); - } - - void insertItems(int index, const QList > &items) { - beginInsertRows(QModelIndex(), index, index+items.count()-1); - for (int i=0; i(items[i].first, items[i].second)); - endInsertRows(); - } - - void removeItem(int index) { - beginRemoveRows(QModelIndex(), index, index); - list.removeAt(index); - endRemoveRows(); - } - - void removeItems(int index, int count) { - emit beginRemoveRows(QModelIndex(), index, index+count-1); - while (count--) - list.removeAt(index); - emit endRemoveRows(); - } - - void moveItem(int from, int to) { - beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); - list.move(from, to); - endMoveRows(); - } - - void moveItems(int from, int to, int count) { - beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); - move(from, to, count); - endMoveRows(); - } - - void modifyItem(int idx, const QString &name, const QString &number) { - list[idx] = QPair(name, number); - emit dataChanged(index(idx,0), index(idx,0)); - } - - void move(int from, int to, int n) - { - if (from > to) { - // Only move forwards - flip if backwards moving - int tfrom = from; - int tto = to; - from = tto; - to = tto+n; - n = tfrom-tto; - } - if (n == 1) { - list.move(from, to); - } else { - QList > replaced; - int i=0; - QList >::ConstIterator it=list.begin(); it += from+n; - for (; i >::ConstIterator f=replaced.begin(); - QList >::Iterator t=list.begin(); t += from; - for (; f != replaced.end(); ++f, ++t) - *t = *f; - } - } - -private: - QList > list; -}; - - -tst_QQuickPathView::tst_QQuickPathView() -{ -} - -void tst_QQuickPathView::initValues() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview1.qml"))); - QQuickPathView *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QVERIFY(obj->path() == 0); - QVERIFY(obj->delegate() == 0); - QCOMPARE(obj->model(), QVariant()); - QCOMPARE(obj->currentIndex(), 0); - QCOMPARE(obj->offset(), 0.); - QCOMPARE(obj->preferredHighlightBegin(), 0.); - QCOMPARE(obj->dragMargin(), 0.); - QCOMPARE(obj->count(), 0); - QCOMPARE(obj->pathItemCount(), -1); - - delete obj; -} - -void tst_QQuickPathView::items() -{ - QQuickView *canvas = createView(); - - TestModel model; - model.addItem("Fred", "12345"); - model.addItem("John", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - QCOMPARE(pathview->count(), model.count()); - QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); - QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight - - for (int i = 0; i < model.count(); ++i) { - QQuickText *name = findItem(pathview, "textName", i); - QVERIFY(name != 0); - QCOMPARE(name->text(), model.name(i)); - QQuickText *number = findItem(pathview, "textNumber", i); - QVERIFY(number != 0); - QCOMPARE(number->text(), model.number(i)); - } - - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - - QVERIFY(pathview->highlightItem()); - QPointF start = path->pointAt(0.0); - QPointF offset; - offset.setX(pathview->highlightItem()->width()/2); - offset.setY(pathview->highlightItem()->height()/2); - QCOMPARE(pathview->highlightItem()->pos() + offset, start); - - delete canvas; -} - -void tst_QQuickPathView::pathview2() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview2.qml"))); - QQuickPathView *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QVERIFY(obj->path() != 0); - QVERIFY(obj->delegate() != 0); - QVERIFY(obj->model() != QVariant()); - QCOMPARE(obj->currentIndex(), 0); - QCOMPARE(obj->offset(), 0.); - QCOMPARE(obj->preferredHighlightBegin(), 0.); - QCOMPARE(obj->dragMargin(), 0.); - QCOMPARE(obj->count(), 8); - QCOMPARE(obj->pathItemCount(), 10); - - delete obj; -} - -void tst_QQuickPathView::pathview3() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview3.qml"))); - QQuickPathView *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QVERIFY(obj->path() != 0); - QVERIFY(obj->delegate() != 0); - QVERIFY(obj->model() != QVariant()); - QCOMPARE(obj->currentIndex(), 0); - QCOMPARE(obj->offset(), 1.0); - QCOMPARE(obj->preferredHighlightBegin(), 0.5); - QCOMPARE(obj->dragMargin(), 24.); - QCOMPARE(obj->count(), 8); - QCOMPARE(obj->pathItemCount(), 4); - - delete obj; -} - -void tst_QQuickPathView::insertModel_data() -{ - QTest::addColumn("mode"); - QTest::addColumn("idx"); - QTest::addColumn("count"); - QTest::addColumn("offset"); - - // We have 8 items, with currentIndex == 4 - QTest::newRow("insert after current") - << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 5.; - QTest::newRow("insert before current") - << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.; - QTest::newRow("insert multiple after current") - << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 6.; - QTest::newRow("insert multiple before current") - << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.; - QTest::newRow("insert at end") - << int(QQuickPathView::StrictlyEnforceRange) << 8 << 1 << 5.; - QTest::newRow("insert at beginning") - << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.; - QTest::newRow("insert at current") - << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 4.; - - QTest::newRow("no range - insert after current") - << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 5.; - QTest::newRow("no range - insert before current") - << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.; - QTest::newRow("no range - insert multiple after current") - << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 6.; - QTest::newRow("no range - insert multiple before current") - << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.; - QTest::newRow("no range - insert at end") - << int(QQuickPathView::NoHighlightRange) << 8 << 1 << 5.; - QTest::newRow("no range - insert at beginning") - << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.; - QTest::newRow("no range - insert at current") - << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.; -} - -void tst_QQuickPathView::insertModel() -{ - QFETCH(int, mode); - QFETCH(int, idx); - QFETCH(int, count); - QFETCH(qreal, offset); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Ben", "12345"); - model.addItem("Bohn", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - model.addItem("Jinny", "679"); - model.addItem("Milly", "73378"); - model.addItem("Jimmy", "3535"); - model.addItem("Barb", "9039"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); - - pathview->setCurrentIndex(4); - if (mode == QQuickPathView::StrictlyEnforceRange) - QTRY_COMPARE(pathview->offset(), 4.0); - else - pathview->setOffset(4); - - QList > items; - for (int i = 0; i < count; ++i) - items.append(qMakePair(QString("New"), QString::number(i))); - - model.insertItems(idx, items); - QTRY_COMPARE(pathview->offset(), offset); - - delete canvas; -} - -void tst_QQuickPathView::removeModel_data() -{ - QTest::addColumn("mode"); - QTest::addColumn("idx"); - QTest::addColumn("count"); - QTest::addColumn("offset"); - - // We have 8 items, with currentIndex == 4 - QTest::newRow("remove after current") - << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 3.; - QTest::newRow("remove before current") - << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.; - QTest::newRow("remove multiple after current") - << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 2.; - QTest::newRow("remove multiple before current") - << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.; - QTest::newRow("remove last") - << int(QQuickPathView::StrictlyEnforceRange) << 7 << 1 << 3.; - QTest::newRow("remove first") - << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.; - QTest::newRow("remove current") - << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 3.; - - QTest::newRow("no range - remove after current") - << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 3.; - QTest::newRow("no range - remove before current") - << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.; - QTest::newRow("no range - remove multiple after current") - << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 2.; - QTest::newRow("no range - remove multiple before current") - << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.; - QTest::newRow("no range - remove last") - << int(QQuickPathView::NoHighlightRange) << 7 << 1 << 3.; - QTest::newRow("no range - remove first") - << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.; - QTest::newRow("no range - remove current offset") - << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.; -} - -void tst_QQuickPathView::removeModel() -{ - QFETCH(int, mode); - QFETCH(int, idx); - QFETCH(int, count); - QFETCH(qreal, offset); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Ben", "12345"); - model.addItem("Bohn", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - model.addItem("Jinny", "679"); - model.addItem("Milly", "73378"); - model.addItem("Jimmy", "3535"); - model.addItem("Barb", "9039"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); - - pathview->setCurrentIndex(4); - if (mode == QQuickPathView::StrictlyEnforceRange) - QTRY_COMPARE(pathview->offset(), 4.0); - else - pathview->setOffset(4); - - model.removeItems(idx, count); - QTRY_COMPARE(pathview->offset(), offset); - - delete canvas; -} - - -void tst_QQuickPathView::moveModel_data() -{ - QTest::addColumn("mode"); - QTest::addColumn("from"); - QTest::addColumn("to"); - QTest::addColumn("count"); - QTest::addColumn("offset"); - - // We have 8 items, with currentIndex == 4 - QTest::newRow("move after current") - << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 1 << 4.; - QTest::newRow("move before current") - << int(QQuickPathView::StrictlyEnforceRange) << 2 << 3 << 1 << 4.; - QTest::newRow("move before current to after") - << int(QQuickPathView::StrictlyEnforceRange) << 2 << 6 << 1 << 5.; - QTest::newRow("move multiple after current") - << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 2 << 4.; - QTest::newRow("move multiple before current") - << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 2 << 4.; - QTest::newRow("move before current to end") - << int(QQuickPathView::StrictlyEnforceRange) << 2 << 7 << 1 << 5.; - QTest::newRow("move last to beginning") - << int(QQuickPathView::StrictlyEnforceRange) << 7 << 0 << 1 << 3.; - QTest::newRow("move current") - << int(QQuickPathView::StrictlyEnforceRange) << 4 << 6 << 1 << 2.; - - QTest::newRow("no range - move after current") - << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 1 << 4.; - QTest::newRow("no range - move before current") - << int(QQuickPathView::NoHighlightRange) << 2 << 3 << 1 << 4.; - QTest::newRow("no range - move before current to after") - << int(QQuickPathView::NoHighlightRange) << 2 << 6 << 1 << 5.; - QTest::newRow("no range - move multiple after current") - << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 2 << 4.; - QTest::newRow("no range - move multiple before current") - << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 2 << 4.; - QTest::newRow("no range - move before current to end") - << int(QQuickPathView::NoHighlightRange) << 2 << 7 << 1 << 5.; - QTest::newRow("no range - move last to beginning") - << int(QQuickPathView::NoHighlightRange) << 7 << 0 << 1 << 3.; - QTest::newRow("no range - move current") - << int(QQuickPathView::NoHighlightRange) << 4 << 6 << 1 << 4.; - QTest::newRow("no range - move multiple incl. current") - << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 5 << 4.; -} - -void tst_QQuickPathView::moveModel() -{ - QFETCH(int, mode); - QFETCH(int, from); - QFETCH(int, to); - QFETCH(int, count); - QFETCH(qreal, offset); - - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Ben", "12345"); - model.addItem("Bohn", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - model.addItem("Jinny", "679"); - model.addItem("Milly", "73378"); - model.addItem("Jimmy", "3535"); - model.addItem("Barb", "9039"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); - - pathview->setCurrentIndex(4); - if (mode == QQuickPathView::StrictlyEnforceRange) - QTRY_COMPARE(pathview->offset(), 4.0); - else - pathview->setOffset(4); - - model.moveItems(from, to, count); - QTRY_COMPARE(pathview->offset(), offset); - - delete canvas; -} - -void tst_QQuickPathView::path() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathtest.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - - QVERIFY(obj != 0); - QCOMPARE(obj->startX(), 120.); - QCOMPARE(obj->startY(), 100.); - QVERIFY(obj->path() != QPainterPath()); - - QDeclarativeListReference list(obj, "pathElements"); - QCOMPARE(list.count(), 5); - - QDeclarativePathAttribute* attr = qobject_cast(list.at(0)); - QVERIFY(attr != 0); - QCOMPARE(attr->name(), QString("scale")); - QCOMPARE(attr->value(), 1.0); - - QDeclarativePathQuad* quad = qobject_cast(list.at(1)); - QVERIFY(quad != 0); - QCOMPARE(quad->x(), 120.); - QCOMPARE(quad->y(), 25.); - QCOMPARE(quad->controlX(), 260.); - QCOMPARE(quad->controlY(), 75.); - - QDeclarativePathPercent* perc = qobject_cast(list.at(2)); - QVERIFY(perc != 0); - QCOMPARE(perc->value(), 0.3); - - QDeclarativePathLine* line = qobject_cast(list.at(3)); - QVERIFY(line != 0); - QCOMPARE(line->x(), 120.); - QCOMPARE(line->y(), 100.); - - QDeclarativePathCubic* cubic = qobject_cast(list.at(4)); - QVERIFY(cubic != 0); - QCOMPARE(cubic->x(), 180.); - QCOMPARE(cubic->y(), 0.); - QCOMPARE(cubic->control1X(), -10.); - QCOMPARE(cubic->control1Y(), 90.); - QCOMPARE(cubic->control2X(), 210.); - QCOMPARE(cubic->control2Y(), 90.); - - delete obj; -} - -void tst_QQuickPathView::dataModel() -{ - QQuickView *canvas = createView(); - canvas->show(); - - QDeclarativeContext *ctxt = canvas->rootContext(); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - TestModel model; - model.addItem("red", "1"); - model.addItem("green", "2"); - model.addItem("blue", "3"); - model.addItem("purple", "4"); - model.addItem("gray", "5"); - model.addItem("brown", "6"); - model.addItem("yellow", "7"); - model.addItem("thistle", "8"); - model.addItem("cyan", "9"); - model.addItem("peachpuff", "10"); - model.addItem("powderblue", "11"); - model.addItem("gold", "12"); - model.addItem("sandybrown", "13"); - - ctxt->setContextProperty("testData", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("datamodel.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = qobject_cast(canvas->rootObject()); - QVERIFY(pathview != 0); - - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); - - QQuickItem *item = findItem(pathview, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->x(), 110.0); - QCOMPARE(item->y(), 10.0); - - model.insertItem(4, "orange", "10"); - QTest::qWait(100); - - QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); - QTRY_COMPARE(findItems(pathview, "wrapper").count(), 14); - - QVERIFY(pathview->currentIndex() == 0); - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); - - QQuickText *text = findItem(pathview, "myText", 4); - QVERIFY(text); - QCOMPARE(text->text(), model.name(4)); - - model.removeItem(2); - QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); - text = findItem(pathview, "myText", 2); - QVERIFY(text); - QCOMPARE(text->text(), model.name(2)); - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); - - testObject->setPathItemCount(5); - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); - - QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); - - QQuickRectangle *testItem = findItem(pathview, "wrapper", 4); - QVERIFY(testItem != 0); - testItem = findItem(pathview, "wrapper", 5); - QVERIFY(testItem == 0); - - pathview->setCurrentIndex(1); - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); - QTest::qWait(100); - - model.insertItem(2, "pink", "2"); - QTest::qWait(100); - - QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); - QVERIFY(pathview->currentIndex() == 1); - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); - - text = findItem(pathview, "myText", 2); - QVERIFY(text); - QCOMPARE(text->text(), model.name(2)); - - model.removeItem(3); - QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); - text = findItem(pathview, "myText", 3); - QVERIFY(text); - QCOMPARE(text->text(), model.name(3)); - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); - - model.moveItem(3, 5); - QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); - QList items = findItems(pathview, "wrapper"); - foreach (QQuickItem *item, items) { - QVERIFY(item->property("onPath").toBool()); - } - QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); - - // QTBUG-14199 - pathview->setOffset(7); - pathview->setOffset(0); - QCOMPARE(findItems(pathview, "wrapper").count(), 5); - - pathview->setCurrentIndex(model.count()-1); - model.removeItem(model.count()-1); - QCOMPARE(pathview->currentIndex(), model.count()-1); - - delete canvas; - delete testObject; -} - -void tst_QQuickPathView::pathMoved() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Ben", "12345"); - model.addItem("Bohn", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - QPointF start = path->pointAt(0.0); - QPointF offset;//Center of item is at point, but pos is from corner - offset.setX(firstItem->width()/2); - offset.setY(firstItem->height()/2); - QTRY_COMPARE(firstItem->pos() + offset, start); - pathview->setOffset(1.0); - - for (int i=0; i(pathview, "wrapper", i); - QPointF itemPos(path->pointAt(0.25 + i*0.25)); - QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y()))); - } - - pathview->setOffset(0.0); - QCOMPARE(firstItem->pos() + offset, start); - - // Change delegate size - pathview->setOffset(0.1); - pathview->setOffset(0.0); - canvas->rootObject()->setProperty("delegateWidth", 30); - QCOMPARE(firstItem->width(), 30.0); - offset.setX(firstItem->width()/2); - QTRY_COMPARE(firstItem->pos() + offset, start); - - // Change delegate scale - pathview->setOffset(0.1); - pathview->setOffset(0.0); - canvas->rootObject()->setProperty("delegateScale", 1.2); - QTRY_COMPARE(firstItem->pos() + offset, start); - - delete canvas; -} - -void tst_QQuickPathView::setCurrentIndex() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - model.addItem("Ben", "12345"); - model.addItem("Bohn", "2345"); - model.addItem("Bob", "54321"); - model.addItem("Bill", "4321"); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - QPointF start = path->pointAt(0.0); - QPointF offset;//Center of item is at point, but pos is from corner - offset.setX(firstItem->width()/2); - offset.setY(firstItem->height()/2); - QCOMPARE(firstItem->pos() + offset, start); - QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0); - QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0); - - pathview->setCurrentIndex(2); - - firstItem = findItem(pathview, "wrapper", 2); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2); - QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 1); - firstItem = findItem(pathview, "wrapper", 1); - QVERIFY(firstItem); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 0); - firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 3); - firstItem = findItem(pathview, "wrapper", 3); - QVERIFY(firstItem); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->incrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 0); - firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - // move an item, set move duration to 0, and change currentIndex to moved item. QTBUG-22786 - model.moveItem(0, 3); - pathview->setHighlightMoveDuration(0); - pathview->setCurrentIndex(3); - QCOMPARE(pathview->currentIndex(), 3); - firstItem = findItem(pathview, "wrapper", 3); - QVERIFY(firstItem); - QCOMPARE(pathview->currentItem(), firstItem); - QTRY_COMPARE(firstItem->pos() + offset, start); - model.moveItem(3, 0); - pathview->setCurrentIndex(0); - pathview->setHighlightMoveDuration(300); - - // Check the current item is still created when outside the bounds of pathItemCount. - pathview->setPathItemCount(2); - pathview->setHighlightRangeMode(QQuickPathView::NoHighlightRange); - QVERIFY(findItem(pathview, "wrapper", 0)); - QVERIFY(findItem(pathview, "wrapper", 1)); - QVERIFY(!findItem(pathview, "wrapper", 2)); - QVERIFY(!findItem(pathview, "wrapper", 3)); - - pathview->setCurrentIndex(2); - firstItem = findItem(pathview, "wrapper", 2); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(false)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 1); - firstItem = findItem(pathview, "wrapper", 1); - QVERIFY(firstItem); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 0); - firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - pathview->decrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 3); - firstItem = findItem(pathview, "wrapper", 3); - QVERIFY(firstItem); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(false)); - - pathview->incrementCurrentIndex(); - QTRY_COMPARE(pathview->currentIndex(), 0); - firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QCOMPARE(pathview->currentItem(), firstItem); - QCOMPARE(firstItem->property("onPath"), QVariant(true)); - - delete canvas; -} - -void tst_QQuickPathView::resetModel() -{ - QQuickView *canvas = createView(); - - QStringList strings; - strings << "one" << "two" << "three"; - QStringListModel model(strings); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaypath.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - QCOMPARE(pathview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(pathview, "displayText", i); - QVERIFY(display != 0); - QCOMPARE(display->text(), strings.at(i)); - } - - strings.clear(); - strings << "four" << "five" << "six" << "seven"; - model.setStringList(strings); - - QCOMPARE(pathview->count(), model.rowCount()); - - for (int i = 0; i < model.rowCount(); ++i) { - QQuickText *display = findItem(pathview, "displayText", i); - QVERIFY(display != 0); - QCOMPARE(display->text(), strings.at(i)); - } - - delete canvas; -} - -void tst_QQuickPathView::propertyChanges() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged())); - QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged())); - - QCOMPARE(pathView->preferredHighlightBegin(), 0.1); - QCOMPARE(pathView->dragMargin(), 5.0); - - pathView->setPreferredHighlightBegin(0.4); - pathView->setPreferredHighlightEnd(0.4); - pathView->setDragMargin(20.0); - - QCOMPARE(pathView->preferredHighlightBegin(), 0.4); - QCOMPARE(pathView->preferredHighlightEnd(), 0.4); - QCOMPARE(pathView->dragMargin(), 20.0); - - QCOMPARE(snapPositionSpy.count(), 1); - QCOMPARE(dragMarginSpy.count(), 1); - - pathView->setPreferredHighlightBegin(0.4); - pathView->setPreferredHighlightEnd(0.4); - pathView->setDragMargin(20.0); - - QCOMPARE(snapPositionSpy.count(), 1); - QCOMPARE(dragMarginSpy.count(), 1); - delete canvas; -} - -void tst_QQuickPathView::pathChanges() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QDeclarativePath *path = canvas->rootObject()->findChild("path"); - QVERIFY(path); - - QSignalSpy startXSpy(path, SIGNAL(startXChanged())); - QSignalSpy startYSpy(path, SIGNAL(startYChanged())); - - QCOMPARE(path->startX(), 220.0); - QCOMPARE(path->startY(), 200.0); - - path->setStartX(240.0); - path->setStartY(220.0); - - QCOMPARE(path->startX(), 240.0); - QCOMPARE(path->startY(), 220.0); - - QCOMPARE(startXSpy.count(),1); - QCOMPARE(startYSpy.count(),1); - - path->setStartX(240); - path->setStartY(220); - - QCOMPARE(startXSpy.count(),1); - QCOMPARE(startYSpy.count(),1); - - QDeclarativePath *alternatePath = canvas->rootObject()->findChild("alternatePath"); - QVERIFY(alternatePath); - - QSignalSpy pathSpy(pathView, SIGNAL(pathChanged())); - - QCOMPARE(pathView->path(), path); - - pathView->setPath(alternatePath); - QCOMPARE(pathView->path(), alternatePath); - QCOMPARE(pathSpy.count(),1); - - pathView->setPath(alternatePath); - QCOMPARE(pathSpy.count(),1); - - QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild("pathAttribute"); - QVERIFY(pathAttribute); - - QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged())); - QCOMPARE(pathAttribute->name(), QString("opacity")); - - pathAttribute->setName("scale"); - QCOMPARE(pathAttribute->name(), QString("scale")); - QCOMPARE(nameSpy.count(),1); - - pathAttribute->setName("scale"); - QCOMPARE(nameSpy.count(),1); - delete canvas; -} - -void tst_QQuickPathView::componentChanges() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QDeclarativeComponent delegateComponent(canvas->engine()); - delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); - - QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged())); - - pathView->setDelegate(&delegateComponent); - QCOMPARE(pathView->delegate(), &delegateComponent); - QCOMPARE(delegateSpy.count(),1); - - pathView->setDelegate(&delegateComponent); - QCOMPARE(delegateSpy.count(),1); - delete canvas; -} - -void tst_QQuickPathView::modelChanges() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); - QVERIFY(alternateModel); - QVariant modelVariant = QVariant::fromValue(alternateModel); - QSignalSpy modelSpy(pathView, SIGNAL(modelChanged())); - - pathView->setModel(modelVariant); - QCOMPARE(pathView->model(), modelVariant); - QCOMPARE(modelSpy.count(),1); - - pathView->setModel(modelVariant); - QCOMPARE(modelSpy.count(),1); - - pathView->setModel(QVariant()); - QCOMPARE(modelSpy.count(),2); - - delete canvas; -} - -void tst_QQuickPathView::pathUpdateOnStartChanged() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdateOnStartChanged.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QDeclarativePath *path = canvas->rootObject()->findChild("path"); - QVERIFY(path); - QCOMPARE(path->startX(), 400.0); - QCOMPARE(path->startY(), 300.0); - - QQuickItem *item = findItem(pathView, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->x(), path->startX() - item->width() / 2.0); - QCOMPARE(item->y(), path->startY() - item->height() / 2.0); - - delete canvas; -} - -void tst_QQuickPathView::package() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("photoPathView"); - QVERIFY(pathView); - - QQuickItem *item = findItem(pathView, "pathItem"); - QVERIFY(item); - QVERIFY(item->scale() != 1.0); - - delete canvas; -} - -//QTBUG-13017 -void tst_QQuickPathView::emptyModel() -{ - QQuickView *canvas = createView(); - - QStringListModel model; - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("emptyModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("emptymodel.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = qobject_cast(canvas->rootObject()); - QVERIFY(pathview != 0); - - QCOMPARE(pathview->offset(), qreal(0.0)); - - delete canvas; -} - -void tst_QQuickPathView::closed() -{ - QDeclarativeEngine engine; - - { - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("openPath.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj); - QCOMPARE(obj->isClosed(), false); - delete obj; - } - - { - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("closedPath.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj); - QCOMPARE(obj->isClosed(), true); - delete obj; - } -} - -// QTBUG-14239 -void tst_QQuickPathView::pathUpdate() -{ - QQuickView *canvas = createView(); - QVERIFY(canvas); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdate.qml"))); - - QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); - QVERIFY(pathView); - - QQuickItem *item = findItem(pathView, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->x(), 150.0); - - delete canvas; -} - -void tst_QQuickPathView::visualDataModel() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("vdm.qml"))); - - QQuickPathView *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->count(), 3); - - delete obj; -} - -void tst_QQuickPathView::undefinedPath() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("undefinedpath.qml"))); - - QQuickPathView *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QCOMPARE(obj->count(), 3); - - delete obj; -} - -void tst_QQuickPathView::mouseDrag() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_COMPARE(canvas, qGuiApp->focusWindow()); - - QQuickPathView *pathview = qobject_cast(canvas->rootObject()); - QVERIFY(pathview != 0); - - int current = pathview->currentIndex(); - - QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100)); - QTest::qWait(100); - - { - QMouseEvent mv(QEvent::MouseMove, QPoint(30,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - } - { - QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QApplication::sendEvent(canvas, &mv); - } - - QVERIFY(pathview->currentIndex() != current); - - QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100)); - - delete canvas; -} - -void tst_QQuickPathView::treeModel() -{ - QQuickView *canvas = createView(); - canvas->show(); - - QStandardItemModel model; - initStandardTreeModel(&model); - canvas->engine()->rootContext()->setContextProperty("myModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("treemodel.qml"))); - - QQuickPathView *pathview = qobject_cast(canvas->rootObject()); - QVERIFY(pathview != 0); - QCOMPARE(pathview->count(), 3); - - QQuickText *item = findItem(pathview, "wrapper", 0); - QVERIFY(item); - QCOMPARE(item->text(), QLatin1String("Row 1 Item")); - - QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1))); - QCOMPARE(pathview->count(), 1); - - QTRY_VERIFY(item = findItem(pathview, "wrapper", 0)); - QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item")); - - delete canvas; -} - -void tst_QQuickPathView::changePreferredHighlight() -{ - QQuickView *canvas = createView(); - canvas->setGeometry(0,0,400,200); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QTRY_COMPARE(canvas, qGuiApp->focusWindow()); - - QQuickPathView *pathview = qobject_cast(canvas->rootObject()); - QVERIFY(pathview != 0); - - int current = pathview->currentIndex(); - QCOMPARE(current, 0); - - QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - QPointF start = path->pointAt(0.5); - start.setX(qRound(start.x())); - start.setY(qRound(start.y())); - QPointF offset;//Center of item is at point, but pos is from corner - offset.setX(firstItem->width()/2); - offset.setY(firstItem->height()/2); - QTRY_COMPARE(firstItem->pos() + offset, start); - - pathview->setPreferredHighlightBegin(0.8); - pathview->setPreferredHighlightEnd(0.8); - start = path->pointAt(0.8); - start.setX(qRound(start.x())); - start.setY(qRound(start.y())); - QTRY_COMPARE(firstItem->pos() + offset, start); - QCOMPARE(pathview->currentIndex(), 0); - - delete canvas; -} - -void tst_QQuickPathView::creationContext() -{ - QQuickView canvas; - canvas.setGeometry(0,0,240,320); - canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); - - QQuickItem *rootItem = qobject_cast(canvas.rootObject()); - QVERIFY(rootItem); - QVERIFY(rootItem->property("count").toInt() > 0); - - QQuickItem *item; - QVERIFY(item = findItem(rootItem, "listItem", 0)); - QCOMPARE(item->property("text").toString(), QString("Hello!")); -} - -// QTBUG-21320 -void tst_QQuickPathView::currentOffsetOnInsertion() -{ - QQuickView *canvas = createView(); - canvas->show(); - - TestModel model; - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testModel", &model); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathline.qml"))); - qApp->processEvents(); - - QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); - QVERIFY(pathview != 0); - - pathview->setPreferredHighlightBegin(0.5); - pathview->setPreferredHighlightEnd(0.5); - - QCOMPARE(pathview->count(), model.count()); - - model.addItem("item0", "0"); - - QCOMPARE(pathview->count(), model.count()); - - QQuickRectangle *item = 0; - QTRY_VERIFY(item = findItem(pathview, "wrapper", 0)); - - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - - QPointF start = path->pointAt(0.5); - start = QPointF(qRound(start.x()), qRound(start.y())); - QPointF offset;//Center of item is at point, but pos is from corner - offset.setX(item->width()/2); - offset.setY(item->height()/2); - QCOMPARE(item->pos() + offset, start); - - QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged())); - - // insert an item at the beginning - model.insertItem(0, "item1", "1"); - qApp->processEvents(); - - QCOMPARE(currentIndexSpy.count(), 1); - - // currentIndex is now 1 - QVERIFY(item = findItem(pathview, "wrapper", 1)); - - // verify that current item (item 1) is still at offset 0.5 - QCOMPARE(item->pos() + offset, start); - - // insert another item at the beginning - model.insertItem(0, "item2", "2"); - qApp->processEvents(); - - QCOMPARE(currentIndexSpy.count(), 2); - - // currentIndex is now 2 - QVERIFY(item = findItem(pathview, "wrapper", 2)); - - // verify that current item (item 2) is still at offset 0.5 - QCOMPARE(item->pos() + offset, start); - - // verify that remove before current maintains current item - model.removeItem(0); - qApp->processEvents(); - - QCOMPARE(currentIndexSpy.count(), 3); - - // currentIndex is now 1 - QVERIFY(item = findItem(pathview, "wrapper", 1)); - - // verify that current item (item 1) is still at offset 0.5 - QCOMPARE(item->pos() + offset, start); - - delete canvas; -} - -void tst_QQuickPathView::asynchronous() -{ - QQuickView *canvas = createView(); - canvas->show(); - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - canvas->setSource(TESTDATA("asyncloader.qml")); - - QQuickItem *rootObject = qobject_cast(canvas->rootObject()); - QVERIFY(rootObject); - - QQuickPathView *pathview = 0; - while (!pathview) { - bool b = false; - controller.incubateWhile(&b); - pathview = rootObject->findChild("view"); - } - - // items will be created one at a time - for (int i = 0; i < 5; ++i) { - QVERIFY(findItem(pathview, "wrapper", i) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(pathview, "wrapper", i); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - // verify positioning - QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); - QVERIFY(firstItem); - QDeclarativePath *path = qobject_cast(pathview->path()); - QVERIFY(path); - QPointF start = path->pointAt(0.0); - QPointF offset;//Center of item is at point, but pos is from corner - offset.setX(firstItem->width()/2); - offset.setY(firstItem->height()/2); - QTRY_COMPARE(firstItem->pos() + offset, start); - pathview->setOffset(1.0); - - for (int i=0; i<5; i++) { - QQuickItem *curItem = findItem(pathview, "wrapper", i); - QPointF itemPos(path->pointAt(0.2 + i*0.2)); - QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y()))); - } - - delete canvas; -} - -QQuickView *tst_QQuickPathView::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - return canvas; -} - -/* - Find an item with the specified objectName. If index is supplied then the - item must also evaluate the {index} expression equal to index - */ -template -T *tst_QQuickPathView::findItem(QQuickItem *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast(item); - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -template -QList tst_QQuickPathView::findItems(QQuickItem *parent, const QString &objectName) -{ - QList items; - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->QQuickItem::children().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) - items.append(static_cast(item)); - items += findItems(item, objectName); - } - - return items; -} - -void tst_QQuickPathView::missingPercent() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("missingPercent.qml"))); - QDeclarativePath *obj = qobject_cast(c.create()); - QVERIFY(obj); - QCOMPARE(obj->attributeAt("_qfx_percent", 1.0), qreal(1.0)); - delete obj; -} - - -QTEST_MAIN(tst_QQuickPathView) - -#include "tst_qquickpathview.moc" diff --git a/tests/auto/declarative/qquickpincharea/data/pinchproperties.qml b/tests/auto/declarative/qquickpincharea/data/pinchproperties.qml deleted file mode 100644 index 44d116184e..0000000000 --- a/tests/auto/declarative/qquickpincharea/data/pinchproperties.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 -Rectangle { - id: whiteRect - property variant center - property real scale - property int pointCount: 0 - width: 240; height: 320 - color: "white" - Rectangle { - id: blackRect - objectName: "blackrect" - color: "black" - y: 50 - x: 50 - width: 100 - height: 100 - opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 - Text { text: blackRect.opacity} - PinchArea { - id: pincharea - objectName: "pincharea" - anchors.fill: parent - pinch.target: blackRect - pinch.dragAxis: Drag.XandYAxis - pinch.minimumX: 0 - pinch.maximumX: whiteRect.width-blackRect.width - pinch.minimumY: 0 - pinch.maximumY: whiteRect.height-blackRect.height - pinch.minimumScale: 1.0 - pinch.maximumScale: 2.0 - pinch.minimumRotation: 0.0 - pinch.maximumRotation: 90.0 - onPinchStarted: { - whiteRect.center = pinch.center - whiteRect.scale = pinch.scale - whiteRect.pointCount = pinch.pointCount; - } - onPinchUpdated: { - whiteRect.center = pinch.center - whiteRect.scale = pinch.scale - whiteRect.pointCount = pinch.pointCount; - } - onPinchFinished: { - whiteRect.center = pinch.center - whiteRect.scale = pinch.scale - whiteRect.pointCount = pinch.pointCount; - } - } - } - } diff --git a/tests/auto/declarative/qquickpincharea/qquickpincharea.pro b/tests/auto/declarative/qquickpincharea/qquickpincharea.pro deleted file mode 100644 index df750fb2f6..0000000000 --- a/tests/auto/declarative/qquickpincharea/qquickpincharea.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickpincharea -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickpincharea.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private testlib diff --git a/tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp deleted file mode 100644 index 0d6126e671..0000000000 --- a/tests/auto/declarative/qquickpincharea/tst_qquickpincharea.cpp +++ /dev/null @@ -1,395 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_QQuickPinchArea: public QObject -{ - Q_OBJECT -private slots: - void initTestCase(); - void cleanupTestCase(); - void pinchProperties(); - void scale(); - void pan(); - void retouch(); - -private: - QQuickView *createView(); -}; -void tst_QQuickPinchArea::initTestCase() -{ -} - -void tst_QQuickPinchArea::cleanupTestCase() -{ - -} -void tst_QQuickPinchArea::pinchProperties() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QVERIFY(canvas->rootObject() != 0); - - QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); - QQuickPinch *pinch = pinchArea->pinch(); - QVERIFY(pinchArea != 0); - QVERIFY(pinch != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - QVERIFY(blackRect == pinch->target()); - QQuickItem *rootItem = qobject_cast(canvas->rootObject()); - QVERIFY(rootItem != 0); - QSignalSpy targetSpy(pinch, SIGNAL(targetChanged())); - pinch->setTarget(rootItem); - QCOMPARE(targetSpy.count(),1); - pinch->setTarget(rootItem); - QCOMPARE(targetSpy.count(),1); - - // axis - QCOMPARE(pinch->axis(), QQuickPinch::XandYAxis); - QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged())); - pinch->setAxis(QQuickPinch::XAxis); - QCOMPARE(pinch->axis(), QQuickPinch::XAxis); - QCOMPARE(axisSpy.count(),1); - pinch->setAxis(QQuickPinch::XAxis); - QCOMPARE(axisSpy.count(),1); - - // minimum and maximum drag properties - QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged())); - QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged())); - QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged())); - QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged())); - - QCOMPARE(pinch->xmin(), 0.0); - QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width()); - QCOMPARE(pinch->ymin(), 0.0); - QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height()); - - pinch->setXmin(10); - pinch->setXmax(10); - pinch->setYmin(10); - pinch->setYmax(10); - - QCOMPARE(pinch->xmin(), 10.0); - QCOMPARE(pinch->xmax(), 10.0); - QCOMPARE(pinch->ymin(), 10.0); - QCOMPARE(pinch->ymax(), 10.0); - - QCOMPARE(xminSpy.count(),1); - QCOMPARE(xmaxSpy.count(),1); - QCOMPARE(yminSpy.count(),1); - QCOMPARE(ymaxSpy.count(),1); - - pinch->setXmin(10); - pinch->setXmax(10); - pinch->setYmin(10); - pinch->setYmax(10); - - QCOMPARE(xminSpy.count(),1); - QCOMPARE(xmaxSpy.count(),1); - QCOMPARE(yminSpy.count(),1); - QCOMPARE(ymaxSpy.count(),1); - - // minimum and maximum scale properties - QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged())); - QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged())); - - QCOMPARE(pinch->minimumScale(), 1.0); - QCOMPARE(pinch->maximumScale(), 2.0); - - pinch->setMinimumScale(0.5); - pinch->setMaximumScale(1.5); - - QCOMPARE(pinch->minimumScale(), 0.5); - QCOMPARE(pinch->maximumScale(), 1.5); - - QCOMPARE(scaleMinSpy.count(),1); - QCOMPARE(scaleMaxSpy.count(),1); - - pinch->setMinimumScale(0.5); - pinch->setMaximumScale(1.5); - - QCOMPARE(scaleMinSpy.count(),1); - QCOMPARE(scaleMaxSpy.count(),1); - - // minimum and maximum rotation properties - QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged())); - QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged())); - - QCOMPARE(pinch->minimumRotation(), 0.0); - QCOMPARE(pinch->maximumRotation(), 90.0); - - pinch->setMinimumRotation(-90.0); - pinch->setMaximumRotation(45.0); - - QCOMPARE(pinch->minimumRotation(), -90.0); - QCOMPARE(pinch->maximumRotation(), 45.0); - - QCOMPARE(rotMinSpy.count(),1); - QCOMPARE(rotMaxSpy.count(),1); - - pinch->setMinimumRotation(-90.0); - pinch->setMaximumRotation(45.0); - - QCOMPARE(rotMinSpy.count(),1); - QCOMPARE(rotMaxSpy.count(),1); - - delete canvas; -} - -QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) -{ - QTouchEvent::TouchPoint touchPoint(id); - touchPoint.setPos(i->mapFromScene(p)); - touchPoint.setScreenPos(v->mapToGlobal(p)); - touchPoint.setScenePos(p); - return touchPoint; -} - -void tst_QQuickPinchArea::scale() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(canvas->rootObject() != 0); - qApp->processEvents(); - - QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); - QQuickPinch *pinch = pinchArea->pinch(); - QVERIFY(pinchArea != 0); - QVERIFY(pinch != 0); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - - QPoint p1(80, 80); - QPoint p2(100, 100); - - QTest::touchEvent(canvas).press(0, p1, canvas); - QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas); - - QCOMPARE(root->property("scale").toReal(), 1.0); - - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas); - - QCOMPARE(root->property("scale").toReal(), 1.5); - QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 - QCOMPARE(blackRect->scale(), 1.5); - - // scale beyond bound - p1 -= QPoint(50,50); - p2 += QPoint(50,50); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(blackRect->scale(), 2.0); - - QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); - - delete canvas; -} - -void tst_QQuickPinchArea::pan() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(canvas->rootObject() != 0); - qApp->processEvents(); - - QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); - QQuickPinch *pinch = pinchArea->pinch(); - QVERIFY(pinchArea != 0); - QVERIFY(pinch != 0); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root != 0); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - - QPoint p1(80, 80); - QPoint p2(100, 100); - - QTest::touchEvent(canvas).press(0, p1, canvas); - QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); - p1 += QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(root->property("scale").toReal(), 1.0); - - p1 += QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50 - - QCOMPARE(blackRect->x(), 60.0); - QCOMPARE(blackRect->y(), 60.0); - - // pan x beyond bound - p1 += QPoint(100,100); - p2 += QPoint(100,100); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(blackRect->x(), 140.0); - QCOMPARE(blackRect->y(), 160.0); - - QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); - - delete canvas; -} - -// test pinch, release one point, touch again to continue pinch -void tst_QQuickPinchArea::retouch() -{ - QQuickView *canvas = createView(); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - QVERIFY(canvas->rootObject() != 0); - qApp->processEvents(); - - QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); - QQuickPinch *pinch = pinchArea->pinch(); - QVERIFY(pinchArea != 0); - QVERIFY(pinch != 0); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root != 0); - - QSignalSpy startedSpy(pinchArea, SIGNAL(pinchStarted(QQuickPinchEvent *))); - QSignalSpy finishedSpy(pinchArea, SIGNAL(pinchFinished(QQuickPinchEvent *))); - - // target - QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); - QVERIFY(blackRect != 0); - - QPoint p1(80, 80); - QPoint p2(100, 100); - - QTest::touchEvent(canvas).press(0, p1, canvas); - QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(root->property("scale").toReal(), 1.0); - - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - QCOMPARE(startedSpy.count(), 1); - - QCOMPARE(root->property("scale").toReal(), 1.5); - QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 - QCOMPARE(blackRect->scale(), 1.5); - - QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2); - - QCOMPARE(startedSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - - QTest::touchEvent(canvas).stationary(0).release(1, p2, canvas); - - QCOMPARE(startedSpy.count(), 1); - QCOMPARE(finishedSpy.count(), 0); - - QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 1); - - QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); - p1 -= QPoint(10,10); - p2 += QPoint(10,10); - QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); - - // Lifting and retouching results in onPinchStarted being called again - QCOMPARE(startedSpy.count(), 2); - QCOMPARE(finishedSpy.count(), 0); - - QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2); - - QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); - - QCOMPARE(startedSpy.count(), 2); - QCOMPARE(finishedSpy.count(), 1); - - delete canvas; -} - - -QQuickView *tst_QQuickPinchArea::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - return canvas; -} - -QTEST_MAIN(tst_QQuickPinchArea) - -#include "tst_qquickpincharea.moc" diff --git a/tests/auto/declarative/qquickpositioners/data/allInvisible.qml b/tests/auto/declarative/qquickpositioners/data/allInvisible.qml deleted file mode 100644 index 5894171434..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/allInvisible.qml +++ /dev/null @@ -1,44 +0,0 @@ -import QtQuick 2.0 - -Item{ - width: 400 - height: 400 - Column{ - spacing: 20 - objectName: "column" - Item{ - width: 0 - height: 20 - visible: false - } - Item{ - width: 20 - height: 0 - visible: false - } - Item{ - width: 20 - height: 20 - visible: false - } - } - Row{ - spacing: 20 - objectName: "row" - Item{ - width: 0 - height: 20 - visible: false - } - Item{ - width: 20 - height: 0 - visible: false - } - Item{ - width: 20 - height: 20 - visible: false - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/attachedproperties-column.qml b/tests/auto/declarative/qquickpositioners/data/attachedproperties-column.qml deleted file mode 100644 index 4c667aa205..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/attachedproperties-column.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 100 - height: 200 - - Column { - - Rectangle { - width: 100 - height: 100 - color: 'red' - visible: false - } - - Rectangle { - objectName: "greenRect" - width: 100 - height: 100 - color: 'green' - property int posIndex: Positioner.index - property bool isFirstItem: Positioner.isFirstItem - property bool isLastItem: Positioner.isLastItem - } - - Rectangle { - width: 100 - height: 100 - color: 'blue' - visible: false - } - - Rectangle { - objectName: "yellowRect" - width: 100 - height: 100 - color: 'yellow' - - property int posIndex: -1 - property bool isFirstItem: false - property bool isLastItem: false - - function onDemandPositioner() { - posIndex = Positioner.index; - isFirstItem = Positioner.isFirstItem - isLastItem = Positioner.isLastItem - } - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/attachedproperties-dynamic.qml b/tests/auto/declarative/qquickpositioners/data/attachedproperties-dynamic.qml deleted file mode 100644 index 894749dc16..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/attachedproperties-dynamic.qml +++ /dev/null @@ -1,44 +0,0 @@ -import QtQuick 2.0 - -Rectangle -{ - width: 300 - height: 100 - - Row { - id: pos - objectName: "pos" - anchors.fill: parent - - Rectangle { - objectName: "rect0" - width: 100 - height: 100 - color: 'red' - property int index: Positioner.index - property bool firstItem: Positioner.isFirstItem - property bool lastItem: Positioner.isLastItem - } - - Rectangle { - objectName: "rect1" - width: 100 - height: 100 - color: 'green' - property int index: Positioner.index - property bool firstItem: Positioner.isFirstItem - property bool lastItem: Positioner.isLastItem - } - - property QtObject subRect; - - function createSubRect() { - var component = Qt.createComponent("rectangleComponent.qml"); - subRect = component.createObject(pos, {}); - } - - function destroySubRect() { - subRect.destroy(); - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/attachedproperties-flow.qml b/tests/auto/declarative/qquickpositioners/data/attachedproperties-flow.qml deleted file mode 100644 index e7f9a63e2a..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/attachedproperties-flow.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 100 - - Flow { - - Rectangle { - width: 100 - height: 100 - color: 'red' - visible: false - } - - Rectangle { - objectName: "greenRect" - width: 100 - height: 100 - color: 'green' - property int posIndex: Positioner.index - property bool isFirstItem: Positioner.isFirstItem - property bool isLastItem: Positioner.isLastItem - } - - Rectangle { - width: 100 - height: 100 - color: 'blue' - visible: false - } - - Rectangle { - objectName: "yellowRect" - width: 100 - height: 100 - color: 'yellow' - - property int posIndex: -1 - property bool isFirstItem: false - property bool isLastItem: false - - function onDemandPositioner() { - posIndex = Positioner.index; - isFirstItem = Positioner.isFirstItem - isLastItem = Positioner.isLastItem - } - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/attachedproperties-grid.qml b/tests/auto/declarative/qquickpositioners/data/attachedproperties-grid.qml deleted file mode 100644 index 2094309b9f..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/attachedproperties-grid.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 100 - - Grid { - - Rectangle { - width: 100 - height: 100 - color: 'red' - visible: false - } - - Rectangle { - objectName: "greenRect" - width: 100 - height: 100 - color: 'green' - property int posIndex: Positioner.index - property bool isFirstItem: Positioner.isFirstItem - property bool isLastItem: Positioner.isLastItem - } - - Rectangle { - width: 100 - height: 100 - color: 'blue' - visible: false - } - - Rectangle { - objectName: "yellowRect" - width: 100 - height: 100 - color: 'yellow' - - property int posIndex: -1 - property bool isFirstItem: false - property bool isLastItem: false - - function onDemandPositioner() { - posIndex = Positioner.index; - isFirstItem = Positioner.isFirstItem - isLastItem = Positioner.isLastItem - } - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/attachedproperties-row.qml b/tests/auto/declarative/qquickpositioners/data/attachedproperties-row.qml deleted file mode 100644 index 212a26b431..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/attachedproperties-row.qml +++ /dev/null @@ -1,50 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 200 - height: 100 - - Row { - - Rectangle { - width: 100 - height: 100 - color: 'red' - visible: false - } - - Rectangle { - objectName: "greenRect" - width: 100 - height: 100 - color: 'green' - property int posIndex: Positioner.index - property bool isFirstItem: Positioner.isFirstItem - property bool isLastItem: Positioner.isLastItem - } - - Rectangle { - width: 100 - height: 100 - color: 'blue' - visible: false - } - - Rectangle { - objectName: "yellowRect" - width: 100 - height: 100 - color: 'yellow' - - property int posIndex: -1 - property bool isFirstItem: false - property bool isLastItem: false - - function onDemandPositioner() { - posIndex = Positioner.index; - isFirstItem = Positioner.isFirstItem - isLastItem = Positioner.isLastItem - } - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/flow-testimplicitsize.qml b/tests/auto/declarative/qquickpositioners/data/flow-testimplicitsize.qml deleted file mode 100644 index c32b78676c..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/flow-testimplicitsize.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 300; height: 200; - - property int flowLayout: 1 - - Flow { - objectName: "flow" - layoutDirection: (flowLayout == 2) ? Qt.RightToLeft : Qt.LeftToRight - flow: (flowLayout == 1) ? Flow.TopToBottom : Flow.LeftToRight; - - spacing: 20 - anchors.horizontalCenter: parent.horizontalCenter - Rectangle { color: "red"; width: 100; height: 50 } - Rectangle { color: "blue"; width: 100; height: 50 } - } -} - diff --git a/tests/auto/declarative/qquickpositioners/data/flowtest-toptobottom.qml b/tests/auto/declarative/qquickpositioners/data/flowtest-toptobottom.qml deleted file mode 100644 index a7d3ee13c7..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/flowtest-toptobottom.qml +++ /dev/null @@ -1,44 +0,0 @@ -import QtQuick 2.0 - -Item { - height: 90 - width: 480 - property bool testRightToLeft: false - - Flow { - objectName: "flow" - height: parent.height - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - flow: Flow.TopToBottom - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/flowtest.qml b/tests/auto/declarative/qquickpositioners/data/flowtest.qml deleted file mode 100644 index 40b042dd79..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/flowtest.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 90 - height: 480 - property bool testRightToLeft: false - - Flow { - objectName: "flow" - width: parent.width - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/grid-animated.qml b/tests/auto/declarative/qquickpositioners/data/grid-animated.qml deleted file mode 100644 index b8ee8f9a52..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/grid-animated.qml +++ /dev/null @@ -1,64 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - property bool testRightToLeft: true - - Grid { - objectName: "grid" - columns: 3 - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - add: Transition { - NumberAnimation { - properties: "x,y"; - } - } - move: Transition { - NumberAnimation { - properties: "x,y"; - } - } - Rectangle { - objectName: "one" - color: "red" - x: -100 - y: -100 - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - x: -100 - y: -100 - visible: false - color: "green" - width: 50 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - x: -100 - y: -100 - width: 50 - height: 50 - } - Rectangle { - objectName: "four" - color: "cyan" - x: -100 - y: -100 - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - x: -100 - y: -100 - width: 50 - height: 50 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/grid-row-column-spacing.qml b/tests/auto/declarative/qquickpositioners/data/grid-row-column-spacing.qml deleted file mode 100644 index 49bbd337e7..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/grid-row-column-spacing.qml +++ /dev/null @@ -1,43 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Grid { - objectName: "grid" - columns: 3 - spacing: 4 - rowSpacing: 7 - columnSpacing: 11 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/grid-spacing.qml b/tests/auto/declarative/qquickpositioners/data/grid-spacing.qml deleted file mode 100644 index 535a39037f..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/grid-spacing.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Grid { - objectName: "grid" - columns: 3 - spacing: 4 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/grid-toptobottom.qml b/tests/auto/declarative/qquickpositioners/data/grid-toptobottom.qml deleted file mode 100644 index 45559aab5d..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/grid-toptobottom.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Grid { - objectName: "grid" - rows: 3 - flow: Grid.TopToBottom - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/gridtest.qml b/tests/auto/declarative/qquickpositioners/data/gridtest.qml deleted file mode 100644 index 50bec1377b..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/gridtest.qml +++ /dev/null @@ -1,42 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - property bool testRightToLeft: false - Grid { - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - objectName: "grid" - columns: 3 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 30 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/gridzerocolumns.qml b/tests/auto/declarative/qquickpositioners/data/gridzerocolumns.qml deleted file mode 100644 index a252f279c3..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/gridzerocolumns.qml +++ /dev/null @@ -1,40 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Grid { - objectName: "grid" - columns: 0 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "green" - width: 20 - height: 50 - } - Rectangle { - objectName: "three" - color: "blue" - width: 50 - height: 20 - } - Rectangle { - objectName: "four" - color: "cyan" - width: 50 - height: 50 - } - Rectangle { - objectName: "five" - color: "magenta" - width: 10 - height: 10 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/horizontal-animated-disabled.qml b/tests/auto/declarative/qquickpositioners/data/horizontal-animated-disabled.qml deleted file mode 100644 index 8723ffc78f..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/horizontal-animated-disabled.qml +++ /dev/null @@ -1,40 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - - Row { - objectName: "row" - add: Transition { - enabled: false - NumberAnimation { properties: "x" } - } - move: Transition { - enabled: false - NumberAnimation { properties: "x" } - } - Rectangle { - objectName: "one" - color: "red" - x: -100; - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "blue" - x: -100; - visible: false - width: 50 - height: 50 - } - Rectangle { - objectName: "three" - x: -100; - color: "green" - width: 50 - height: 50 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/horizontal-animated.qml b/tests/auto/declarative/qquickpositioners/data/horizontal-animated.qml deleted file mode 100644 index a88c26b66c..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/horizontal-animated.qml +++ /dev/null @@ -1,47 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - property bool testRightToLeft: false - property bool testEnabled: false - - Row { - objectName: "row" - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - add: Transition { - enabled: testEnabled ? false : true - NumberAnimation { - properties: "x"; - } - } - move: Transition { - enabled: testEnabled ? false : true - NumberAnimation { - properties: "x"; - } - } - Rectangle { - objectName: "one" - color: "red" - x: -100; - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "blue" - x: -100; - visible: false - width: 50 - height: 50 - } - Rectangle { - objectName: "three" - x: -100; - color: "green" - width: 50 - height: 50 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/horizontal-spacing.qml b/tests/auto/declarative/qquickpositioners/data/horizontal-spacing.qml deleted file mode 100644 index c6ff75ac6b..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/horizontal-spacing.qml +++ /dev/null @@ -1,31 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - property bool testRightToLeft: false - - Row { - objectName: "row" - spacing: 10 - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "red" - width: 20 - height: 10 - } - Rectangle { - objectName: "three" - color: "red" - width: 40 - height: 20 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/horizontal.qml b/tests/auto/declarative/qquickpositioners/data/horizontal.qml deleted file mode 100644 index 235ee78c9b..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/horizontal.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - property bool testRightToLeft: false - Row { - objectName: "row" - layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "red" - width: 20 - height: 10 - } - Rectangle { - objectName: "three" - color: "red" - width: 40 - height: 20 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/propertychangestest.qml b/tests/auto/declarative/qquickpositioners/data/propertychangestest.qml deleted file mode 100644 index c9fd62b012..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/propertychangestest.qml +++ /dev/null @@ -1,39 +0,0 @@ -import QtQuick 2.0 - -Grid { - id: myGrid - - width: 270 - height: 270 - x: 3 - y: 3 - columns: 4 - spacing: 3 - - add: columnTransition - move: columnTransition - - Repeater { - model: 20 - Rectangle { color: "black"; width: 50; height: 50 } - } - - data: [ - Transition { - id: rowTransition - objectName: "rowTransition" - NumberAnimation { - properties: "x,y"; - easing.type: "OutInCubic" - } - }, - Transition { - id: columnTransition - objectName: "columnTransition" - NumberAnimation { - properties: "x,y"; - easing.type: "OutInCubic" - } - } - ] -} diff --git a/tests/auto/declarative/qquickpositioners/data/rectangleComponent.qml b/tests/auto/declarative/qquickpositioners/data/rectangleComponent.qml deleted file mode 100644 index de1bb99593..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/rectangleComponent.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0; - -Rectangle { - objectName: "rect2" - color: "blue" - width: 100 - height: 100 - property int index: Positioner.index - property bool firstItem: Positioner.isFirstItem - property bool lastItem: Positioner.isLastItem -} diff --git a/tests/auto/declarative/qquickpositioners/data/repeatertest.qml b/tests/auto/declarative/qquickpositioners/data/repeatertest.qml deleted file mode 100644 index d90e1cf160..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/repeatertest.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Row { - Repeater{ model: 3; - delegate: Component { - Rectangle { - color: "red" - width: 50 - height: 50 - z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} - objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} - } - } - } - } - - //This crashed once (QTBUG-16959) because the repeater ended up on the end of the list - //If this grid just instantiates without crashing, then it has not regressed. - Grid { - id: grid - rows: 2 - flow: Grid.TopToBottom - - Repeater { - model: 13 - Rectangle { - color: "goldenrod" - width: 100 - height: 100 - radius: 10 - border.width: 1 - } - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/vertical-animated.qml b/tests/auto/declarative/qquickpositioners/data/vertical-animated.qml deleted file mode 100644 index ecf593cd70..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/vertical-animated.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Column { - objectName: "column" - add: Transition { - NumberAnimation { - properties: "y"; - } - } - move: Transition { - NumberAnimation { - properties: "y"; - } - } - Rectangle { - objectName: "one" - color: "red" - y: -100 - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "blue" - y: -100 - visible: false - width: 50 - height: 50 - } - Rectangle { - objectName: "three" - color: "red" - y: -100 - width: 50 - height: 50 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/vertical-spacing.qml b/tests/auto/declarative/qquickpositioners/data/vertical-spacing.qml deleted file mode 100644 index 7087961651..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/vertical-spacing.qml +++ /dev/null @@ -1,28 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Column { - objectName: "column" - spacing: 10 - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "red" - width: 20 - height: 10 - } - Rectangle { - objectName: "three" - color: "red" - width: 40 - height: 20 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/data/vertical.qml b/tests/auto/declarative/qquickpositioners/data/vertical.qml deleted file mode 100644 index 0c3a81f008..0000000000 --- a/tests/auto/declarative/qquickpositioners/data/vertical.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 640 - height: 480 - Column { - objectName: "column" - Rectangle { - objectName: "one" - color: "red" - width: 50 - height: 50 - } - Rectangle { - objectName: "two" - color: "red" - width: 20 - height: 10 - } - Rectangle { - objectName: "three" - color: "red" - width: 40 - height: 20 - } - } -} diff --git a/tests/auto/declarative/qquickpositioners/qquickpositioners.pro b/tests/auto/declarative/qquickpositioners/qquickpositioners.pro deleted file mode 100644 index eee9eca97a..0000000000 --- a/tests/auto/declarative/qquickpositioners/qquickpositioners.pro +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickpositioners -SOURCES += tst_qquickpositioners.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp deleted file mode 100644 index ebfd394b0e..0000000000 --- a/tests/auto/declarative/qquickpositioners/tst_qquickpositioners.cpp +++ /dev/null @@ -1,1473 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" - -class tst_qquickpositioners : public QObject -{ - Q_OBJECT -public: - tst_qquickpositioners(); - -private slots: - void test_horizontal(); - void test_horizontal_rtl(); - void test_horizontal_spacing(); - void test_horizontal_spacing_rightToLeft(); - void test_horizontal_animated(); - void test_horizontal_animated_rightToLeft(); - void test_horizontal_animated_disabled(); - void test_vertical(); - void test_vertical_spacing(); - void test_vertical_animated(); - void test_grid(); - void test_grid_topToBottom(); - void test_grid_rightToLeft(); - void test_grid_spacing(); - void test_grid_row_column_spacing(); - void test_grid_animated(); - void test_grid_animated_rightToLeft(); - void test_grid_zero_columns(); - void test_propertychanges(); - void test_repeater(); - void test_flow(); - void test_flow_rightToLeft(); - void test_flow_topToBottom(); - void test_flow_resize(); - void test_flow_resize_rightToLeft(); - void test_flow_implicit_resize(); - void test_conflictinganchors(); - void test_mirroring(); - void test_allInvisible(); - void test_attachedproperties(); - void test_attachedproperties_data(); - void test_attachedproperties_dynamic(); - -private: - QQuickView *createView(const QString &filename, bool wait=true); -}; - -tst_qquickpositioners::tst_qquickpositioners() -{ -} - -void tst_qquickpositioners::test_horizontal() -{ - QQuickView *canvas = createView(TESTDATA("horizontal.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 70.0); - QCOMPARE(three->y(), 0.0); - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QCOMPARE(row->width(), 110.0); - QCOMPARE(row->height(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_rtl() -{ - QQuickView *canvas = createView(TESTDATA("horizontal.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 60.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 40.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 0.0); - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QCOMPARE(row->width(), 110.0); - QCOMPARE(row->height(), 50.0); - - // Change the width of the row and check that items stay to the right - row->setWidth(200); - QTRY_COMPARE(one->x(), 150.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 130.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 90.0); - QCOMPARE(three->y(), 0.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_spacing() -{ - QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 60.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 90.0); - QCOMPARE(three->y(), 0.0); - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QCOMPARE(row->width(), 130.0); - QCOMPARE(row->height(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_spacing_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 80.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 00.0); - QCOMPARE(three->y(), 0.0); - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QCOMPARE(row->width(), 130.0); - QCOMPARE(row->height(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_animated() -{ - QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - //Note that they animate in - QCOMPARE(one->x(), -100.0); - QCOMPARE(two->x(), -100.0); - QCOMPARE(three->x(), -100.0); - - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QVERIFY(row); - QCOMPARE(row->width(), 100.0); - QCOMPARE(row->height(), 50.0); - - //QTRY_COMPARE used instead of waiting for the expected time of animation completion - //Note that this means the duration of the animation is NOT tested - - QTRY_COMPARE(one->x(), 0.0); - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(two->isVisible(), false); - QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet - QTRY_COMPARE(two->y(), 0.0); - QTRY_COMPARE(three->x(), 50.0); - QTRY_COMPARE(three->y(), 0.0); - - //Add 'two' - two->setVisible(true); - QTRY_COMPARE(two->isVisible(), true); - QTRY_COMPARE(row->width(), 150.0); - QTRY_COMPARE(row->height(), 50.0); - - QTest::qWait(0);//Let the animation start - QVERIFY(two->x() >= -100.0 && two->x() < 50.0); - QVERIFY(three->x() >= 50.0 && three->x() < 100.0); - - QTRY_COMPARE(two->x(), 50.0); - QTRY_COMPARE(three->x(), 100.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_animated_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - //Note that they animate in - QCOMPARE(one->x(), -100.0); - QCOMPARE(two->x(), -100.0); - QCOMPARE(three->x(), -100.0); - - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QVERIFY(row); - QCOMPARE(row->width(), 100.0); - QCOMPARE(row->height(), 50.0); - - //QTRY_COMPARE used instead of waiting for the expected time of animation completion - //Note that this means the duration of the animation is NOT tested - - QTRY_COMPARE(one->x(), 50.0); - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(two->isVisible(), false); - QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet - QTRY_COMPARE(two->y(), 0.0); - QTRY_COMPARE(three->x(), 0.0); - QTRY_COMPARE(three->y(), 0.0); - - //Add 'two' - two->setVisible(true); - QTRY_COMPARE(two->isVisible(), true); - - // New size should propagate after visible change - QTRY_COMPARE(row->width(), 150.0); - QTRY_COMPARE(row->height(), 50.0); - - QTest::qWait(0);//Let the animation start - QVERIFY(one->x() >= 50.0 && one->x() < 100); - QVERIFY(two->x() >= -100.0 && two->x() < 50.0); - - QTRY_COMPARE(one->x(), 100.0); - QTRY_COMPARE(two->x(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_horizontal_animated_disabled() -{ - QQuickView *canvas = createView(TESTDATA("horizontal-animated-disabled.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QQuickItem *row = canvas->rootObject()->findChild("row"); - QVERIFY(row); - - qApp->processEvents(); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->isVisible(), false); - QCOMPARE(two->x(), -100.0);//Not 'in' yet - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 50.0); - QCOMPARE(three->y(), 0.0); - - //Add 'two' - two->setVisible(true); - QCOMPARE(two->isVisible(), true); - QTRY_COMPARE(row->width(), 150.0); - QTRY_COMPARE(row->height(), 50.0); - - QTRY_COMPARE(two->x(), 50.0); - QTRY_COMPARE(three->x(), 100.0); - - delete canvas; -} - -void tst_qquickpositioners::test_vertical() -{ - QQuickView *canvas = createView(TESTDATA("vertical.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 0.0); - QCOMPARE(two->y(), 50.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 60.0); - - QQuickItem *column = canvas->rootObject()->findChild("column"); - QVERIFY(column); - QCOMPARE(column->height(), 80.0); - QCOMPARE(column->width(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_vertical_spacing() -{ - QQuickView *canvas = createView(TESTDATA("vertical-spacing.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 0.0); - QCOMPARE(two->y(), 60.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 80.0); - - QQuickItem *column = canvas->rootObject()->findChild("column"); - QCOMPARE(column->height(), 100.0); - QCOMPARE(column->width(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_vertical_animated() -{ - QQuickView *canvas = createView(TESTDATA("vertical-animated.qml"), false); - - //Note that they animate in - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QCOMPARE(one->y(), -100.0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QCOMPARE(two->y(), -100.0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QCOMPARE(three->y(), -100.0); - - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - QQuickItem *column = canvas->rootObject()->findChild("column"); - QVERIFY(column); - QCOMPARE(column->height(), 100.0); - QCOMPARE(column->width(), 50.0); - - //QTRY_COMPARE used instead of waiting for the expected time of animation completion - //Note that this means the duration of the animation is NOT tested - - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(one->x(), 0.0); - QTRY_COMPARE(two->isVisible(), false); - QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet - QTRY_COMPARE(two->x(), 0.0); - QTRY_COMPARE(three->y(), 50.0); - QTRY_COMPARE(three->x(), 0.0); - - //Add 'two' - two->setVisible(true); - QTRY_COMPARE(two->isVisible(), true); - QTRY_COMPARE(column->height(), 150.0); - QTRY_COMPARE(column->width(), 50.0); - QTest::qWait(0);//Let the animation start - QVERIFY(two->y() >= -100.0 && two->y() < 50.0); - QVERIFY(three->y() >= 50.0 && three->y() < 100.0); - - QTRY_COMPARE(two->y(), 50.0); - QTRY_COMPARE(three->y(), 100.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid() -{ - QQuickView *canvas = createView(TESTDATA("gridtest.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 70.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 50.0); - QCOMPARE(five->x(), 50.0); - QCOMPARE(five->y(), 50.0); - - QQuickGrid *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->flow(), QQuickGrid::LeftToRight); - QCOMPARE(grid->width(), 100.0); - QCOMPARE(grid->height(), 100.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_topToBottom() -{ - QQuickView *canvas = createView(TESTDATA("grid-toptobottom.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 0.0); - QCOMPARE(two->y(), 50.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 100.0); - QCOMPARE(four->x(), 50.0); - QCOMPARE(four->y(), 0.0); - QCOMPARE(five->x(), 50.0); - QCOMPARE(five->y(), 50.0); - - QQuickGrid *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->flow(), QQuickGrid::TopToBottom); - QCOMPARE(grid->width(), 100.0); - QCOMPARE(grid->height(), 120.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("gridtest.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 50.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 30.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 50.0); - QCOMPARE(four->y(), 50.0); - QCOMPARE(five->x(), 40.0); - QCOMPARE(five->y(), 50.0); - - QQuickGrid *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->layoutDirection(), Qt::RightToLeft); - QCOMPARE(grid->width(), 100.0); - QCOMPARE(grid->height(), 100.0); - - // Change the width of the grid and check that items stay to the right - grid->setWidth(200); - QTRY_COMPARE(one->x(), 150.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 130.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 100.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 150.0); - QCOMPARE(four->y(), 50.0); - QCOMPARE(five->x(), 140.0); - QCOMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_spacing() -{ - QQuickView *canvas = createView(TESTDATA("grid-spacing.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 54.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 78.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 54.0); - QCOMPARE(five->x(), 54.0); - QCOMPARE(five->y(), 54.0); - - QQuickItem *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->width(), 128.0); - QCOMPARE(grid->height(), 104.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_row_column_spacing() -{ - QQuickView *canvas = createView(TESTDATA("grid-row-column-spacing.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 61.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 92.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 57.0); - QCOMPARE(five->x(), 61.0); - QCOMPARE(five->y(), 57.0); - - QQuickItem *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->width(), 142.0); - QCOMPARE(grid->height(), 107.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_animated() -{ - QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - //Note that all animate in - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QCOMPARE(one->x(), -100.0); - QCOMPARE(one->y(), -100.0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QCOMPARE(two->x(), -100.0); - QCOMPARE(two->y(), -100.0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QCOMPARE(three->x(), -100.0); - QCOMPARE(three->y(), -100.0); - - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QCOMPARE(four->x(), -100.0); - QCOMPARE(four->y(), -100.0); - - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - QCOMPARE(five->x(), -100.0); - QCOMPARE(five->y(), -100.0); - - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - QQuickItem *grid = canvas->rootObject()->findChild("grid"); - QVERIFY(grid); - QCOMPARE(grid->width(), 150.0); - QCOMPARE(grid->height(), 100.0); - - //QTRY_COMPARE used instead of waiting for the expected time of animation completion - //Note that this means the duration of the animation is NOT tested - - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(one->x(), 0.0); - QTRY_COMPARE(two->isVisible(), false); - QTRY_COMPARE(two->y(), -100.0); - QTRY_COMPARE(two->x(), -100.0); - QTRY_COMPARE(three->y(), 0.0); - QTRY_COMPARE(three->x(), 50.0); - QTRY_COMPARE(four->y(), 0.0); - QTRY_COMPARE(four->x(), 100.0); - QTRY_COMPARE(five->y(), 50.0); - QTRY_COMPARE(five->x(), 0.0); - - //Add 'two' - two->setVisible(true); - QCOMPARE(two->isVisible(), true); - QCOMPARE(grid->width(), 150.0); - QCOMPARE(grid->height(), 100.0); - QTest::qWait(0);//Let the animation start - QCOMPARE(two->x(), -100.0); - QCOMPARE(two->y(), -100.0); - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(three->x(), 50.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 100.0); - QCOMPARE(four->y(), 0.0); - QCOMPARE(five->x(), 0.0); - QCOMPARE(five->y(), 50.0); - //Let the animation complete - QTRY_COMPARE(two->x(), 50.0); - QTRY_COMPARE(two->y(), 0.0); - QTRY_COMPARE(one->x(), 0.0); - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(three->x(), 100.0); - QTRY_COMPARE(three->y(), 0.0); - QTRY_COMPARE(four->x(), 0.0); - QTRY_COMPARE(four->y(), 50.0); - QTRY_COMPARE(five->x(), 50.0); - QTRY_COMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_animated_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - //Note that all animate in - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QCOMPARE(one->x(), -100.0); - QCOMPARE(one->y(), -100.0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QCOMPARE(two->x(), -100.0); - QCOMPARE(two->y(), -100.0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QCOMPARE(three->x(), -100.0); - QCOMPARE(three->y(), -100.0); - - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QCOMPARE(four->x(), -100.0); - QCOMPARE(four->y(), -100.0); - - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - QCOMPARE(five->x(), -100.0); - QCOMPARE(five->y(), -100.0); - - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - QQuickItem *grid = canvas->rootObject()->findChild("grid"); - QVERIFY(grid); - QCOMPARE(grid->width(), 150.0); - QCOMPARE(grid->height(), 100.0); - - //QTRY_COMPARE used instead of waiting for the expected time of animation completion - //Note that this means the duration of the animation is NOT tested - - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(one->x(), 100.0); - QTRY_COMPARE(two->isVisible(), false); - QTRY_COMPARE(two->y(), -100.0); - QTRY_COMPARE(two->x(), -100.0); - QTRY_COMPARE(three->y(), 0.0); - QTRY_COMPARE(three->x(), 50.0); - QTRY_COMPARE(four->y(), 0.0); - QTRY_COMPARE(four->x(), 0.0); - QTRY_COMPARE(five->y(), 50.0); - QTRY_COMPARE(five->x(), 100.0); - - //Add 'two' - two->setVisible(true); - QCOMPARE(two->isVisible(), true); - QCOMPARE(grid->width(), 150.0); - QCOMPARE(grid->height(), 100.0); - QTest::qWait(0);//Let the animation start - QCOMPARE(two->x(), -100.0); - QCOMPARE(two->y(), -100.0); - QCOMPARE(one->x(), 100.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(three->x(), 50.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 0.0); - QCOMPARE(five->x(), 100.0); - QCOMPARE(five->y(), 50.0); - //Let the animation complete - QTRY_COMPARE(two->x(), 50.0); - QTRY_COMPARE(two->y(), 0.0); - QTRY_COMPARE(one->x(), 100.0); - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(three->x(), 0.0); - QTRY_COMPARE(three->y(), 0.0); - QTRY_COMPARE(four->x(), 100.0); - QTRY_COMPARE(four->y(), 50.0); - QTRY_COMPARE(five->x(), 50.0); - QTRY_COMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_grid_zero_columns() -{ - QQuickView *canvas = createView(TESTDATA("gridzerocolumns.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 70.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 120.0); - QCOMPARE(four->y(), 0.0); - QCOMPARE(five->x(), 0.0); - QCOMPARE(five->y(), 50.0); - - QQuickItem *grid = canvas->rootObject()->findChild("grid"); - QCOMPARE(grid->width(), 170.0); - QCOMPARE(grid->height(), 60.0); - - delete canvas; -} - -void tst_qquickpositioners::test_propertychanges() -{ - QQuickView *canvas = createView(TESTDATA("propertychangestest.qml")); - - QQuickGrid *grid = qobject_cast(canvas->rootObject()); - QVERIFY(grid != 0); - QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild("rowTransition"); - QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild("columnTransition"); - - QSignalSpy addSpy(grid, SIGNAL(addChanged())); - QSignalSpy moveSpy(grid, SIGNAL(moveChanged())); - QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged())); - QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged())); - - QVERIFY(grid); - QVERIFY(rowTransition); - QVERIFY(columnTransition); - QCOMPARE(grid->add(), columnTransition); - QCOMPARE(grid->move(), columnTransition); - QCOMPARE(grid->columns(), 4); - QCOMPARE(grid->rows(), -1); - - grid->setAdd(rowTransition); - grid->setMove(rowTransition); - QCOMPARE(grid->add(), rowTransition); - QCOMPARE(grid->move(), rowTransition); - QCOMPARE(addSpy.count(),1); - QCOMPARE(moveSpy.count(),1); - - grid->setAdd(rowTransition); - grid->setMove(rowTransition); - QCOMPARE(addSpy.count(),1); - QCOMPARE(moveSpy.count(),1); - - grid->setAdd(0); - grid->setMove(0); - QCOMPARE(addSpy.count(),2); - QCOMPARE(moveSpy.count(),2); - - grid->setColumns(-1); - grid->setRows(3); - QCOMPARE(grid->columns(), -1); - QCOMPARE(grid->rows(), 3); - QCOMPARE(columnsSpy.count(),1); - QCOMPARE(rowsSpy.count(),1); - - grid->setColumns(-1); - grid->setRows(3); - QCOMPARE(columnsSpy.count(),1); - QCOMPARE(rowsSpy.count(),1); - - grid->setColumns(2); - grid->setRows(2); - QCOMPARE(columnsSpy.count(),2); - QCOMPARE(rowsSpy.count(),2); - - delete canvas; -} - -void tst_qquickpositioners::test_repeater() -{ - QQuickView *canvas = createView(TESTDATA("repeatertest.qml")); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 100.0); - QCOMPARE(three->y(), 0.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow() -{ - QQuickView *canvas = createView(TESTDATA("flowtest.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 0.0); - QCOMPARE(three->y(), 50.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 70.0); - QCOMPARE(five->x(), 50.0); - QCOMPARE(five->y(), 70.0); - - QQuickItem *flow = canvas->rootObject()->findChild("flow"); - QVERIFY(flow); - QCOMPARE(flow->width(), 90.0); - QCOMPARE(flow->height(), 120.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("flowtest.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 40.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 20.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 40.0); - QCOMPARE(three->y(), 50.0); - QCOMPARE(four->x(), 40.0); - QCOMPARE(four->y(), 70.0); - QCOMPARE(five->x(), 30.0); - QCOMPARE(five->y(), 70.0); - - QQuickItem *flow = canvas->rootObject()->findChild("flow"); - QVERIFY(flow); - QCOMPARE(flow->width(), 90.0); - QCOMPARE(flow->height(), 120.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow_topToBottom() -{ - QQuickView *canvas = createView(TESTDATA("flowtest-toptobottom.qml")); - - canvas->rootObject()->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 0.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 50.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 50.0); - QCOMPARE(three->y(), 50.0); - QCOMPARE(four->x(), 100.0); - QCOMPARE(four->y(), 00.0); - QCOMPARE(five->x(), 100.0); - QCOMPARE(five->y(), 50.0); - - QQuickItem *flow = canvas->rootObject()->findChild("flow"); - QVERIFY(flow); - QCOMPARE(flow->height(), 90.0); - QCOMPARE(flow->width(), 150.0); - - canvas->rootObject()->setProperty("testRightToLeft", true); - - QVERIFY(flow); - QCOMPARE(flow->height(), 90.0); - QCOMPARE(flow->width(), 150.0); - - QCOMPARE(one->x(), 100.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 80.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 50.0); - QCOMPARE(three->y(), 50.0); - QCOMPARE(four->x(), 0.0); - QCOMPARE(four->y(), 0.0); - QCOMPARE(five->x(), 40.0); - QCOMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow_resize() -{ - QQuickView *canvas = createView(TESTDATA("flowtest.qml")); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root); - root->setWidth(125); - root->setProperty("testRightToLeft", false); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QVERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QTRY_COMPARE(one->x(), 0.0); - QTRY_COMPARE(one->y(), 0.0); - QTRY_COMPARE(two->x(), 50.0); - QTRY_COMPARE(two->y(), 0.0); - QTRY_COMPARE(three->x(), 70.0); - QTRY_COMPARE(three->y(), 0.0); - QTRY_COMPARE(four->x(), 0.0); - QTRY_COMPARE(four->y(), 50.0); - QTRY_COMPARE(five->x(), 50.0); - QTRY_COMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow_resize_rightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("flowtest.qml")); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root); - root->setWidth(125); - root->setProperty("testRightToLeft", true); - - QQuickRectangle *one = canvas->rootObject()->findChild("one"); - QTRY_VERIFY(one != 0); - QQuickRectangle *two = canvas->rootObject()->findChild("two"); - QVERIFY(two != 0); - QQuickRectangle *three = canvas->rootObject()->findChild("three"); - QVERIFY(three != 0); - QQuickRectangle *four = canvas->rootObject()->findChild("four"); - QVERIFY(four != 0); - QQuickRectangle *five = canvas->rootObject()->findChild("five"); - QVERIFY(five != 0); - - QCOMPARE(one->x(), 75.0); - QCOMPARE(one->y(), 0.0); - QCOMPARE(two->x(), 55.0); - QCOMPARE(two->y(), 0.0); - QCOMPARE(three->x(), 5.0); - QCOMPARE(three->y(), 0.0); - QCOMPARE(four->x(), 75.0); - QCOMPARE(four->y(), 50.0); - QCOMPARE(five->x(), 65.0); - QCOMPARE(five->y(), 50.0); - - delete canvas; -} - -void tst_qquickpositioners::test_flow_implicit_resize() -{ - QQuickView *canvas = createView(TESTDATA("flow-testimplicitsize.qml")); - QVERIFY(canvas->rootObject() != 0); - - QQuickFlow *flow = canvas->rootObject()->findChild("flow"); - QVERIFY(flow != 0); - - QCOMPARE(flow->width(), 100.0); - QCOMPARE(flow->height(), 120.0); - - canvas->rootObject()->setProperty("flowLayout", 0); - QCOMPARE(flow->flow(), QQuickFlow::LeftToRight); - QCOMPARE(flow->width(), 220.0); - QCOMPARE(flow->height(), 50.0); - - canvas->rootObject()->setProperty("flowLayout", 1); - QCOMPARE(flow->flow(), QQuickFlow::TopToBottom); - QCOMPARE(flow->width(), 100.0); - QCOMPARE(flow->height(), 120.0); - - canvas->rootObject()->setProperty("flowLayout", 2); - QCOMPARE(flow->layoutDirection(), Qt::RightToLeft); - QCOMPARE(flow->width(), 220.0); - QCOMPARE(flow->height(), 50.0); - - delete canvas; -} - -QString warningMessage; - -void interceptWarnings(QtMsgType type, const char *msg) -{ - Q_UNUSED( type ); - warningMessage = msg; -} - -void tst_qquickpositioners::test_conflictinganchors() -{ - QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings); - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine); - - component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile("")); - QQuickItem *item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - delete item; - - component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - delete item; - - component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - delete item; - - component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - delete item; - - component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QVERIFY(warningMessage.isEmpty()); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid")); - warningMessage.clear(); - delete item; - - component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow")); - delete item; - - component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile("")); - item = qobject_cast(component.create()); - QVERIFY(item); - QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow")); - qInstallMsgHandler(oldMsgHandler); - delete item; -} - -void tst_qquickpositioners::test_mirroring() -{ - QList qmlFiles; - qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml"; - QList objectNames; - objectNames << "one" << "two" << "three" << "four" << "five"; - - foreach (const QString qmlFile, qmlFiles) { - QQuickView *canvasA = createView(TESTDATA(qmlFile)); - QQuickItem *rootA = qobject_cast(canvasA->rootObject()); - - QQuickView *canvasB = createView(TESTDATA(qmlFile)); - QQuickItem *rootB = qobject_cast(canvasB->rootObject()); - - rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft - - // LTR != RTL - foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) - break; - QQuickItem *itemA = rootA->findChild(objectName); - QQuickItem *itemB = rootB->findChild(objectName); - QTRY_VERIFY(itemA->x() != itemB->x()); - } - - QQuickItemPrivate* rootPrivateB = QQuickItemPrivate::get(rootB); - - rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true - rootPrivateB->isMirrorImplicit = false; - rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true - rootPrivateB->resolveLayoutMirror(); - - // RTL == mirror - foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) - break; - QQuickItem *itemA = rootA->findChild(objectName); - QQuickItem *itemB = rootB->findChild(objectName); - QTRY_COMPARE(itemA->x(), itemB->x()); - } - - rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight - rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft - - // LTR == RTL + mirror - foreach (const QString objectName, objectNames) { - // horizontal.qml only has three items - if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) - break; - QQuickItem *itemA = rootA->findChild(objectName); - QQuickItem *itemB = rootB->findChild(objectName); - QTRY_COMPARE(itemA->x(), itemB->x()); - } - delete canvasA; - delete canvasB; - } -} - -void tst_qquickpositioners::test_allInvisible() -{ - //QTBUG-19361 - QQuickView *canvas = createView(TESTDATA("allInvisible.qml")); - - QQuickItem *root = qobject_cast(canvas->rootObject()); - QVERIFY(root); - - QQuickRow *row = canvas->rootObject()->findChild("row"); - QVERIFY(row != 0); - QVERIFY(row->width() == 0); - QVERIFY(row->height() == 0); - QQuickColumn *column = canvas->rootObject()->findChild("column"); - QVERIFY(column != 0); - QVERIFY(column->width() == 0); - QVERIFY(column->height() == 0); -} - -void tst_qquickpositioners::test_attachedproperties() -{ - QFETCH(QString, filename); - - QQuickView *canvas = createView(filename); - QVERIFY(canvas->rootObject() != 0); - - QQuickRectangle *greenRect = canvas->rootObject()->findChild("greenRect"); - QVERIFY(greenRect != 0); - - int posIndex = greenRect->property("posIndex").toInt(); - QVERIFY(posIndex == 0); - bool isFirst = greenRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == true); - bool isLast = greenRect->property("isLastItem").toBool(); - QVERIFY(isLast == false); - - QQuickRectangle *yellowRect = canvas->rootObject()->findChild("yellowRect"); - QVERIFY(yellowRect != 0); - - posIndex = yellowRect->property("posIndex").toInt(); - QVERIFY(posIndex == -1); - isFirst = yellowRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == false); - isLast = yellowRect->property("isLastItem").toBool(); - QVERIFY(isLast == false); - - yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner"); - - posIndex = yellowRect->property("posIndex").toInt(); - QVERIFY(posIndex == 1); - isFirst = yellowRect->property("isFirstItem").toBool(); - QVERIFY(isFirst == false); - isLast = yellowRect->property("isLastItem").toBool(); - QVERIFY(isLast == true); - - delete canvas; -} - -void tst_qquickpositioners::test_attachedproperties_data() -{ - QTest::addColumn("filename"); - - QTest::newRow("column") << TESTDATA("attachedproperties-column.qml"); - QTest::newRow("row") << TESTDATA("attachedproperties-row.qml"); - QTest::newRow("grid") << TESTDATA("attachedproperties-grid.qml"); - QTest::newRow("flow") << TESTDATA("attachedproperties-flow.qml"); -} - -void tst_qquickpositioners::test_attachedproperties_dynamic() -{ - QQuickView *canvas = createView(TESTDATA("attachedproperties-dynamic.qml")); - QVERIFY(canvas->rootObject() != 0); - - QQuickRow *row = canvas->rootObject()->findChild("pos"); - QVERIFY(row != 0); - - QQuickRectangle *rect0 = canvas->rootObject()->findChild("rect0"); - QVERIFY(rect0 != 0); - - int posIndex = rect0->property("index").toInt(); - QVERIFY(posIndex == 0); - bool isFirst = rect0->property("firstItem").toBool(); - QVERIFY(isFirst == true); - bool isLast = rect0->property("lastItem").toBool(); - QVERIFY(isLast == false); - - QQuickRectangle *rect1 = canvas->rootObject()->findChild("rect1"); - QVERIFY(rect1 != 0); - - posIndex = rect1->property("index").toInt(); - QVERIFY(posIndex == 1); - isFirst = rect1->property("firstItem").toBool(); - QVERIFY(isFirst == false); - isLast = rect1->property("lastItem").toBool(); - QVERIFY(isLast == true); - - row->metaObject()->invokeMethod(row, "createSubRect"); - - QTRY_VERIFY(rect1->property("index").toInt() == 1); - QTRY_VERIFY(rect1->property("firstItem").toBool() == false); - QTRY_VERIFY(rect1->property("lastItem").toBool() == false); - - QQuickRectangle *rect2 = canvas->rootObject()->findChild("rect2"); - QVERIFY(rect2 != 0); - - posIndex = rect2->property("index").toInt(); - QVERIFY(posIndex == 2); - isFirst = rect2->property("firstItem").toBool(); - QVERIFY(isFirst == false); - isLast = rect2->property("lastItem").toBool(); - QVERIFY(isLast == true); - - row->metaObject()->invokeMethod(row, "destroySubRect"); - - qApp->processEvents(QEventLoop::DeferredDeletion); - - QTRY_VERIFY(rect1->property("index").toInt() == 1); - QTRY_VERIFY(rect1->property("firstItem").toBool() == false); - QTRY_VERIFY(rect1->property("lastItem").toBool() == true); - - delete canvas; -} - -QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait) -{ - QQuickView *canvas = new QQuickView(0); - - canvas->setSource(QUrl::fromLocalFile(filename)); - canvas->show(); - if (wait) - QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn - - return canvas; -} - - -QTEST_MAIN(tst_qquickpositioners) - -#include "tst_qquickpositioners.moc" diff --git a/tests/auto/declarative/qquickrepeater/data/asyncloader.qml b/tests/auto/declarative/qquickrepeater/data/asyncloader.qml deleted file mode 100644 index 82094e2666..0000000000 --- a/tests/auto/declarative/qquickrepeater/data/asyncloader.qml +++ /dev/null @@ -1,32 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 360 - height: 480 - - Loader { - asynchronous: true - sourceComponent: viewComponent - } - - Component { - id: viewComponent - Column { - objectName: "container" - Repeater { - id: repeater - objectName: "repeater" - - model: 10 - - delegate: Rectangle { - objectName: "delegate" + index - color: "red" - width: 360 - height: 50 - Text { text: index } - } - } - } - } -} diff --git a/tests/auto/declarative/qquickrepeater/data/initparent.qml b/tests/auto/declarative/qquickrepeater/data/initparent.qml deleted file mode 100644 index e6571f09d3..0000000000 --- a/tests/auto/declarative/qquickrepeater/data/initparent.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Item { - id: root - property Item parentItem: null - Repeater { - model: 1 - Item { - Component.onCompleted: root.parentItem = parent - } - } -} diff --git a/tests/auto/declarative/qquickrepeater/data/intmodel.qml b/tests/auto/declarative/qquickrepeater/data/intmodel.qml deleted file mode 100644 index 30a650dd52..0000000000 --- a/tests/auto/declarative/qquickrepeater/data/intmodel.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: container - objectName: "container" - width: 240 - height: 320 - color: "white" - - function checkProperties() { - testObject.error = false; - if (repeater.delegate != comp) { - console.log("delegate property incorrect"); - testObject.error = true; - } - } - - Component { - id: comp - Item{} - } - - Repeater { - id: repeater - objectName: "repeater" - model: testData - delegate: comp - } -} diff --git a/tests/auto/declarative/qquickrepeater/data/itemlist.qml b/tests/auto/declarative/qquickrepeater/data/itemlist.qml deleted file mode 100644 index 174bfd4d18..0000000000 --- a/tests/auto/declarative/qquickrepeater/data/itemlist.qml +++ /dev/null @@ -1,68 +0,0 @@ -// This example demonstrates placing items in a view using -// a VisualItemModel - -import QtQuick 2.0 - -Rectangle { - id: root - color: "lightgray" - width: 240 - height: 320 - property variant itemModel: itemModel1 - - function checkProperties() { - testObject.error = false; - if (testObject.useModel && view.model != root.itemModel) { - console.log("model property incorrect"); - testObject.error = true; - } - } - - function switchModel() { - root.itemModel = itemModel2 - } - - VisualItemModel { - id: itemModel1 - objectName: "itemModel1" - Rectangle { - objectName: "item1" - height: 50; width: 100; color: "#FFFEF0" - Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item2" - height: 50; width: 100; color: "#F0FFF7" - Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item3" - height: 50; width: 100; color: "#F4F0FF" - Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - } - - VisualItemModel { - id: itemModel2 - objectName: "itemModel2" - Rectangle { - objectName: "item4" - height: 50; width: 100; color: "#FFFEF0" - Text { objectName: "text4"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - Rectangle { - objectName: "item5" - height: 50; width: 100; color: "#F0FFF7" - Text { objectName: "text5"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } - } - } - - Column { - objectName: "container" - Repeater { - id: view - objectName: "repeater" - model: testObject.useModel ? root.itemModel : 0 - } - } -} diff --git a/tests/auto/declarative/qquickrepeater/data/modelChanged.qml b/tests/auto/declarative/qquickrepeater/data/modelChanged.qml deleted file mode 100644 index 23af127e79..0000000000 --- a/tests/auto/declarative/qquickrepeater/data/modelChanged.qml +++ /dev/null @@ -1,26 +0,0 @@ -import QtQuick 2.0 - -Column { - Repeater { - id: repeater - objectName: "repeater" - - property int itemsCount - property variant itemsFound: [] - - delegate: Rectangle { - color: "red" - width: (index+1)*50 - height: 50 - } - - onModelChanged: { - repeater.itemsCount = repeater.count - var items = [] - for (var i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../shared/util.h" -#include "../../../shared/util.h" - -inline QUrl TEST_FILE(const QString &filename) -{ - return QUrl::fromLocalFile(TESTDATA(filename)); -} - -class tst_QQuickRepeater : public QObject -{ - Q_OBJECT -public: - tst_QQuickRepeater(); - -private slots: - void numberModel(); - void objectList(); - void stringList(); - void dataModel_adding(); - void dataModel_removing(); - void dataModel_changes(); - void itemModel(); - void resetModel(); - void modelChanged(); - void properties(); - void asynchronous(); - void initParent(); - -private: - QQuickView *createView(); - template - T *findItem(QObject *parent, const QString &objectName, int index); - template - T *findItem(QObject *parent, const QString &id); -}; - -class TestObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(bool error READ error WRITE setError) - Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged) - -public: - TestObject() : QObject(), mError(true), mUseModel(false) {} - - bool error() const { return mError; } - void setError(bool err) { mError = err; } - - bool useModel() const { return mUseModel; } - void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); } - -signals: - void useModelChanged(); - -private: - bool mError; - bool mUseModel; -}; - -class TestModel : public QAbstractListModel -{ -public: - enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; - - TestModel(QObject *parent=0) : QAbstractListModel(parent) { - QHash roles; - roles[Name] = "name"; - roles[Number] = "number"; - setRoleNames(roles); - } - - int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } - QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { - QVariant rv; - if (role == Name) - rv = list.at(index.row()).first; - else if (role == Number) - rv = list.at(index.row()).second; - - return rv; - } - - int count() const { return rowCount(); } - QString name(int index) const { return list.at(index).first; } - QString number(int index) const { return list.at(index).second; } - - void addItem(const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), list.count(), list.count()); - list.append(QPair(name, number)); - emit endInsertRows(); - } - - void insertItem(int index, const QString &name, const QString &number) { - emit beginInsertRows(QModelIndex(), index, index); - list.insert(index, QPair(name, number)); - emit endInsertRows(); - } - - void removeItem(int index) { - emit beginRemoveRows(QModelIndex(), index, index); - list.removeAt(index); - emit endRemoveRows(); - } - - void moveItem(int from, int to) { - emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); - list.move(from, to); - emit endMoveRows(); - } - - void modifyItem(int idx, const QString &name, const QString &number) { - list[idx] = QPair(name, number); - emit dataChanged(index(idx,0), index(idx,0)); - } - -private: - QList > list; -}; - - -tst_QQuickRepeater::tst_QQuickRepeater() -{ -} - -void tst_QQuickRepeater::numberModel() -{ - QQuickView *canvas = createView(); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testData", 5); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(TEST_FILE("intmodel.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QCOMPARE(repeater->parentItem()->childItems().count(), 5+1); - - QVERIFY(!repeater->itemAt(-1)); - for (int i=0; icount(); i++) - QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i)); - QVERIFY(!repeater->itemAt(repeater->count())); - - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); - - delete testObject; - delete canvas; -} - -class MyObject : public QObject -{ - Q_OBJECT - Q_PROPERTY(int idx READ idx CONSTANT) -public: - MyObject(int i) : QObject(), m_idx(i) {} - - int idx() const { return m_idx; } - - int m_idx; -}; - -void tst_QQuickRepeater::objectList() -{ - QQuickView *canvas = createView(); - QObjectList data; - for (int i=0; i<100; i++) - data << new MyObject(i); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testData", QVariant::fromValue(data)); - - canvas->setSource(TEST_FILE("objlist.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data - QCOMPARE(repeater->property("instantiated").toInt(), 100); - - QVERIFY(!repeater->itemAt(-1)); - for (int i=0; iitemAt(i), repeater->parentItem()->childItems().at(i)); - QVERIFY(!repeater->itemAt(data.count())); - - QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); - QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); - ctxt->setContextProperty("testData", QVariant::fromValue(data)); - QCOMPARE(addedSpy.count(), data.count()); - QCOMPARE(removedSpy.count(), data.count()); - - qDeleteAll(data); - delete canvas; -} - -/* -The Repeater element creates children at its own position in its parent's -stacking order. In this test we insert a repeater between two other Text -elements to test this. -*/ -void tst_QQuickRepeater::stringList() -{ - QQuickView *canvas = createView(); - - QStringList data; - data << "One"; - data << "Two"; - data << "Three"; - data << "Four"; - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testData", data); - - canvas->setSource(TEST_FILE("repeater1.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - - QCOMPARE(container->childItems().count(), data.count() + 3); - - bool saw_repeater = false; - for (int i = 0; i < container->childItems().count(); ++i) { - - if (i == 0) { - QQuickText *name = qobject_cast(container->childItems().at(i)); - QVERIFY(name != 0); - QCOMPARE(name->text(), QLatin1String("Zero")); - } else if (i == container->childItems().count() - 2) { - // The repeater itself - QQuickRepeater *rep = qobject_cast(container->childItems().at(i)); - QCOMPARE(rep, repeater); - saw_repeater = true; - continue; - } else if (i == container->childItems().count() - 1) { - QQuickText *name = qobject_cast(container->childItems().at(i)); - QVERIFY(name != 0); - QCOMPARE(name->text(), QLatin1String("Last")); - } else { - QQuickText *name = qobject_cast(container->childItems().at(i)); - QVERIFY(name != 0); - QCOMPARE(name->text(), data.at(i-1)); - } - } - QVERIFY(saw_repeater); - - delete canvas; -} - -void tst_QQuickRepeater::dataModel_adding() -{ - QQuickView *canvas = createView(); - QDeclarativeContext *ctxt = canvas->rootContext(); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - TestModel testModel; - ctxt->setContextProperty("testData", &testModel); - canvas->setSource(TEST_FILE("repeater2.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - - QVERIFY(!repeater->itemAt(0)); - - QSignalSpy countSpy(repeater, SIGNAL(countChanged())); - QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); - - // add to empty model - testModel.addItem("two", "2"); - QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(addedSpy.count(), 1); - QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); - QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(0)); - addedSpy.clear(); - - // insert at start - testModel.insertItem(0, "one", "1"); - QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(addedSpy.count(), 1); - QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); - QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(0)); - addedSpy.clear(); - - // insert at end - testModel.insertItem(2, "four", "4"); - QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(addedSpy.count(), 1); - QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); - QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(2)); - addedSpy.clear(); - - // insert in middle - testModel.insertItem(2, "three", "3"); - QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(addedSpy.count(), 1); - QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); - QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(2)); - addedSpy.clear(); - - delete testObject; - addedSpy.clear(); - countSpy.clear(); - delete canvas; -} - -void tst_QQuickRepeater::dataModel_removing() -{ - QQuickView *canvas = createView(); - QDeclarativeContext *ctxt = canvas->rootContext(); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - TestModel testModel; - testModel.addItem("one", "1"); - testModel.addItem("two", "2"); - testModel.addItem("three", "3"); - testModel.addItem("four", "4"); - testModel.addItem("five", "5"); - - ctxt->setContextProperty("testData", &testModel); - canvas->setSource(TEST_FILE("repeater2.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - QCOMPARE(container->childItems().count(), repeater->count()+1); - - QSignalSpy countSpy(repeater, SIGNAL(countChanged())); - QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); - - // remove at start - QQuickItem *item = repeater->itemAt(0); - QCOMPARE(item, container->childItems().at(0)); - - testModel.removeItem(0); - QVERIFY(repeater->itemAt(0) != item); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(removedSpy.count(), 1); - QCOMPARE(removedSpy.at(0).at(0).toInt(), 0); - QCOMPARE(removedSpy.at(0).at(1).value(), item); - removedSpy.clear(); - - // remove at end - int lastIndex = testModel.count()-1; - item = repeater->itemAt(lastIndex); - QCOMPARE(item, container->childItems().at(lastIndex)); - - testModel.removeItem(lastIndex); - QVERIFY(repeater->itemAt(lastIndex) != item); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(removedSpy.count(), 1); - QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex); - QCOMPARE(removedSpy.at(0).at(1).value(), item); - removedSpy.clear(); - - // remove from middle - item = repeater->itemAt(1); - QCOMPARE(item, container->childItems().at(1)); - - testModel.removeItem(1); - QVERIFY(repeater->itemAt(lastIndex) != item); - QCOMPARE(countSpy.count(), 1); countSpy.clear(); - QCOMPARE(removedSpy.count(), 1); - QCOMPARE(removedSpy.at(0).at(0).toInt(), 1); - QCOMPARE(removedSpy.at(0).at(1).value(), item); - removedSpy.clear(); - - delete testObject; - delete canvas; -} - -void tst_QQuickRepeater::dataModel_changes() -{ - QQuickView *canvas = createView(); - QDeclarativeContext *ctxt = canvas->rootContext(); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - TestModel testModel; - testModel.addItem("one", "1"); - testModel.addItem("two", "2"); - testModel.addItem("three", "3"); - - ctxt->setContextProperty("testData", &testModel); - canvas->setSource(TEST_FILE("repeater2.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - QCOMPARE(container->childItems().count(), repeater->count()+1); - - // Check that model changes are propagated - QQuickText *text = findItem(canvas->rootObject(), "myName", 1); - QVERIFY(text); - QCOMPARE(text->text(), QString("two")); - - testModel.modifyItem(1, "Item two", "_2"); - text = findItem(canvas->rootObject(), "myName", 1); - QVERIFY(text); - QCOMPARE(text->text(), QString("Item two")); - - text = findItem(canvas->rootObject(), "myNumber", 1); - QVERIFY(text); - QCOMPARE(text->text(), QString("_2")); - - delete testObject; - delete canvas; -} - -void tst_QQuickRepeater::itemModel() -{ - QQuickView *canvas = createView(); - QDeclarativeContext *ctxt = canvas->rootContext(); - TestObject *testObject = new TestObject; - ctxt->setContextProperty("testObject", testObject); - - canvas->setSource(TEST_FILE("itemlist.qml")); - qApp->processEvents(); - - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - - QCOMPARE(container->childItems().count(), 1); - - testObject->setUseModel(true); - QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); - QVERIFY(testObject->error() == false); - - QCOMPARE(container->childItems().count(), 4); - QVERIFY(qobject_cast(container->childItems().at(0))->objectName() == "item1"); - QVERIFY(qobject_cast(container->childItems().at(1))->objectName() == "item2"); - QVERIFY(qobject_cast(container->childItems().at(2))->objectName() == "item3"); - QVERIFY(container->childItems().at(3) == repeater); - - QMetaObject::invokeMethod(canvas->rootObject(), "switchModel"); - QCOMPARE(container->childItems().count(), 3); - QVERIFY(qobject_cast(container->childItems().at(0))->objectName() == "item4"); - QVERIFY(qobject_cast(container->childItems().at(1))->objectName() == "item5"); - QVERIFY(container->childItems().at(2) == repeater); - - testObject->setUseModel(false); - QCOMPARE(container->childItems().count(), 1); - - delete testObject; - delete canvas; -} - -void tst_QQuickRepeater::resetModel() -{ - QQuickView *canvas = createView(); - - QStringList dataA; - for (int i=0; i<10; i++) - dataA << QString::number(i); - - QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("testData", dataA); - canvas->setSource(TEST_FILE("repeater1.qml")); - qApp->processEvents(); - QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); - QVERIFY(repeater != 0); - QQuickItem *container = findItem(canvas->rootObject(), "container"); - QVERIFY(container != 0); - - QCOMPARE(repeater->count(), dataA.count()); - for (int i=0; icount(); i++) - QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object - - QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged())); - QSignalSpy countSpy(repeater, SIGNAL(countChanged())); - QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); - QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); - - QStringList dataB; - for (int i=0; i<20; i++) - dataB << QString::number(i); - - // reset context property - ctxt->setContextProperty("testData", dataB); - QCOMPARE(repeater->count(), dataB.count()); - - QCOMPARE(modelChangedSpy.count(), 1); - QCOMPARE(countSpy.count(), 1); - QCOMPARE(removedSpy.count(), dataA.count()); - QCOMPARE(addedSpy.count(), dataB.count()); - for (int i=0; i(), repeater->itemAt(i)); - } - modelChangedSpy.clear(); - countSpy.clear(); - removedSpy.clear(); - addedSpy.clear(); - - // reset via setModel() - repeater->setModel(dataA); - QCOMPARE(repeater->count(), dataA.count()); - - QCOMPARE(modelChangedSpy.count(), 1); - QCOMPARE(countSpy.count(), 1); - QCOMPARE(removedSpy.count(), dataB.count()); - QCOMPARE(addedSpy.count(), dataA.count()); - for (int i=0; i(), repeater->itemAt(i)); - } - - modelChangedSpy.clear(); - countSpy.clear(); - removedSpy.clear(); - addedSpy.clear(); - - delete canvas; -} - -// QTBUG-17156 -void tst_QQuickRepeater::modelChanged() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml")); - - QQuickItem *rootObject = qobject_cast(component.create()); - QVERIFY(rootObject); - QQuickRepeater *repeater = findItem(rootObject, "repeater"); - QVERIFY(repeater); - - repeater->setModel(4); - QCOMPARE(repeater->count(), 4); - QCOMPARE(repeater->property("itemsCount").toInt(), 4); - QCOMPARE(repeater->property("itemsFound").toList().count(), 4); - - repeater->setModel(10); - QCOMPARE(repeater->count(), 10); - QCOMPARE(repeater->property("itemsCount").toInt(), 10); - QCOMPARE(repeater->property("itemsFound").toList().count(), 10); - - delete rootObject; -} - -void tst_QQuickRepeater::properties() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, TEST_FILE("properties.qml")); - - QQuickItem *rootObject = qobject_cast(component.create()); - QVERIFY(rootObject); - - QQuickRepeater *repeater = findItem(rootObject, "repeater"); - QVERIFY(repeater); - - QSignalSpy modelSpy(repeater, SIGNAL(modelChanged())); - repeater->setModel(3); - QCOMPARE(modelSpy.count(),1); - repeater->setModel(3); - QCOMPARE(modelSpy.count(),1); - - QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged())); - - QDeclarativeComponent rectComponent(&engine); - rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile("")); - - repeater->setDelegate(&rectComponent); - QCOMPARE(delegateSpy.count(),1); - repeater->setDelegate(&rectComponent); - QCOMPARE(delegateSpy.count(),1); - - delete rootObject; -} - -void tst_QQuickRepeater::asynchronous() -{ - QQuickView *canvas = createView(); - canvas->show(); - QDeclarativeIncubationController controller; - canvas->engine()->setIncubationController(&controller); - - canvas->setSource(TEST_FILE("asyncloader.qml")); - - QQuickItem *rootObject = qobject_cast(canvas->rootObject()); - QVERIFY(rootObject); - - QQuickItem *container = findItem(rootObject, "container"); - QVERIFY(!container); - while (!container) { - bool b = false; - controller.incubateWhile(&b); - container = findItem(rootObject, "container"); - } - - QQuickRepeater *repeater = 0; - while (!repeater) { - bool b = false; - controller.incubateWhile(&b); - repeater = findItem(rootObject, "repeater"); - } - - // items will be created one at a time - for (int i = 0; i < 10; ++i) { - QString name("delegate"); - name += QString::number(i); - QVERIFY(findItem(container, name) == 0); - QQuickItem *item = 0; - while (!item) { - bool b = false; - controller.incubateWhile(&b); - item = findItem(container, name); - } - } - - { - bool b = true; - controller.incubateWhile(&b); - } - - // verify positioning - for (int i = 0; i < 10; ++i) { - QString name("delegate"); - name += QString::number(i); - QQuickItem *item = findItem(container, name); - QTRY_COMPARE(item->y(), i * 50.0); - } - - delete canvas; -} - -void tst_QQuickRepeater::initParent() -{ - QDeclarativeEngine engine; - QDeclarativeComponent component(&engine, TEST_FILE("initparent.qml")); - - QQuickItem *rootObject = qobject_cast(component.create()); - QVERIFY(rootObject); - - QCOMPARE(qvariant_cast(rootObject->property("parentItem")), rootObject); -} - -QQuickView *tst_QQuickRepeater::createView() -{ - QQuickView *canvas = new QQuickView(0); - canvas->setGeometry(0,0,240,320); - - return canvas; -} - -template -T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->children().count() << "children"; - for (int i = 0; i < parent->children().count(); ++i) { - QQuickItem *item = qobject_cast(parent->children().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast(item); - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -template -T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName) -{ - const QMetaObject &mo = T::staticMetaObject; - if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName)) - return static_cast(parent); - for (int i = 0; i < parent->children().count(); ++i) { - QQuickItem *child = qobject_cast(parent->children().at(i)); - if (!child) - continue; - QQuickItem *item = findItem(child, objectName); - if (item) - return static_cast(item); - } - - return 0; -} - -QTEST_MAIN(tst_QQuickRepeater) - -#include "tst_qquickrepeater.moc" diff --git a/tests/auto/declarative/qquickshadereffect/qquickshadereffect.pro b/tests/auto/declarative/qquickshadereffect/qquickshadereffect.pro deleted file mode 100644 index 540bbe1515..0000000000 --- a/tests/auto/declarative/qquickshadereffect/qquickshadereffect.pro +++ /dev/null @@ -1,8 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickshadereffect -SOURCES += tst_qquickshadereffect.cpp - -macx:CONFIG -= app_bundle - -CONFIG += parallel_test -QT += core-private gui-private declarative-private widgets testlib diff --git a/tests/auto/declarative/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/declarative/qquickshadereffect/tst_qquickshadereffect.cpp deleted file mode 100644 index 327fecf1ab..0000000000 --- a/tests/auto/declarative/qquickshadereffect/tst_qquickshadereffect.cpp +++ /dev/null @@ -1,320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include - -class TestShaderEffect : public QQuickShaderEffect -{ - Q_OBJECT - Q_PROPERTY(QVariant source READ dummyRead NOTIFY dummyChanged) - Q_PROPERTY(QVariant _0aA9zZ READ dummyRead NOTIFY dummyChanged) - Q_PROPERTY(QVariant x86 READ dummyRead NOTIFY dummyChanged) - Q_PROPERTY(QVariant X READ dummyRead NOTIFY dummyChanged) - -public: - QVariant dummyRead() const { return QVariant(); } - bool isConnected(const char *signal) const { return m_signals.contains(signal); } - -protected: - void connectNotify(const char *signal) { m_signals.append(signal); } - void disconnectNotify(const char *signal) { m_signals.removeOne(signal); } - -signals: - void dummyChanged(); - -private: - QList m_signals; -}; - -class tst_qquickshadereffect : public QObject -{ - Q_OBJECT -public: - tst_qquickshadereffect(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void lookThroughShaderCode_data(); - void lookThroughShaderCode(); - -private: - enum PresenceFlags { - VertexPresent = 0x01, - TexCoordPresent = 0x02, - MatrixPresent = 0x04, - OpacityPresent = 0x08, - PropertyPresent = 0x10 - }; - - static void installMsgHandler(); - static void uninstallMsgHandler(); - static void msgHandler(QtMsgType type, const char *msg); - static void expectWarning(const char *msg); - - static QtMsgHandler originalMsgHandler; - static QByteArray actualWarnings; - static QByteArray expectedWarnings; -}; - -QtMsgHandler tst_qquickshadereffect::originalMsgHandler = 0; -QByteArray tst_qquickshadereffect::actualWarnings; -QByteArray tst_qquickshadereffect::expectedWarnings; - -void tst_qquickshadereffect::installMsgHandler() -{ - Q_ASSERT(originalMsgHandler == 0); - originalMsgHandler = qInstallMsgHandler(msgHandler); - actualWarnings.clear(); - expectedWarnings.clear(); -} - -void tst_qquickshadereffect::uninstallMsgHandler() -{ - Q_ASSERT(originalMsgHandler != 0); - qInstallMsgHandler(originalMsgHandler); - originalMsgHandler = 0; - QCOMPARE(QString(actualWarnings), QString(expectedWarnings)); // QString for sensible output. -} - -void tst_qquickshadereffect::msgHandler(QtMsgType type, const char *msg) -{ - Q_ASSERT(originalMsgHandler != 0); - if (type == QtWarningMsg) - actualWarnings.append(msg).append('\n'); - originalMsgHandler(type, msg); -} - -void tst_qquickshadereffect::expectWarning(const char *msg) -{ - Q_ASSERT(originalMsgHandler != 0); - expectedWarnings.append(msg).append('\n'); - QTest::ignoreMessage(QtWarningMsg, msg); -} - -tst_qquickshadereffect::tst_qquickshadereffect() -{ -} - -void tst_qquickshadereffect::initTestCase() -{ -} - -void tst_qquickshadereffect::cleanupTestCase() -{ -} - -void tst_qquickshadereffect::lookThroughShaderCode_data() -{ - QTest::addColumn("vertexShader"); - QTest::addColumn("fragmentShader"); - QTest::addColumn("presenceFlags"); - - QTest::newRow("default") - << QByteArray("uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_Vertex; \n" - "attribute highp vec2 qt_MultiTexCoord0; \n" - "varying highp vec2 qt_TexCoord0; \n" - "void main() { \n" - " qt_TexCoord0 = qt_MultiTexCoord0; \n" - " gl_Position = qt_Matrix * qt_Vertex; \n" - "}") - << QByteArray("varying highp vec2 qt_TexCoord0; \n" - "uniform sampler2D source; \n" - "uniform lowp float qt_Opacity; \n" - "void main() { \n" - " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n" - "}") - << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | PropertyPresent); - - QTest::newRow("empty") - << QByteArray(" ") // one space -- if completely empty, default will be used instead. - << QByteArray(" ") - << 0; - - - QTest::newRow("inside line 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); - - 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); - - QTest::newRow("inside preprocessor directive") - << QByteArray("#define uniform\nhighp mat4 qt_Matrix;\n" - "attribute highp vec4 qt_Vertex;\n" - "#if\\\nattribute highp vec2 qt_MultiTexCoord0;") - << QByteArray("uniform int source;\n" - " # undef uniform lowp float qt_Opacity;") - << (VertexPresent | PropertyPresent); - - - QTest::newRow("line comments between") - << QByteArray("uniform//foo\nhighp//bar\nmat4//baz\nqt_Matrix;\n" - "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); - - 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); - - 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); - - QTest::newRow("newline between") - << QByteArray("uniform\nhighp\nmat4\nqt_Matrix\n;\n" - "attribute \t\r\n highp \n vec4 \n\n qt_Vertex ;\n" - " \n attribute \n highp \n vec2 \n qt_Multi\nTexCoord0 \n ;") - << QByteArray("uniform\nsampler2D\nsource;" - "uniform lowp float qt_Opacity;") - << (VertexPresent | MatrixPresent | OpacityPresent | PropertyPresent); - - - QTest::newRow("extra characters #1") - << QByteArray("funiform highp mat4 qt_Matrix;\n" - "attribute highp vec4 qt_Vertex_;\n" - "attribute highp vec2 qqt_MultiTexCoord0;") - << QByteArray("uniformm int source;\n" - "uniform4 lowp float qt_Opacity;") - << 0; - - QTest::newRow("extra characters #2") - << QByteArray("attribute phighp vec4 qt_Vertex;\n" - "attribute highpi vec2 qt_MultiTexCoord0;" - "fattribute highp vec4 qt_Vertex;\n" - "attributed highp vec2 qt_MultiTexCoord0;") - << QByteArray(" ") - << 0; - - QTest::newRow("missing characters #1") - << QByteArray("unifor highp mat4 qt_Matrix;\n" - "attribute highp vec4 qt_Vert;\n" - "attribute highp vec2 MultiTexCoord0;") - << QByteArray("niform int source;\n" - "uniform qt_Opacity;") - << 0; - - QTest::newRow("missing characters #2") - << QByteArray("attribute high vec4 qt_Vertex;\n" - "attribute ighp vec2 qt_MultiTexCoord0;" - "tribute highp vec4 qt_Vertex;\n" - "attrib highp vec2 qt_MultiTexCoord0;") - << QByteArray(" ") - << 0; - - QTest::newRow("precision") - << QByteArray("uniform mat4 qt_Matrix;\n" - "attribute kindofhighp vec4 qt_Vertex;\n" - "attribute highp qt_MultiTexCoord0;\n") - << QByteArray("uniform lowp float qt_Opacity;\n" - "uniform mediump float source;\n") - << (MatrixPresent | OpacityPresent | PropertyPresent); - - - QTest::newRow("property name #1") - << QByteArray("uniform highp vec3 _0aA9zZ;") - << QByteArray(" ") - << int(PropertyPresent); - - QTest::newRow("property name #2") - << QByteArray("uniform mediump vec2 x86;") - << QByteArray(" ") - << int(PropertyPresent); - - QTest::newRow("property name #3") - << QByteArray("uniform lowp float X;") - << QByteArray(" ") - << int(PropertyPresent); -} - -void tst_qquickshadereffect::lookThroughShaderCode() -{ - QFETCH(QByteArray, vertexShader); - QFETCH(QByteArray, fragmentShader); - QFETCH(int, presenceFlags); - - TestShaderEffect item; - QVERIFY(!item.isConnected(SIGNAL(dummyChanged()))); // Nothing connected yet. - - installMsgHandler(); - if ((presenceFlags & VertexPresent) == 0) - expectWarning("QQuickShaderEffect: Missing reference to \'qt_Vertex\'."); - if ((presenceFlags & TexCoordPresent) == 0) - expectWarning("QQuickShaderEffect: Missing reference to \'qt_MultiTexCoord0\'."); - if ((presenceFlags & MatrixPresent) == 0) - expectWarning("QQuickShaderEffect: Missing reference to \'qt_Matrix\'."); - if ((presenceFlags & OpacityPresent) == 0) - expectWarning("QQuickShaderEffect: Missing reference to \'qt_Opacity\'."); - - static_cast(item).classBegin(); - item.setVertexShader(vertexShader); - item.setFragmentShader(fragmentShader); - static_cast(item).componentComplete(); - uninstallMsgHandler(); - - // If the uniform was successfully parsed, the notify signal has been connected to an update slot. - QCOMPARE(item.isConnected(SIGNAL(dummyChanged())), (presenceFlags & PropertyPresent) != 0); -} - -QTEST_MAIN(tst_qquickshadereffect) - -#include "tst_qquickshadereffect.moc" diff --git a/tests/auto/declarative/qquickspriteimage/data/basic.qml b/tests/auto/declarative/qquickspriteimage/data/basic.qml deleted file mode 100644 index 1fcdfd99c3..0000000000 --- a/tests/auto/declarative/qquickspriteimage/data/basic.qml +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -Rectangle { - color: "black" - width: 320 - height: 320 - - SpriteImage { - objectName: "sprite" - sprites: Sprite { - name: "happy" - source: "squarefacesprite.png" - frames: 6 - duration: 120 - } - width: 160 - height: 160 - } -} diff --git a/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png b/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png deleted file mode 100644 index f9a5d5fcce..0000000000 Binary files a/tests/auto/declarative/qquickspriteimage/data/squarefacesprite.png and /dev/null differ diff --git a/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro b/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro deleted file mode 100644 index db5c45da8a..0000000000 --- a/tests/auto/declarative/qquickspriteimage/qquickspriteimage.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickspriteimage -SOURCES += tst_qquickspriteimage.cpp -macx:CONFIG -= app_bundle - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private declarative-private network testlib diff --git a/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp b/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp deleted file mode 100644 index 1b8c58b873..0000000000 --- a/tests/auto/declarative/qquickspriteimage/tst_qquickspriteimage.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include "../shared/util.h" -#include -#include - -class tst_qquickspriteimage : public QObject -{ - Q_OBJECT -public: - tst_qquickspriteimage(){} - -private slots: - void test_properties(); -}; - -void tst_qquickspriteimage::test_properties() -{ - QQuickView *canvas = new QQuickView(0); - - canvas->setSource(QUrl::fromLocalFile(TESTDATA("basic.qml"))); - canvas->show(); - QTest::qWaitForWindowShown(canvas); - - QVERIFY(canvas->rootObject()); - QQuickSpriteImage* sprite = canvas->rootObject()->findChild("sprite"); - QVERIFY(sprite); - - QVERIFY(sprite->running()); - QVERIFY(sprite->interpolate()); - - sprite->setRunning(false); - QVERIFY(!sprite->running()); - sprite->setInterpolate(false); - QVERIFY(!sprite->interpolate()); - - delete canvas; -} - -QTEST_MAIN(tst_qquickspriteimage) - -#include "tst_qquickspriteimage.moc" diff --git a/tests/auto/declarative/qquicktext/data/alignments.qml b/tests/auto/declarative/qquicktext/data/alignments.qml deleted file mode 100644 index 9798d9c736..0000000000 --- a/tests/auto/declarative/qquicktext/data/alignments.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 70; height: 70; - - property alias horizontalAlignment: t.horizontalAlignment - property alias verticalAlignment: t.verticalAlignment - property alias wrapMode: t.wrapMode - property alias running: timer.running - property string txt: "Test" - - Rectangle { - anchors.centerIn: parent - width: 40 - height: 40 - color: "green" - - Text { - id: t - - anchors.fill: parent - horizontalAlignment: Text.AlignRight - verticalAlignment: Text.AlignBottom - wrapMode: Text.WordWrap - text: top.txt - } - Timer { - id: timer - - interval: 1 - running: true - repeat: true - onTriggered: { - top.txt = top.txt + "
more " + top.txt.length; - if (top.txt.length > 50) - running = false - } - } - } -} diff --git a/tests/auto/declarative/qquicktext/data/alignments_cb.png b/tests/auto/declarative/qquicktext/data/alignments_cb.png deleted file mode 100644 index cf6199a418..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_cb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_cc.png b/tests/auto/declarative/qquicktext/data/alignments_cc.png deleted file mode 100644 index f81ccb4238..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_cc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_ct.png b/tests/auto/declarative/qquicktext/data/alignments_ct.png deleted file mode 100644 index 9ba64125d5..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_ct.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_lb.png b/tests/auto/declarative/qquicktext/data/alignments_lb.png deleted file mode 100644 index 1b50a81f3d..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_lb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_lc.png b/tests/auto/declarative/qquicktext/data/alignments_lc.png deleted file mode 100644 index f041b868f8..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_lc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_lt.png b/tests/auto/declarative/qquicktext/data/alignments_lt.png deleted file mode 100644 index c75e0d158e..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_lt.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_rb.png b/tests/auto/declarative/qquicktext/data/alignments_rb.png deleted file mode 100644 index b06a5da715..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_rb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_rc.png b/tests/auto/declarative/qquicktext/data/alignments_rc.png deleted file mode 100644 index e468857cd0..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_rc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/alignments_rt.png b/tests/auto/declarative/qquicktext/data/alignments_rt.png deleted file mode 100644 index 576715ffce..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/alignments_rt.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/embeddedImagesLocal.qml b/tests/auto/declarative/qquicktext/data/embeddedImagesLocal.qml deleted file mode 100644 index 74b2ab817a..0000000000 --- a/tests/auto/declarative/qquicktext/data/embeddedImagesLocal.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Text { - textFormat: Text.RichText - text: "" -} diff --git a/tests/auto/declarative/qquicktext/data/embeddedImagesLocalError.qml b/tests/auto/declarative/qquicktext/data/embeddedImagesLocalError.qml deleted file mode 100644 index a2f7e0c89f..0000000000 --- a/tests/auto/declarative/qquicktext/data/embeddedImagesLocalError.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Text { - textFormat: Text.RichText - text: "" -} diff --git a/tests/auto/declarative/qquicktext/data/embeddedImagesRemote.qml b/tests/auto/declarative/qquicktext/data/embeddedImagesRemote.qml deleted file mode 100644 index 702633c538..0000000000 --- a/tests/auto/declarative/qquicktext/data/embeddedImagesRemote.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Text { - textFormat: Text.RichText - text: "" -} diff --git a/tests/auto/declarative/qquicktext/data/embeddedImagesRemoteError.qml b/tests/auto/declarative/qquicktext/data/embeddedImagesRemoteError.qml deleted file mode 100644 index 5762f3e47d..0000000000 --- a/tests/auto/declarative/qquicktext/data/embeddedImagesRemoteError.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Text { - textFormat: Text.RichText - text: "" -} diff --git a/tests/auto/declarative/qquicktext/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qquicktext/data/horizontalAlignment_RightToLeft.qml deleted file mode 100644 index 5ba4d35684..0000000000 --- a/tests/auto/declarative/qquicktext/data/horizontalAlignment_RightToLeft.qml +++ /dev/null @@ -1,23 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 200; height: 70; - - property alias horizontalAlignment: text.horizontalAlignment - property string text: "اختبا" - - Rectangle { - anchors.centerIn: parent - width: 180 - height: 20 - color: "green" - - Text { - id: text - objectName: "text" - anchors.fill: parent - text: top.text - } - } -} diff --git a/tests/auto/declarative/qquicktext/data/http/exists.png b/tests/auto/declarative/qquicktext/data/http/exists.png deleted file mode 100644 index 399bd0b1d9..0000000000 Binary files a/tests/auto/declarative/qquicktext/data/http/exists.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktext/data/lineCount.qml b/tests/auto/declarative/qquicktext/data/lineCount.qml deleted file mode 100644 index b672863684..0000000000 --- a/tests/auto/declarative/qquicktext/data/lineCount.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 200 - height: 200 - - Text { - id: myText - objectName: "myText" - width: 200 - wrapMode: Text.WordWrap - maximumLineCount: undefined - text: "Testing that maximumLines, visibleLines, and totalLines works properly in the autotests. The quick brown fox jumped over the lazy anything with the letter 'g'." - } -} diff --git a/tests/auto/declarative/qquicktext/data/lineHeight.qml b/tests/auto/declarative/qquicktext/data/lineHeight.qml deleted file mode 100644 index c1f337aa05..0000000000 --- a/tests/auto/declarative/qquicktext/data/lineHeight.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 200 - height: 200 - - Text { - id: myText - objectName: "myText" - width: 200 - wrapMode: Text.WordWrap - font.pixelSize: 13 - text: "Lorem ipsum sit amet, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum." - } -} diff --git a/tests/auto/declarative/qquicktext/data/lineLayout.qml b/tests/auto/declarative/qquicktext/data/lineLayout.qml deleted file mode 100644 index cb2474791e..0000000000 --- a/tests/auto/declarative/qquicktext/data/lineLayout.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: main - width: 800; height: 600 - - property real off: 0 - - Text { - id: myText - objectName: "myText" - wrapMode: Text.WordWrap - font.pixelSize: 14 - textFormat: Text.StyledText - focus: true - - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at ante dui. Sed eu egestas est. -

Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Aenean ultricies lectus ut orci dictum quis convallis nisi ultrices. Nunc elit mi, iaculis a porttitor rutrum, venenatis malesuada nisi. Suspendisse turpis quam, euismod non imperdiet et, rutrum nec ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper tristique metus eu sodales. Integer eget risus ipsum. Quisque ut risus ut nulla tristique volutpat at sit amet nisl. Aliquam pulvinar auctor diam nec bibendum.

Quisque luctus sapien id arcu volutpat pharetra. Praesent pretium imperdiet euismod. Integer fringilla rhoncus condimentum. Quisque sit amet ornare nulla. Cras sapien augue, sagittis a dictum id, suscipit et nunc. Cras vitae augue in enim elementum venenatis sed nec risus. Sed nisi quam, mollis quis auctor ac, vestibulum in neque. Vivamus eu justo risus. Suspendisse vel mollis est. Vestibulum gravida interdum mi, in molestie neque gravida in. Donec nibh odio, mattis facilisis vulputate et, scelerisque ut felis. Sed ornare eros nec odio aliquam eu varius augue adipiscing. Vivamus sit amet massa dapibus sapien pulvinar consectetur a sit amet felis. Cras non mi id libero dictum iaculis id dignissim eros. Praesent eget enim dui, sed bibendum neque. Ut interdum nisl id leo malesuada ornare. Pellentesque id nisl eu odio volutpat posuere et at massa. Pellentesque nec lorem justo. Integer sem urna, pharetra sed sagittis vitae, condimentum ac felis. Ut vitae sapien ac tortor adipiscing pharetra. Cras tristique urna tempus ante volutpat eleifend non eu ligula. Mauris sodales nisl et lorem tristique sodales. Mauris arcu orci, vehicula semper cursus ac, dapibus ut mi." - - onLineLaidOut: { - line.width = line.number * 15 - if (line.number === 30 || line.number === 60) { - main.off = line.y - } - if (line.number >= 30) { - line.x = line.width + 30 - line.y -= main.off - } - if (line.number >= 60) { - line.x = line.width * 2 + 60 - line.height = 20 - } - } - } -} diff --git a/tests/auto/declarative/qquicktext/data/multilineelide.qml b/tests/auto/declarative/qquicktext/data/multilineelide.qml deleted file mode 100644 index 23398a84a1..0000000000 --- a/tests/auto/declarative/qquicktext/data/multilineelide.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Text { - width: 200; height: 200 - wrapMode: Text.WordWrap - elide: Text.ElideRight - maximumLineCount: 3 - text: "the quick brown fox jumped over the lazy dog the quick brown fox jumped over the lazy dog" -} - diff --git a/tests/auto/declarative/qquicktext/data/qtbug_14734.qml b/tests/auto/declarative/qquicktext/data/qtbug_14734.qml deleted file mode 100644 index e71a798421..0000000000 --- a/tests/auto/declarative/qquicktext/data/qtbug_14734.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width: 640 - height: 480 - - Text { - text: "í " - } -} diff --git a/tests/auto/declarative/qquicktext/data/rotated.qml b/tests/auto/declarative/qquicktext/data/rotated.qml deleted file mode 100644 index fecf64b249..0000000000 --- a/tests/auto/declarative/qquicktext/data/rotated.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - width : 200 - height : 100 - - Text { - objectName: "text" - x: 20 - y: 20 - height : 20 - width : 80 - text : "Something" - rotation : 30 - transformOrigin : Item.TopLeft - } -} - diff --git a/tests/auto/declarative/qquicktext/qquicktext.pro b/tests/auto/declarative/qquicktext/qquicktext.pro deleted file mode 100644 index fe69f75746..0000000000 --- a/tests/auto/declarative/qquicktext/qquicktext.pro +++ /dev/null @@ -1,17 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquicktext -macx:CONFIG -= app_bundle - -SOURCES += tst_qquicktext.cpp - -INCLUDEPATH += ../shared/ -HEADERS += ../shared/testhttpserver.h -SOURCES += ../shared/testhttpserver.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private widgets-private opengl-private network testlib diff --git a/tests/auto/declarative/qquicktext/tst_qquicktext.cpp b/tests/auto/declarative/qquicktext/tst_qquicktext.cpp deleted file mode 100644 index fb37357608..0000000000 --- a/tests/auto/declarative/qquicktext/tst_qquicktext.cpp +++ /dev/null @@ -1,1460 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include "testhttpserver.h" - -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - -class tst_qquicktext : public QObject -{ - Q_OBJECT -public: - tst_qquicktext(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void text(); - void width(); - void wrap(); - void elide(); - void multilineElide(); - void textFormat(); - - void alignments_data(); - void alignments(); - - void embeddedImages_data(); - void embeddedImages(); - - void lineCount(); - void lineHeight(); - - // ### these tests may be trivial - void horizontalAlignment(); - void horizontalAlignment_RightToLeft(); - void verticalAlignment(); - void font(); - void style(); - void color(); - void smooth(); - - // QDeclarativeFontValueType - void weight(); - void underline(); - void overline(); - void strikeout(); - void capitalization(); - void letterSpacing(); - void wordSpacing(); - - void clickLink(); - - void implicitSize_data(); - void implicitSize(); - - void lineLaidOut(); - - -private: - QStringList standard; - QStringList richText; - - QStringList horizontalAlignmentmentStrings; - QStringList verticalAlignmentmentStrings; - - QList verticalAlignmentments; - QList horizontalAlignmentments; - - QStringList styleStrings; - QList styles; - - QStringList colorStrings; - - QDeclarativeEngine engine; - - QQuickView *createView(const QString &filename); -}; -void tst_qquicktext::initTestCase() -{ -} - -void tst_qquicktext::cleanupTestCase() -{ - -} -tst_qquicktext::tst_qquicktext() -{ - standard << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox\n jumped over the lazy dog"; - - richText << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox
jumped over the lazy dog
"; - - horizontalAlignmentmentStrings << "AlignLeft" - << "AlignRight" - << "AlignHCenter"; - - verticalAlignmentmentStrings << "AlignTop" - << "AlignBottom" - << "AlignVCenter"; - - horizontalAlignmentments << Qt::AlignLeft - << Qt::AlignRight - << Qt::AlignHCenter; - - verticalAlignmentments << Qt::AlignTop - << Qt::AlignBottom - << Qt::AlignVCenter; - - styleStrings << "Normal" - << "Outline" - << "Raised" - << "Sunken"; - - styles << QQuickText::Normal - << QQuickText::Outline - << QQuickText::Raised - << QQuickText::Sunken; - - colorStrings << "aliceblue" - << "antiquewhite" - << "aqua" - << "darkkhaki" - << "darkolivegreen" - << "dimgray" - << "palevioletred" - << "lightsteelblue" - << "#000000" - << "#AAAAAA" - << "#FFFFFF" - << "#2AC05F"; - // - // need a different test to do alpha channel test - // << "#AA0011DD" - // << "#00F16B11"; - // -} - -QQuickView *tst_qquicktext::createView(const QString &filename) -{ - QQuickView *canvas = new QQuickView(0); - - canvas->setSource(QUrl::fromLocalFile(filename)); - return canvas; -} - -void tst_qquicktext::text() -{ - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->text(), QString("")); - QVERIFY(textObject->width() == 0); - - delete textObject; - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->text(), standard.at(i)); - QVERIFY(textObject->width() > 0); - - delete textObject; - } - - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QString expected = richText.at(i); - QCOMPARE(textObject->text(), expected.replace("\\\"", "\"")); - QVERIFY(textObject->width() > 0); - - delete textObject; - } -} - -void tst_qquicktext::width() -{ - // uses Font metrics to find the width for standard and document to find the width for rich - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->width(), 0.); - - delete textObject; - } - - bool requiresUnhintedMetrics = !qmlDisableDistanceField(); - - for (int i = 0; i < standard.size(); i++) - { - QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test - - QFont f; - qreal metricWidth = 0.0; - - if (requiresUnhintedMetrics) { - QString s = standard.at(i); - s.replace(QLatin1Char('\n'), QChar::LineSeparator); - - QTextLayout layout(s); - layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); - { - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - } - - layout.beginLayout(); - forever { - QTextLine line = layout.createLine(); - if (!line.isValid()) - break; - } - - layout.endLayout(); - - metricWidth = qCeil(layout.boundingRect().width()); - } else { - QFontMetricsF fm(f); - qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); - metricWidth = qCeil(metricWidth); - } - - QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->boundingRect().width() > 0); - QCOMPARE(textObject->width(), qreal(metricWidth)); - QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format - - delete textObject; - } - - for (int i = 0; i < richText.size(); i++) - { - QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test - - QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QVERIFY(textObject != 0); - - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); - QVERIFY(textPrivate != 0); - - QTextDocument *doc = textPrivate->textDocument(); - QVERIFY(doc != 0); - - QCOMPARE(int(textObject->width()), int(doc->idealWidth())); - QVERIFY(textObject->textFormat() == QQuickText::RichText); - - delete textObject; - } -} - -void tst_qquicktext::wrap() -{ - int textHeight = 0; - // for specified width and wrap set true - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - textHeight = textObject->height(); - - QVERIFY(textObject != 0); - QVERIFY(textObject->wrapMode() == QQuickText::WordWrap); - QCOMPARE(textObject->width(), 300.); - - delete textObject; - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->width(), 30.); - QVERIFY(textObject->height() > textHeight); - - int oldHeight = textObject->height(); - textObject->setWidth(100); - QVERIFY(textObject->height() < oldHeight); - - delete textObject; - } - - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->width(), 30.); - QVERIFY(textObject->height() > textHeight); - - qreal oldHeight = textObject->height(); - textObject->setWidth(100); - QVERIFY(textObject->height() < oldHeight); - - delete textObject; - } - - // richtext again with a fixed height - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->width(), 30.); - QVERIFY(textObject->implicitHeight() > textHeight); - - qreal oldHeight = textObject->implicitHeight(); - textObject->setWidth(100); - QVERIFY(textObject->implicitHeight() < oldHeight); - - delete textObject; - } -} - -void tst_qquicktext::elide() -{ - for (QQuickText::TextElideMode m = QQuickText::ElideLeft; m<=QQuickText::ElideNone; m=QQuickText::TextElideMode(int(m)+1)) { - const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"}; - QString elide = "elide: Text." + QString(elidename[int(m)]) + ";"; - - // XXX Poor coverage. - - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->elideMode(), m); - QCOMPARE(textObject->width(), 100.); - - delete textObject; - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->elideMode(), m); - QCOMPARE(textObject->width(), 100.); - - delete textObject; - } - - // richtext - does nothing - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->elideMode(), m); - QCOMPARE(textObject->width(), 100.); - - delete textObject; - } - } -} - -void tst_qquicktext::multilineElide() -{ - QQuickView *canvas = createView(TESTDATA("multilineelide.qml")); - - QQuickText *myText = qobject_cast(canvas->rootObject()); - QVERIFY(myText != 0); - - QCOMPARE(myText->lineCount(), 3); - QCOMPARE(myText->truncated(), true); - - qreal lineHeight = myText->paintedHeight() / 3.; - - // reduce size and ensure fewer lines are drawn - myText->setHeight(lineHeight * 2); - QCOMPARE(myText->lineCount(), 2); - - myText->setHeight(lineHeight); - QCOMPARE(myText->lineCount(), 1); - - myText->setHeight(5); - QCOMPARE(myText->lineCount(), 1); - - myText->setHeight(lineHeight * 3); - QCOMPARE(myText->lineCount(), 3); - - // remove max count and show all lines. - myText->setHeight(1000); - myText->resetMaximumLineCount(); - - QCOMPARE(myText->truncated(), false); - - // reduce size again - myText->setHeight(lineHeight * 2); - QCOMPARE(myText->lineCount(), 2); - QCOMPARE(myText->truncated(), true); - - // change line height - myText->setLineHeight(1.1); - QCOMPARE(myText->lineCount(), 1); - - delete canvas; -} - -void tst_qquicktext::textFormat() -{ - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::RichText); - - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); - QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->richText == true); - - delete textObject; - } - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\" }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::AutoText); - - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); - QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->styledText == true); - - delete textObject; - } - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.PlainText }", QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickText::PlainText); - - delete textObject; - } -} - - -void tst_qquicktext::alignments_data() -{ - QTest::addColumn("hAlign"); - QTest::addColumn("vAlign"); - QTest::addColumn("expectfile"); - - QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << TESTDATA("alignments_lt.png"); - QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << TESTDATA("alignments_rt.png"); - QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << TESTDATA("alignments_ct.png"); - - QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << TESTDATA("alignments_lb.png"); - QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << TESTDATA("alignments_rb.png"); - QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << TESTDATA("alignments_cb.png"); - - QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << TESTDATA("alignments_lc.png"); - QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << TESTDATA("alignments_rc.png"); - QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << TESTDATA("alignments_cc.png"); -} - - -void tst_qquicktext::alignments() -{ - QSKIP("Text alignment pixmap comparison tests will not work with scenegraph"); -#if (0)// No widgets in scenegraph - QFETCH(int, hAlign); - QFETCH(int, vAlign); - QFETCH(QString, expectfile); - - QQuickView *canvas = createView(TESTDATA("alignments.qml")); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWait(50); - QTRY_COMPARE(QApplication::activeWindow(), static_cast(canvas)); - - QObject *ob = canvas->rootObject(); - QVERIFY(ob != 0); - ob->setProperty("horizontalAlignment",hAlign); - ob->setProperty("verticalAlignment",vAlign); - QTRY_COMPARE(ob->property("running").toBool(),false); - QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32); - actual.fill(qRgb(255,255,255)); - QPainter p(&actual); - canvas->render(&p); - - QImage expect(expectfile); - if (QApplicationPrivate::graphics_system_name == "raster" || QApplicationPrivate::graphics_system_name == "") { - QCOMPARE(actual,expect); - } - delete canvas; -#endif -} - -//the alignment tests may be trivial o.oa -void tst_qquicktext::horizontalAlignment() -{ - //test one align each, and then test if two align fails. - - for (int i = 0; i < standard.size(); i++) - { - for (int j=0; j < horizontalAlignmentmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); - - delete textObject; - } - } - - for (int i = 0; i < richText.size(); i++) - { - for (int j=0; j < horizontalAlignmentmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); - - delete textObject; - } - } - -} - -void tst_qquicktext::horizontalAlignment_RightToLeft() -{ - QQuickView *canvas = createView(TESTDATA("horizontalAlignment_RightToLeft.qml")); - QQuickText *text = canvas->rootObject()->findChild("text"); - QVERIFY(text != 0); - canvas->show(); - - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text); - QVERIFY(textPrivate != 0); - - // implicit alignment should follow the reading direction of RTL text - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); - - // explicitly left aligned text - text->setHAlign(QQuickText::AlignLeft); - QCOMPARE(text->hAlign(), QQuickText::AlignLeft); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); - - // explicitly right aligned text - text->setHAlign(QQuickText::AlignRight); - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); - - // change to rich text - QString textString = text->text(); - text->setText(QString("") + textString + QString("")); - text->setTextFormat(QQuickText::RichText); - text->resetHAlign(); - - // implicitly aligned rich text should follow the reading direction of text - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); - - // explicitly left aligned rich text - text->setHAlign(QQuickText::AlignLeft); - QCOMPARE(text->hAlign(), QQuickText::AlignLeft); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignRight); - - // explicitly right aligned rich text - text->setHAlign(QQuickText::AlignRight); - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); - - text->setText(textString); - text->setTextFormat(QQuickText::PlainText); - - // explicitly center aligned - text->setHAlign(QQuickText::AlignHCenter); - QCOMPARE(text->hAlign(), QQuickText::AlignHCenter); - QCOMPARE(text->effectiveHAlign(), text->hAlign()); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2); - - // reseted alignment should go back to following the text reading direction - text->resetHAlign(); - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); - - // mirror the text item - QQuickItemPrivate::get(text)->setLayoutMirror(true); - - // mirrored implicit alignment should continue to follow the reading direction of the text - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); - - // mirrored explicitly right aligned behaves as left aligned - text->setHAlign(QQuickText::AlignRight); - QCOMPARE(text->hAlign(), QQuickText::AlignRight); - QCOMPARE(text->effectiveHAlign(), QQuickText::AlignLeft); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); - - // mirrored explicitly left aligned behaves as right aligned - text->setHAlign(QQuickText::AlignLeft); - QCOMPARE(text->hAlign(), QQuickText::AlignLeft); - QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); - - // disable mirroring - QQuickItemPrivate::get(text)->setLayoutMirror(false); - text->resetHAlign(); - - // English text should be implicitly left aligned - text->setText("Hello world!"); - QCOMPARE(text->hAlign(), QQuickText::AlignLeft); - QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); - -#ifndef Q_OS_MAC // QTBUG-18040 - // empty text with implicit alignment follows the system locale-based - // keyboard input direction from QApplication::keyboardInputDirection - text->setText(""); - QCOMPARE(text->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickText::AlignLeft : QQuickText::AlignRight); - text->setHAlign(QQuickText::AlignRight); - QCOMPARE(text->hAlign(), QQuickText::AlignRight); -#endif - - delete canvas; - -#ifndef Q_OS_MAC // QTBUG-18040 - // alignment of Text with no text set to it - QString componentStr = "import QtQuick 2.0\nText {}"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickText::AlignLeft : QQuickText::AlignRight); - delete textObject; -#endif -} - -void tst_qquicktext::verticalAlignment() -{ - //test one align each, and then test if two align fails. - - for (int i = 0; i < standard.size(); i++) - { - for (int j=0; j < verticalAlignmentmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); - - delete textObject; - } - } - - for (int i = 0; i < richText.size(); i++) - { - for (int j=0; j < verticalAlignmentmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); - - delete textObject; - } - } - -} - -void tst_qquicktext::font() -{ - //test size, then bold, then italic, then family - { - QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().pointSize(), 40); - QCOMPARE(textObject->font().bold(), false); - QCOMPARE(textObject->font().italic(), false); - - delete textObject; - } - - { - QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().pixelSize(), 40); - QCOMPARE(textObject->font().bold(), false); - QCOMPARE(textObject->font().italic(), false); - - delete textObject; - } - - { - QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().bold(), true); - QCOMPARE(textObject->font().italic(), false); - - delete textObject; - } - - { - QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().italic(), true); - QCOMPARE(textObject->font().bold(), false); - - delete textObject; - } - - { - QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().family(), QString("Helvetica")); - QCOMPARE(textObject->font().bold(), false); - QCOMPARE(textObject->font().italic(), false); - - delete textObject; - } - - { - QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->font().family(), QString("")); - - delete textObject; - } -} - -void tst_qquicktext::style() -{ - //test style - for (int i = 0; i < styles.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE((int)textObject->style(), (int)styles.at(i)); - QCOMPARE(textObject->styleColor(), QColor("white")); - - delete textObject; - } - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QRectF brPre = textObject->boundingRect(); - textObject->setStyle(QQuickText::Outline); - QRectF brPost = textObject->boundingRect(); - - QVERIFY(brPre.width() < brPost.width()); - QVERIFY(brPre.height() < brPost.height()); - - delete textObject; -} - -void tst_qquicktext::color() -{ - //test style - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); - QCOMPARE(textObject->styleColor(), QColor()); - - delete textObject; - } - - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i))); - // default color to black? - QCOMPARE(textObject->color(), QColor("black")); - - delete textObject; - } - - for (int i = 0; i < colorStrings.size(); i++) - { - for (int j = 0; j < colorStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; styleColor: \"" + colorStrings.at(j) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); - QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j))); - - delete textObject; - } - } - { - QString colorStr = "#AA001234"; - QColor testColor("#001234"); - testColor.setAlpha(170); - - QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QCOMPARE(textObject->color(), testColor); - - delete textObject; - } -} - -void tst_qquicktext::smooth() -{ - for (int i = 0; i < standard.size(); i++) - { - { - QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->smooth(), true); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->smooth(), false); - - delete textObject; - } - } - for (int i = 0; i < richText.size(); i++) - { - { - QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->smooth(), true); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->smooth(), false); - - delete textObject; - } - } -} - -void tst_qquicktext::weight() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Normal); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Bold); - - delete textObject; - } -} - -void tst_qquicktext::underline() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().underline(), false); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().underline(), true); - - delete textObject; - } -} - -void tst_qquicktext::overline() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().overline(), false); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().overline(), true); - - delete textObject; - } -} - -void tst_qquicktext::strikeout() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().strikeOut(), false); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().strikeOut(), true); - - delete textObject; - } -} - -void tst_qquicktext::capitalization() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::MixedCase); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllUppercase); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllLowercase); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::SmallCaps); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::Capitalize); - - delete textObject; - } -} - -void tst_qquicktext::letterSpacing() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().letterSpacing(), 0.0); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().letterSpacing(), -2.); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().letterSpacing(), 3.); - - delete textObject; - } -} - -void tst_qquicktext::wordSpacing() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().wordSpacing(), 0.0); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().wordSpacing(), -50.); - - delete textObject; - } - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QCOMPARE(textObject->font().wordSpacing(), 200.); - - delete textObject; - } -} - - - - -class EventSender : public QQuickItem -{ -public: - void sendEvent(QMouseEvent *event) { - if (event->type() == QEvent::MouseButtonPress) - mousePressEvent(event); - else if (event->type() == QEvent::MouseButtonRelease) - mouseReleaseEvent(event); - else - qWarning() << "Trying to send unsupported event type"; - } -}; - -class LinkTest : public QObject -{ - Q_OBJECT -public: - LinkTest() {} - - QString link; - -public slots: - void linkClicked(QString l) { link = l; } -}; - -void tst_qquicktext::clickLink() -{ - { - QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - - LinkTest test; - QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString))); - - { - QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); - static_cast(static_cast(textObject))->sendEvent(&me); - - } - - { - QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); - static_cast(static_cast(textObject))->sendEvent(&me); - - } - - - QCOMPARE(test.link, QLatin1String("http://qt.nokia.com")); - - delete textObject; - } -} - -void tst_qquicktext::embeddedImages_data() -{ - QTest::addColumn("qmlfile"); - QTest::addColumn("error"); - QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocal.qml")) << ""; - QTest::newRow("local-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml")) - << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml")).toString()+":3:1: QML Text: Cannot open: " + QUrl::fromLocalFile(TESTDATA("http/notexists.png")).toString(); - QTest::newRow("remote") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemote.qml")) << ""; - QTest::newRow("remote-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml")) - << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml")).toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found"; -} - -void tst_qquicktext::embeddedImages() -{ - // Tests QTBUG-9900 - - QFETCH(QUrl, qmlfile); - QFETCH(QString, error); - - TestHTTPServer server(14453); - server.serveDirectory(TESTDATA("http")); - - if (!error.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, error.toLatin1()); - - QDeclarativeComponent textComponent(&engine, qmlfile); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - - QTRY_COMPARE(textObject->resourcesLoading(), 0); - - QPixmap pm(TESTDATA("http/exists.png")); - if (error.isEmpty()) { - QCOMPARE(textObject->width(), double(pm.width())); - QCOMPARE(textObject->height(), double(pm.height())); - } else { - QVERIFY(16 != pm.width()); // check test is effective - QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon - QCOMPARE(textObject->height(), 16.0); - } - - delete textObject; -} - -void tst_qquicktext::lineCount() -{ - QQuickView *canvas = createView(TESTDATA("lineCount.qml")); - - QQuickText *myText = canvas->rootObject()->findChild("myText"); - QVERIFY(myText != 0); - - QVERIFY(myText->lineCount() > 1); - QVERIFY(!myText->truncated()); - QCOMPARE(myText->maximumLineCount(), INT_MAX); - - myText->setMaximumLineCount(2); - QCOMPARE(myText->lineCount(), 2); - QCOMPARE(myText->truncated(), true); - QCOMPARE(myText->maximumLineCount(), 2); - - myText->resetMaximumLineCount(); - QCOMPARE(myText->maximumLineCount(), INT_MAX); - QCOMPARE(myText->truncated(), false); - - myText->setElideMode(QQuickText::ElideRight); - myText->setMaximumLineCount(2); - QCOMPARE(myText->lineCount(), 2); - QCOMPARE(myText->truncated(), true); - QCOMPARE(myText->maximumLineCount(), 2); - - delete canvas; -} - -void tst_qquicktext::lineHeight() -{ - QQuickView *canvas = createView(TESTDATA("lineHeight.qml")); - - QQuickText *myText = canvas->rootObject()->findChild("myText"); - QVERIFY(myText != 0); - - QVERIFY(myText->lineHeight() == 1); - QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight); - - qreal h = myText->height(); - myText->setLineHeight(1.5); - QVERIFY(myText->height() == qCeil(h * 1.5)); - - myText->setLineHeightMode(QQuickText::FixedHeight); - myText->setLineHeight(20); - QCOMPARE(myText->height(), myText->lineCount() * 20.0); - - myText->setText("Lorem ipsum sit amet, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum."); - myText->setLineHeightMode(QQuickText::ProportionalHeight); - myText->setLineHeight(1.0); - - qreal h2 = myText->height(); - myText->setLineHeight(2.0); - QVERIFY(myText->height() == h2 * 2.0); - - myText->setLineHeightMode(QQuickText::FixedHeight); - myText->setLineHeight(10); - QCOMPARE(myText->height(), myText->lineCount() * 10.0); - - delete canvas; -} - -void tst_qquicktext::implicitSize_data() -{ - QTest::addColumn("text"); - QTest::addColumn("wrap"); - QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap"; - QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap"; - QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap"; - QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap"; -} - -void tst_qquicktext::implicitSize() -{ - QFETCH(QString, text); - QFETCH(QString, wrap); - QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickText *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject->width() < textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); - - textObject->resetWidth(); - QVERIFY(textObject->width() == textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); - - delete textObject; -} - -void tst_qquicktext::lineLaidOut() -{ - QQuickView *canvas = createView(TESTDATA("lineLayout.qml")); - - QQuickText *myText = canvas->rootObject()->findChild("myText"); - QVERIFY(myText != 0); - - QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); - QVERIFY(textPrivate != 0); - - QTextDocument *doc = textPrivate->textDocument(); - QVERIFY(doc == 0); - - QVERIFY(myText->lineCount() == textPrivate->linesRects.count()); - - for (int i = 0; i < textPrivate->linesRects.count(); ++i) { - QRectF r = textPrivate->linesRects.at(i); - QVERIFY(r.width() == i * 15); - if (i >= 30) - QVERIFY(r.x() == r.width() + 30); - if (i >= 60) { - QVERIFY(r.x() == r.width() * 2 + 60); - QVERIFY(r.height() == 20); - } - } -} - -QTEST_MAIN(tst_qquicktext) - -#include "tst_qquicktext.moc" diff --git a/tests/auto/declarative/qquicktextedit/data/CursorRect.qml b/tests/auto/declarative/qquicktextedit/data/CursorRect.qml deleted file mode 100644 index cae3e63b72..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/CursorRect.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - objectName: "myEdit" - width: 50 - text: "This is a long piece of text" -} diff --git a/tests/auto/declarative/qquicktextedit/data/alignments.qml b/tests/auto/declarative/qquicktextedit/data/alignments.qml deleted file mode 100644 index 7d365da8cb..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/alignments.qml +++ /dev/null @@ -1,41 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 70; height: 70; - - property alias horizontalAlignment: t.horizontalAlignment - property alias verticalAlignment: t.verticalAlignment - property alias wrapMode: t.wrapMode - property alias running: timer.running - property string txt: "Test" - - Rectangle { - anchors.centerIn: parent - width: 40 - height: 40 - color: "green" - - TextEdit { - id: t - - anchors.fill: parent - horizontalAlignment: TextEdit.AlignRight - verticalAlignment: TextEdit.AlignBottom - wrapMode: TextEdit.WordWrap - text: top.txt - } - Timer { - id: timer - - interval: 1 - running: true - repeat: true - onTriggered: { - top.txt = top.txt + "
more " + top.txt.length; - if (top.txt.length > 50) - running = false - } - } - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_cb.png b/tests/auto/declarative/qquicktextedit/data/alignments_cb.png deleted file mode 100644 index 99de2192de..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_cb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_cc.png b/tests/auto/declarative/qquicktextedit/data/alignments_cc.png deleted file mode 100644 index cb85251180..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_cc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_ct.png b/tests/auto/declarative/qquicktextedit/data/alignments_ct.png deleted file mode 100644 index ddca549c82..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_ct.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_lb.png b/tests/auto/declarative/qquicktextedit/data/alignments_lb.png deleted file mode 100644 index 1b50a81f3d..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_lb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_lc.png b/tests/auto/declarative/qquicktextedit/data/alignments_lc.png deleted file mode 100644 index f041b868f8..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_lc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_lt.png b/tests/auto/declarative/qquicktextedit/data/alignments_lt.png deleted file mode 100644 index c75e0d158e..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_lt.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_rb.png b/tests/auto/declarative/qquicktextedit/data/alignments_rb.png deleted file mode 100644 index b06a5da715..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_rb.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_rc.png b/tests/auto/declarative/qquicktextedit/data/alignments_rc.png deleted file mode 100644 index e468857cd0..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_rc.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/alignments_rt.png b/tests/auto/declarative/qquicktextedit/data/alignments_rt.png deleted file mode 100644 index 576715ffce..0000000000 Binary files a/tests/auto/declarative/qquicktextedit/data/alignments_rt.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextedit/data/cursorTest.qml b/tests/auto/declarative/qquicktextedit/data/cursorTest.qml deleted file mode 100644 index 7bfc869403..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/cursorTest.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Rectangle { width: 300; height: 300; color: "white" - property string contextualProperty: "Hello" - TextEdit { text: "Hello world!"; id: textEditObject; objectName: "textEditObject" - resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ] - cursorDelegate: cursor - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/cursorVisible.qml b/tests/auto/declarative/qquicktextedit/data/cursorVisible.qml deleted file mode 100644 index 49e9386947..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/cursorVisible.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 100 - height: 20 -} diff --git a/tests/auto/declarative/qquicktextedit/data/geometrySignals.qml b/tests/auto/declarative/qquicktextedit/data/geometrySignals.qml deleted file mode 100644 index 3dbe61c74b..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/geometrySignals.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 400; height: 500; - property int bindingWidth: text.width - property int bindingHeight: text.height - - TextInput { - id: text - anchors.fill: parent - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qquicktextedit/data/horizontalAlignment_RightToLeft.qml deleted file mode 100644 index 4cd92367ec..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/horizontalAlignment_RightToLeft.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 200; height: 70; - - property alias horizontalAlignment: text.horizontalAlignment - property string text: "اختبا" - - Rectangle { - anchors.centerIn: parent - width: 200 - height: 20 - color: "green" - - TextEdit { - id: text - objectName: "text" - anchors.fill: parent - text: top.text - focus: true - } - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/ErrItem.qml b/tests/auto/declarative/qquicktextedit/data/http/ErrItem.qml deleted file mode 100644 index 68c0e0c093..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/ErrItem.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -Item{ - Fungus{ - palatable: false; - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/NormItem.qml b/tests/auto/declarative/qquicktextedit/data/http/NormItem.qml deleted file mode 100644 index 2e4c1ed440..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/NormItem.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Item { - objectName: "delegateOkay" - Rectangle { } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTest.qml b/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTest.qml deleted file mode 100644 index be4526e22b..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTest.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Rectangle { width: 300; height: 300; color: "white" - resources: [ - Component { id:cursorFail; FailItem { objectName: "delegateFail" } }, - Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, - Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } }, - Component { id:cursorErr; ErrItem { objectName: "delegateErrorA" } } - ] - TextEdit { - cursorDelegate: cursorFail - } - TextEdit { - cursorDelegate: cursorWait - } - TextEdit { - cursorDelegate: cursorNorm - } - TextEdit { - cursorDelegate: cursorErr - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail1.qml b/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail1.qml deleted file mode 100644 index 1d7763f913..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail1.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { width: 300; height: 300; color: "white" - resources: [ - Component { id:cursorFail; FailItem { objectName: "delegateFail" } }, - Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, - Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } } - ] - TextEdit { - cursorDelegate: cursorFail - } - TextEdit { - cursorDelegate: cursorWait - } - TextEdit { - cursorDelegate: cursorNorm - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail2.qml b/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail2.qml deleted file mode 100644 index c82ec02e68..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestFail2.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { width: 300; height: 300; color: "white" - resources: [ - Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, - Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } }, - Component { id:cursorErr; ErrItem { objectName: "delegateErrorA" } } - ] - TextEdit { - cursorDelegate: cursorWait - } - TextEdit { - cursorDelegate: cursorNorm - } - TextEdit { - cursorDelegate: cursorErr - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestPass.qml b/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestPass.qml deleted file mode 100644 index 96d582c95d..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/cursorHttpTestPass.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -Rectangle { width: 300; height: 300; color: "white" - resources: [ - Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, - Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } } - ] - TextEdit { - cursorDelegate: cursorWait - text: "Hello" - } - TextEdit { - objectName: "textEditObject" - cursorDelegate: cursorNorm - focus: true; - text: "Hello" - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/http/qmldir b/tests/auto/declarative/qquicktextedit/data/http/qmldir deleted file mode 100644 index 886e6ffec0..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/http/qmldir +++ /dev/null @@ -1,4 +0,0 @@ -ErrItem ErrItem.qml -NormItem NormItem.qml -FailItem FailItem.qml -WaitItem WaitItem.qml diff --git a/tests/auto/declarative/qquicktextedit/data/httpfail/FailItem.qml b/tests/auto/declarative/qquicktextedit/data/httpfail/FailItem.qml deleted file mode 100644 index 8161843479..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/httpfail/FailItem.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Item { - Rectangle { } -} diff --git a/tests/auto/declarative/qquicktextedit/data/httpslow/WaitItem.qml b/tests/auto/declarative/qquicktextedit/data/httpslow/WaitItem.qml deleted file mode 100644 index 8161843479..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/httpslow/WaitItem.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Item { - Rectangle { } -} diff --git a/tests/auto/declarative/qquicktextedit/data/inputContext.qml b/tests/auto/declarative/qquicktextedit/data/inputContext.qml deleted file mode 100644 index a37c77e3bf..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/inputContext.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - width: 200 - text: "supercalifra" - focus: true -} diff --git a/tests/auto/declarative/qquicktextedit/data/inputMethodEvent.qml b/tests/auto/declarative/qquicktextedit/data/inputMethodEvent.qml deleted file mode 100644 index e3f629ce3e..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/inputMethodEvent.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true -} diff --git a/tests/auto/declarative/qquicktextedit/data/inputmethodhints.qml b/tests/auto/declarative/qquicktextedit/data/inputmethodhints.qml deleted file mode 100644 index dec3b978e7..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/inputmethodhints.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - text: "Hello world!" - inputMethodHints: Qt.ImhNoPredictiveText -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselection_default.qml b/tests/auto/declarative/qquicktextedit/data/mouseselection_default.qml deleted file mode 100644 index ac32f4ced7..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselection_default.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: false -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselection_false.qml b/tests/auto/declarative/qquicktextedit/data/mouseselection_false.qml deleted file mode 100644 index ac32f4ced7..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselection_false.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: false -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselection_false_words.qml b/tests/auto/declarative/qquicktextedit/data/mouseselection_false_words.qml deleted file mode 100644 index 86aea46a85..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselection_false_words.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: false - mouseSelectionMode: TextEdit.SelectWords -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselection_true.qml b/tests/auto/declarative/qquicktextedit/data/mouseselection_true.qml deleted file mode 100644 index 7c7cb0b6fc..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselection_true.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselection_true_words.qml b/tests/auto/declarative/qquicktextedit/data/mouseselection_true_words.qml deleted file mode 100644 index c356999220..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselection_true_words.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true - mouseSelectionMode: TextEdit.SelectWords -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_characters.qml deleted file mode 100644 index c1fe42fd57..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_characters.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true - mouseSelectionMode: TextEdit.SelectCharacters -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_default.qml b/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_default.qml deleted file mode 100644 index 7c7cb0b6fc..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_default.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true -} diff --git a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_words.qml b/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_words.qml deleted file mode 100644 index 0a372bbf83..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/mouseselectionmode_words.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true - mouseSelectionMode: TextEdit.SelectWords -} diff --git a/tests/auto/declarative/qquicktextedit/data/navigation.qml b/tests/auto/declarative/qquicktextedit/data/navigation.qml deleted file mode 100644 index 0201c62b3c..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/navigation.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property variant myInput: input - - width: 800; height: 600; color: "blue" - - Item { - id: firstItem; - KeyNavigation.right: input - } - - TextEdit { id: input; focus: true - KeyNavigation.left: firstItem - KeyNavigation.right: lastItem - KeyNavigation.up: firstItem - KeyNavigation.down: lastItem - text: "a" - } - Item { - id: lastItem - KeyNavigation.left: input - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/openInputPanel.qml b/tests/auto/declarative/qquicktextedit/data/openInputPanel.qml deleted file mode 100644 index d3aecf21be..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/openInputPanel.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - width: 100; height: 100 - text: "Hello world" - focus: false -} diff --git a/tests/auto/declarative/qquicktextedit/data/positionAt.qml b/tests/auto/declarative/qquicktextedit/data/positionAt.qml deleted file mode 100644 index 19093281fe..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/positionAt.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -TextEdit { - focus: true - objectName: "myInput" - width: 50 - height: 25 - text: "This is\n a long piece of text" -} diff --git a/tests/auto/declarative/qquicktextedit/data/qtbug-22058.qml b/tests/auto/declarative/qquicktextedit/data/qtbug-22058.qml deleted file mode 100644 index 8ad1514fbf..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/qtbug-22058.qml +++ /dev/null @@ -1,39 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property variant inputField: textedit - height: 200 - width: 200 - - Rectangle { - height: parent.height /2 - width: parent.width - color: "transparent" - border.color: "black" - border.width: 4 - Text { - anchors.centerIn: parent - height: parent.height * .95 - width: parent.width * .95 - text: textedit.text - } - } - - Rectangle { - height: parent.height /2 - width: parent.width - color: "transparent" - border.color: "black" - border.width: 4 - anchors.bottom: parent.bottom - TextEdit { - id: textedit - anchors.centerIn: parent - height: parent.height * .95 - width: parent.width * .95 - focus: true - wrapMode: TextEdit.WordWrap - text: "" - } - } -} diff --git a/tests/auto/declarative/qquicktextedit/data/readOnly.qml b/tests/auto/declarative/qquicktextedit/data/readOnly.qml deleted file mode 100644 index 085adba5fb..0000000000 --- a/tests/auto/declarative/qquicktextedit/data/readOnly.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property variant myInput: input - - width: 800; height: 600; color: "blue" - - TextEdit { id: input; focus: true - readOnly: true - text: "I am the very model of a modern major general.\n" - } -} diff --git a/tests/auto/declarative/qquicktextedit/qquicktextedit.pro b/tests/auto/declarative/qquicktextedit/qquicktextedit.pro deleted file mode 100644 index ae2233dafc..0000000000 --- a/tests/auto/declarative/qquicktextedit/qquicktextedit.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquicktextedit -macx:CONFIG -= app_bundle - -SOURCES += tst_qquicktextedit.cpp ../shared/testhttpserver.cpp -HEADERS += ../shared/testhttpserver.h - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -QT += core-private gui-private v8-private declarative-private opengl-private network widgets-private testlib diff --git a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp deleted file mode 100644 index 6bcad83c52..0000000000 --- a/tests/auto/declarative/qquicktextedit/tst_qquicktextedit.cpp +++ /dev/null @@ -1,3555 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include "../shared/testhttpserver.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include -#include - -#ifdef Q_OS_MAC -#include -#endif - - -Q_DECLARE_METATYPE(QQuickTextEdit::SelectionMode) -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - -QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) -{ - // XXX This will be replaced by some clever persistent platform image store. - QString persistent_dir = TESTDATA(""); - QString arch = "unknown-architecture"; // QTest needs to help with this. - - QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; - - if (!QFile::exists(expectfile)) { - actual.save(expectfile); - qWarning() << "created" << expectfile; - } - - return expectfile; -} - -typedef QPair Key; - -class tst_qquicktextedit : public QObject - -{ - Q_OBJECT -public: - tst_qquicktextedit(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void text(); - void width(); - void wrap(); - void textFormat(); - void alignments(); - void alignments_data(); - - // ### these tests may be trivial - void hAlign(); - void hAlign_RightToLeft(); - void vAlign(); - void font(); - void color(); - void textMargin(); - void persistentSelection(); - void focusOnPress(); - void selection(); - void isRightToLeft_data(); - void isRightToLeft(); - void keySelection(); - void moveCursorSelection_data(); - void moveCursorSelection(); - void moveCursorSelectionSequence_data(); - void moveCursorSelectionSequence(); - void mouseSelection_data(); - void mouseSelection(); - void mouseSelectionMode_data(); - void mouseSelectionMode(); - void dragMouseSelection(); - void inputMethodHints(); - - void positionAt(); - - void cursorDelegate(); - void cursorVisible(); - void delegateLoading_data(); - void delegateLoading(); - void navigation(); - void readOnly(); - void copyAndPaste(); - void canPaste(); - void canPasteEmpty(); - void textInput(); - void openInputPanel(); - void geometrySignals(); - void pastingRichText_QTBUG_14003(); - void implicitSize_data(); - void implicitSize(); - void testQtQuick11Attributes(); - void testQtQuick11Attributes_data(); - - void preeditCursorRectangle(); - void inputMethodComposing(); - void cursorRectangleSize(); - - void getText_data(); - void getText(); - void getFormattedText_data(); - void getFormattedText(); - void insert_data(); - void insert(); - void remove_data(); - void remove(); - - void keySequence_data(); - void keySequence(); - - void undo_data(); - void undo(); - void redo_data(); - void redo(); - void undo_keypressevents_data(); - void undo_keypressevents(); - - void emptytags_QTBUG_22058(); - -private: - void simulateKeys(QWindow *window, const QList &keys); - void simulateKeys(QWindow *window, const QKeySequence &sequence); - - void simulateKey(QQuickView *, int key, Qt::KeyboardModifiers modifiers = 0); - - QStringList standard; - QStringList richText; - - QStringList hAlignmentStrings; - QStringList vAlignmentStrings; - - QList vAlignments; - QList hAlignments; - - QStringList colorStrings; - - QDeclarativeEngine engine; -}; - -typedef QList IntList; -Q_DECLARE_METATYPE(IntList) - -typedef QList KeyList; -Q_DECLARE_METATYPE(KeyList) - -Q_DECLARE_METATYPE(QQuickTextEdit::TextFormat) - -void tst_qquicktextedit::simulateKeys(QWindow *window, const QList &keys) -{ - for (int i = 0; i < keys.count(); ++i) { - const int key = keys.at(i).first; - const int modifiers = key & Qt::KeyboardModifierMask; - const QString text = !keys.at(i).second.isNull() ? QString(keys.at(i).second) : QString(); - - QKeyEvent press(QEvent::KeyPress, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); - QKeyEvent release(QEvent::KeyRelease, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); - - QGuiApplication::sendEvent(window, &press); - QGuiApplication::sendEvent(window, &release); - } -} - -void tst_qquicktextedit::simulateKeys(QWindow *window, const QKeySequence &sequence) -{ - for (uint i = 0; i < sequence.count(); ++i) { - const int key = sequence[i]; - const int modifiers = key & Qt::KeyboardModifierMask; - - QTest::keyClick(window, Qt::Key(key & ~modifiers), Qt::KeyboardModifiers(modifiers)); - } -} - -QList &operator <<(QList &keys, const QKeySequence &sequence) -{ - for (uint i = 0; i < sequence.count(); ++i) - keys << Key(sequence[i], QChar()); - return keys; -} - -template QList &operator <<(QList &keys, const char (&characters)[N]) -{ - for (int i = 0; i < N - 1; ++i) { - int key = QTest::asciiToKey(characters[i]); - QChar character = QLatin1Char(characters[i]); - keys << Key(key, character); - } - return keys; -} - -QList &operator <<(QList &keys, Qt::Key key) -{ - keys << Key(key, QChar()); - return keys; -} - - -void tst_qquicktextedit::initTestCase() -{ -} - -void tst_qquicktextedit::cleanupTestCase() -{ - -} -tst_qquicktextedit::tst_qquicktextedit() -{ - standard << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox\n jumped over the lazy dog" - << "Hello, world!" - << "!dlrow ,olleH"; - - richText << "the quick brown fox jumped over the lazy dog" - << "the quick brown fox
jumped over the lazy dog
"; - - hAlignmentStrings << "AlignLeft" - << "AlignRight" - << "AlignHCenter"; - - vAlignmentStrings << "AlignTop" - << "AlignBottom" - << "AlignVCenter"; - - hAlignments << Qt::AlignLeft - << Qt::AlignRight - << Qt::AlignHCenter; - - vAlignments << Qt::AlignTop - << Qt::AlignBottom - << Qt::AlignVCenter; - - colorStrings << "aliceblue" - << "antiquewhite" - << "aqua" - << "darkkhaki" - << "darkolivegreen" - << "dimgray" - << "palevioletred" - << "lightsteelblue" - << "#000000" - << "#AAAAAA" - << "#FFFFFF" - << "#2AC05F"; - // - // need a different test to do alpha channel test - // << "#AA0011DD" - // << "#00F16B11"; - // -} - -void tst_qquicktextedit::text() -{ - { - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\" }", QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->text(), QString("")); - QCOMPARE(textEditObject->length(), 0); - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->text(), standard.at(i)); - QCOMPARE(textEditObject->length(), standard.at(i).length()); - } - - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QString actual = textEditObject->text(); - QString expected = richText.at(i); - actual.replace(QRegExp(".*]*>"),""); - actual.replace(QRegExp("(<[^>]*>)+"),"<>"); - expected.replace(QRegExp("(<[^>]*>)+"),"<>"); - QCOMPARE(actual.simplified(),expected.simplified()); - - expected.replace("<>", " "); - QCOMPARE(textEditObject->length(), expected.simplified().length()); - } -} - -void tst_qquicktextedit::width() -{ - // uses Font metrics to find the width for standard and document to find the width for rich - { - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\" }", QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), 0.0); - } - - bool requiresUnhintedMetrics = !qmlDisableDistanceField(); - - for (int i = 0; i < standard.size(); i++) - { - QFont f; - qreal metricWidth = 0.0; - - if (requiresUnhintedMetrics) { - QString s = standard.at(i); - s.replace(QLatin1Char('\n'), QChar::LineSeparator); - - QTextLayout layout(s); - layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); - { - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - } - - layout.beginLayout(); - forever { - QTextLine line = layout.createLine(); - if (!line.isValid()) - break; - } - - layout.endLayout(); - - metricWidth = ceil(layout.boundingRect().width()); - } else { - QFontMetricsF fm(f); - metricWidth = fm.size(Qt::TextExpandTabs | Qt::TextShowMnemonic, standard.at(i)).width(); - metricWidth = ceil(metricWidth); - } - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(metricWidth)); - } - - for (int i = 0; i < richText.size(); i++) - { - QTextDocument document; - document.setHtml(richText.at(i)); - document.setDocumentMargin(0); - if (requiresUnhintedMetrics) - document.setUseDesignMetrics(true); - - int documentWidth = ceil(document.idealWidth()); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(documentWidth)); - } -} - -void tst_qquicktextedit::wrap() -{ - // for specified width and wrap set true - { - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), 300.); - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), 300.); - } - - for (int i = 0; i < richText.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), 300.); - } - -} - -void tst_qquicktextedit::textFormat() -{ - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile("")); - QQuickTextEdit *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickTextEdit::RichText); - } - { - QDeclarativeComponent textComponent(&engine); - textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.PlainText }", QUrl::fromLocalFile("")); - QQuickTextEdit *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject != 0); - QVERIFY(textObject->textFormat() == QQuickTextEdit::PlainText); - } -} - -void tst_qquicktextedit::alignments_data() -{ - QTest::addColumn("hAlign"); - QTest::addColumn("vAlign"); - QTest::addColumn("expectfile"); - - QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt"; - QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt"; - QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct"; - - QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb"; - QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb"; - QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb"; - - QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc"; - QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc"; - QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc"; -} - - -void tst_qquicktextedit::alignments() -{ - QSKIP("Image comparison of text is almost guaranteed to fail during development"); - - QFETCH(int, hAlign); - QFETCH(int, vAlign); - QFETCH(QString, expectfile); - - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("alignments.qml"))); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QObject *ob = canvas.rootObject(); - QVERIFY(ob != 0); - ob->setProperty("horizontalAlignment",hAlign); - ob->setProperty("verticalAlignment",vAlign); - QTRY_COMPARE(ob->property("running").toBool(),false); - QImage actual = canvas.grabFrameBuffer(); - - expectfile = createExpectedFileIfNotFound(expectfile, actual); - - QImage expect(expectfile); - - QCOMPARE(actual,expect); -} - - -//the alignment tests may be trivial o.oa -void tst_qquicktextedit::hAlign() -{ - //test one align each, and then test if two align fails. - - for (int i = 0; i < standard.size(); i++) - { - for (int j=0; j < hAlignmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); - } - } - - for (int i = 0; i < richText.size(); i++) - { - for (int j=0; j < hAlignmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); - } - } - -} - -void tst_qquicktextedit::hAlign_RightToLeft() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml"))); - QQuickTextEdit *textEdit = canvas.rootObject()->findChild("text"); - QVERIFY(textEdit != 0); - canvas.show(); - - const QString rtlText = textEdit->text(); - - // implicit alignment should follow the reading direction of text - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // explicitly left aligned - textEdit->setHAlign(QQuickTextEdit::AlignLeft); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); - QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); - - // explicitly right aligned - textEdit->setHAlign(QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - QString textString = textEdit->text(); - textEdit->setText(QString("") + textString + QString("")); - textEdit->resetHAlign(); - - // implicitly aligned rich text should follow the reading direction of RTL text - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // explicitly left aligned rich text - textEdit->setHAlign(QQuickTextEdit::AlignLeft); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); - QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); - QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); - - // explicitly right aligned rich text - textEdit->setHAlign(QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - textEdit->setText(textString); - - // explicitly center aligned - textEdit->setHAlign(QQuickTextEdit::AlignHCenter); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignHCenter); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // reseted alignment should go back to following the text reading direction - textEdit->resetHAlign(); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // mirror the text item - QQuickItemPrivate::get(textEdit)->setLayoutMirror(true); - - // mirrored implicit alignment should continue to follow the reading direction of the text - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // mirrored explicitly right aligned behaves as left aligned - textEdit->setHAlign(QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignLeft); - QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); - - // mirrored explicitly left aligned behaves as right aligned - textEdit->setHAlign(QQuickTextEdit::AlignLeft); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); - QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - - // disable mirroring - QQuickItemPrivate::get(textEdit)->setLayoutMirror(false); - textEdit->resetHAlign(); - - // English text should be implicitly left aligned - textEdit->setText("Hello world!"); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); - QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); - - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - textEdit->setText(QString()); - { QInputMethodEvent ev(rtlText, QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - { QInputMethodEvent ev("Hello world!", QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); - - // Clear pre-edit text. TextEdit should maybe do this itself on setText, but that may be - // redundant as an actual input method may take care of it. - { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - -#ifndef Q_OS_MAC // QTBUG-18040 - // empty text with implicit alignment follows the system locale-based - // keyboard input direction from QGuiApplication::keyboardInputDirection - textEdit->setText(""); - QCOMPARE(textEdit->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight); - if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight) - QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); - else - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); - textEdit->setHAlign(QQuickTextEdit::AlignRight); - QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); - QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); -#endif - -#ifndef Q_OS_MAC // QTBUG-18040 - // alignment of TextEdit with no text set to it - QString componentStr = "import QtQuick 2.0\nTextEdit {}"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickTextEdit *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight); - delete textObject; -#endif -} - -void tst_qquicktextedit::vAlign() -{ - //test one align each, and then test if two align fails. - - for (int i = 0; i < standard.size(); i++) - { - for (int j=0; j < vAlignmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); - } - } - - for (int i = 0; i < richText.size(); i++) - { - for (int j=0; j < vAlignmentStrings.size(); j++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); - } - } - -} - -void tst_qquicktextedit::font() -{ - //test size, then bold, then italic, then family - { - QString componentStr = "import QtQuick 2.0\nTextEdit { font.pointSize: 40; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->font().pointSize(), 40); - QCOMPARE(textEditObject->font().bold(), false); - QCOMPARE(textEditObject->font().italic(), false); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { font.bold: true; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->font().bold(), true); - QCOMPARE(textEditObject->font().italic(), false); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { font.italic: true; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->font().italic(), true); - QCOMPARE(textEditObject->font().bold(), false); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->font().family(), QString("Helvetica")); - QCOMPARE(textEditObject->font().bold(), false); - QCOMPARE(textEditObject->font().italic(), false); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->font().family(), QString("")); - } -} - -void tst_qquicktextedit::color() -{ - //test initial color - { - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QQuickTextEditPrivate *textEditPrivate = static_cast(QQuickItemPrivate::get(textEditObject)); - - QVERIFY(textEditObject); - QVERIFY(textEditPrivate); - QVERIFY(textEditPrivate->control); - - QPalette pal = textEditPrivate->control->palette(); - QCOMPARE(textEditPrivate->color, QColor("black")); - QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text)); - } - //test normal - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i)); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i))); - } - - //test selection - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i))); - } - - //test selected text - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextEdit { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i))); - } - - { - QString colorStr = "#AA001234"; - QColor testColor("#001234"); - testColor.setAlpha(170); - - QString componentStr = "import QtQuick 2.0\nTextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->color(), testColor); - } -} - -void tst_qquicktextedit::textMargin() -{ - for (qreal i=0; i<=10; i+=0.3) { - QString componentStr = "import QtQuick 2.0\nTextEdit { textMargin: " + QString::number(i) + "; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->textMargin(), i); - } -} - -void tst_qquicktextedit::persistentSelection() -{ - { - QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: true; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->persistentSelection(), true); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: false; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->persistentSelection(), false); - } -} - -void tst_qquicktextedit::focusOnPress() -{ - { - QString componentStr = "import QtQuick 2.0\nTextEdit { activeFocusOnPress: true; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->focusOnPress(), true); - } - - { - QString componentStr = "import QtQuick 2.0\nTextEdit { activeFocusOnPress: false; text: \"Hello World\" }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->focusOnPress(), false); - } -} - -void tst_qquicktextedit::selection() -{ - QString testStr = standard[0];//TODO: What should happen for multiline/rich text? - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); - QVERIFY(textEditObject != 0); - - - //Test selection follows cursor - for (int i=0; i<= testStr.size(); i++) { - textEditObject->setCursorPosition(i); - QCOMPARE(textEditObject->cursorPosition(), i); - QCOMPARE(textEditObject->selectionStart(), i); - QCOMPARE(textEditObject->selectionEnd(), i); - QVERIFY(textEditObject->selectedText().isNull()); - } - - textEditObject->setCursorPosition(0); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); - QVERIFY(textEditObject->selectedText().isNull()); - - // Verify invalid positions are ignored. - textEditObject->setCursorPosition(-1); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); - QVERIFY(textEditObject->selectedText().isNull()); - - textEditObject->setCursorPosition(textEditObject->text().count()+1); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); - QVERIFY(textEditObject->selectedText().isNull()); - - //Test selection - for (int i=0; i<= testStr.size(); i++) { - textEditObject->select(0,i); - QCOMPARE(testStr.mid(0,i), textEditObject->selectedText()); - } - for (int i=0; i<= testStr.size(); i++) { - textEditObject->select(i,testStr.size()); - QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText()); - } - - textEditObject->setCursorPosition(0); - QVERIFY(textEditObject->cursorPosition() == 0); - QVERIFY(textEditObject->selectionStart() == 0); - QVERIFY(textEditObject->selectionEnd() == 0); - QVERIFY(textEditObject->selectedText().isNull()); - - //Test Error Ignoring behaviour - textEditObject->setCursorPosition(0); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(-10,0); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(100,101); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(0,-10); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(0,100); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(0,10); - QVERIFY(textEditObject->selectedText().size() == 10); - textEditObject->select(-10,0); - QVERIFY(textEditObject->selectedText().size() == 10); - textEditObject->select(100,101); - QVERIFY(textEditObject->selectedText().size() == 10); - textEditObject->select(0,-10); - QVERIFY(textEditObject->selectedText().size() == 10); - textEditObject->select(0,100); - QVERIFY(textEditObject->selectedText().size() == 10); - - textEditObject->deselect(); - QVERIFY(textEditObject->selectedText().isNull()); - textEditObject->select(0,10); - QVERIFY(textEditObject->selectedText().size() == 10); - textEditObject->deselect(); - QVERIFY(textEditObject->selectedText().isNull()); -} - -void tst_qquicktextedit::isRightToLeft_data() -{ - QTest::addColumn("text"); - QTest::addColumn("emptyString"); - QTest::addColumn("firstCharacter"); - QTest::addColumn("lastCharacter"); - QTest::addColumn("middleCharacter"); - QTest::addColumn("startString"); - QTest::addColumn("midString"); - QTest::addColumn("endString"); - - const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; - QTest::newRow("Empty") << "" << false << false << false << false << false << false << false; - QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false; - QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false; - QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true; - QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true; - QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false; -} - -void tst_qquicktextedit::isRightToLeft() -{ - QFETCH(QString, text); - QFETCH(bool, emptyString); - QFETCH(bool, firstCharacter); - QFETCH(bool, lastCharacter); - QFETCH(bool, middleCharacter); - QFETCH(bool, startString); - QFETCH(bool, midString); - QFETCH(bool, endString); - - QQuickTextEdit textEdit; - textEdit.setText(text); - - // first test that the right string is delivered to the QString::isRightToLeft() - QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft()); - QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft()); - QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft()); - QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft()); - QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft()); - QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft()); - if (text.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, ": QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start."); - QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft()); - - // then test that the feature actually works - QCOMPARE(textEdit.isRightToLeft(0,0), emptyString); - QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter); - QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter); - QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter); - QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString); - QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString); - if (text.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, ": QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start."); - QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString); -} - -void tst_qquicktextedit::keySelection() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextEdit *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); - - QSignalSpy spy(input, SIGNAL(selectionChanged())); - - simulateKey(&canvas, Qt::Key_Right, Qt::ShiftModifier); - QVERIFY(input->hasActiveFocus() == true); - QCOMPARE(input->selectedText(), QString("a")); - QCOMPARE(spy.count(), 1); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); - QCOMPARE(input->selectedText(), QString()); - QCOMPARE(spy.count(), 2); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); - QCOMPARE(input->selectedText(), QString()); - QCOMPARE(spy.count(), 2); - - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); - QCOMPARE(spy.count(), 2); - simulateKey(&canvas, Qt::Key_Left, Qt::ShiftModifier); - QVERIFY(input->hasActiveFocus() == true); - QCOMPARE(input->selectedText(), QString("a")); - QCOMPARE(spy.count(), 3); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); - QCOMPARE(input->selectedText(), QString()); - QCOMPARE(spy.count(), 4); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); - QCOMPARE(input->selectedText(), QString()); - QCOMPARE(spy.count(), 4); -} - -void tst_qquicktextedit::moveCursorSelection_data() -{ - QTest::addColumn("testStr"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("movePosition"); - QTest::addColumn("mode"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("reversible"); - - QTest::newRow("(t)he|characters") - << standard[0] << 0 << 1 << QQuickTextEdit::SelectCharacters << 0 << 1 << true; - QTest::newRow("do(g)|characters") - << standard[0] << 43 << 44 << QQuickTextEdit::SelectCharacters << 43 << 44 << true; - QTest::newRow("jum(p)ed|characters") - << standard[0] << 23 << 24 << QQuickTextEdit::SelectCharacters << 23 << 24 << true; - QTest::newRow("jumped( )over|characters") - << standard[0] << 26 << 27 << QQuickTextEdit::SelectCharacters << 26 << 27 << true; - QTest::newRow("(the )|characters") - << standard[0] << 0 << 4 << QQuickTextEdit::SelectCharacters << 0 << 4 << true; - QTest::newRow("( dog)|characters") - << standard[0] << 40 << 44 << QQuickTextEdit::SelectCharacters << 40 << 44 << true; - QTest::newRow("( jumped )|characters") - << standard[0] << 19 << 27 << QQuickTextEdit::SelectCharacters << 19 << 27 << true; - QTest::newRow("th(e qu)ick|characters") - << standard[0] << 2 << 6 << QQuickTextEdit::SelectCharacters << 2 << 6 << true; - QTest::newRow("la(zy d)og|characters") - << standard[0] << 38 << 42 << QQuickTextEdit::SelectCharacters << 38 << 42 << true; - QTest::newRow("jum(ped ov)er|characters") - << standard[0] << 23 << 29 << QQuickTextEdit::SelectCharacters << 23 << 29 << true; - QTest::newRow("()the|characters") - << standard[0] << 0 << 0 << QQuickTextEdit::SelectCharacters << 0 << 0 << true; - QTest::newRow("dog()|characters") - << standard[0] << 44 << 44 << QQuickTextEdit::SelectCharacters << 44 << 44 << true; - QTest::newRow("jum()ped|characters") - << standard[0] << 23 << 23 << QQuickTextEdit::SelectCharacters << 23 << 23 << true; - - QTest::newRow("<(t)he>|words") - << standard[0] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 3 << true; - QTest::newRow("|words") - << standard[0] << 43 << 44 << QQuickTextEdit::SelectWords << 41 << 44 << true; - QTest::newRow("|words") - << standard[0] << 23 << 24 << QQuickTextEdit::SelectWords << 20 << 26 << true; - QTest::newRow("over|words") - << standard[0] << 26 << 27 << QQuickTextEdit::SelectWords << 20 << 27 << false; - QTest::newRow("jumped<( )over>|words,reversed") - << standard[0] << 27 << 26 << QQuickTextEdit::SelectWords << 26 << 31 << false; - QTest::newRow("<(the )>quick|words") - << standard[0] << 0 << 4 << QQuickTextEdit::SelectWords << 0 << 4 << false; - QTest::newRow("<(the )quick>|words,reversed") - << standard[0] << 4 << 0 << QQuickTextEdit::SelectWords << 0 << 9 << false; - QTest::newRow("|words") - << standard[0] << 40 << 44 << QQuickTextEdit::SelectWords << 36 << 44 << false; - QTest::newRow("lazy<( dog)>|words,reversed") - << standard[0] << 44 << 40 << QQuickTextEdit::SelectWords << 40 << 44 << false; - QTest::newRow("over|words") - << standard[0] << 19 << 27 << QQuickTextEdit::SelectWords << 16 << 27 << false; - QTest::newRow("fox<( jumped )over>|words,reversed") - << standard[0] << 27 << 19 << QQuickTextEdit::SelectWords << 19 << 31 << false; - QTest::newRow("|words") - << standard[0] << 2 << 6 << QQuickTextEdit::SelectWords << 0 << 9 << true; - QTest::newRow("") - << standard[0] << 38 << 42 << QQuickTextEdit::SelectWords << 36 << 44 << true; - QTest::newRow("|words") - << standard[0] << 23 << 29 << QQuickTextEdit::SelectWords << 20 << 31 << true; - QTest::newRow("<()>the|words") - << standard[0] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true; - QTest::newRow("dog<()>|words") - << standard[0] << 44 << 44 << QQuickTextEdit::SelectWords << 44 << 44 << true; - QTest::newRow("jum<()>ped|words") - << standard[0] << 23 << 23 << QQuickTextEdit::SelectWords << 23 << 23 << true; - - QTest::newRow("Hello<(,)> |words") - << standard[2] << 5 << 6 << QQuickTextEdit::SelectWords << 5 << 6 << true; - QTest::newRow("Hello<(, )>world|words") - << standard[2] << 5 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false; - QTest::newRow("Hello<(, )world>|words,reversed") - << standard[2] << 7 << 5 << QQuickTextEdit::SelectWords << 5 << 12 << false; - QTest::newRow("world|words") - << standard[2] << 3 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false; - QTest::newRow("|words,reversed") - << standard[2] << 7 << 3 << QQuickTextEdit::SelectWords << 0 << 12 << false; - QTest::newRow(",|words") - << standard[2] << 3 << 5 << QQuickTextEdit::SelectWords << 0 << 5 << true; - QTest::newRow("Hello<()>,|words") - << standard[2] << 5 << 5 << QQuickTextEdit::SelectWords << 5 << 5 << true; - QTest::newRow("Hello,<()>|words") - << standard[2] << 6 << 6 << QQuickTextEdit::SelectWords << 6 << 6 << true; - QTest::newRow("Hello<,( )>world|words") - << standard[2] << 6 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false; - QTest::newRow("Hello,<( )world>|words,reversed") - << standard[2] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false; - QTest::newRow("Hello<,( world)>|words") - << standard[2] << 6 << 12 << QQuickTextEdit::SelectWords << 5 << 12 << false; - QTest::newRow("Hello,<( world)>|words,reversed") - << standard[2] << 12 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false; - QTest::newRow("Hello<,( world!)>|words") - << standard[2] << 6 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << false; - QTest::newRow("Hello,<( world!)>|words,reversed") - << standard[2] << 13 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false; - QTest::newRow("Hello<(, world!)>|words") - << standard[2] << 5 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << true; - QTest::newRow("world<(!)>|words") - << standard[2] << 12 << 13 << QQuickTextEdit::SelectWords << 12 << 13 << true; - QTest::newRow("world!<()>)|words") - << standard[2] << 13 << 13 << QQuickTextEdit::SelectWords << 13 << 13 << true; - QTest::newRow("world<()>!)|words") - << standard[2] << 12 << 12 << QQuickTextEdit::SelectWords << 12 << 12 << true; - - QTest::newRow("<(,)>olleH |words") - << standard[3] << 7 << 8 << QQuickTextEdit::SelectWords << 7 << 8 << true; - QTest::newRow("olleH|words") - << standard[3] << 6 << 8 << QQuickTextEdit::SelectWords << 1 << 8 << false; - QTest::newRow("dlrow<( ,)>olleH|words,reversed") - << standard[3] << 8 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false; - QTest::newRow("|words") - << standard[3] << 6 << 10 << QQuickTextEdit::SelectWords << 1 << 13 << false; - QTest::newRow("dlrow<( ,ol)leH>|words,reversed") - << standard[3] << 10 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false; - QTest::newRow(",<(ol)leH>,|words") - << standard[3] << 8 << 10 << QQuickTextEdit::SelectWords << 8 << 13 << true; - QTest::newRow(",<()>olleH|words") - << standard[3] << 8 << 8 << QQuickTextEdit::SelectWords << 8 << 8 << true; - QTest::newRow("<()>,olleH|words") - << standard[3] << 7 << 7 << QQuickTextEdit::SelectWords << 7 << 7 << true; - QTest::newRow(",olleH|words") - << standard[3] << 6 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false; - QTest::newRow("dlrow<( ),>olleH|words,reversed") - << standard[3] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false; - QTest::newRow("<(dlrow )>,olleH|words") - << standard[3] << 1 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false; - QTest::newRow("<(dlrow ),>olleH|words,reversed") - << standard[3] << 7 << 1 << QQuickTextEdit::SelectWords << 1 << 8 << false; - QTest::newRow("<(!dlrow )>,olleH|words") - << standard[3] << 0 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false; - QTest::newRow("<(!dlrow ),>olleH|words,reversed") - << standard[3] << 7 << 0 << QQuickTextEdit::SelectWords << 0 << 8 << false; - QTest::newRow("(!dlrow ,)olleH|words") - << standard[3] << 0 << 8 << QQuickTextEdit::SelectWords << 0 << 8 << true; - QTest::newRow("<(!)>dlrow|words") - << standard[3] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 1 << true; - QTest::newRow("<()>!dlrow|words") - << standard[3] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true; - QTest::newRow("!<()>dlrow|words") - << standard[3] << 1 << 1 << QQuickTextEdit::SelectWords << 1 << 1 << true; -} - -void tst_qquicktextedit::moveCursorSelection() -{ - QFETCH(QString, testStr); - QFETCH(int, cursorPosition); - QFETCH(int, movePosition); - QFETCH(QQuickTextEdit::SelectionMode, mode); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(bool, reversible); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *texteditObject = qobject_cast(textinputComponent.create()); - QVERIFY(texteditObject != 0); - - texteditObject->setCursorPosition(cursorPosition); - texteditObject->moveCursorSelection(movePosition, mode); - - QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); - QCOMPARE(texteditObject->selectionStart(), selectionStart); - QCOMPARE(texteditObject->selectionEnd(), selectionEnd); - - if (reversible) { - texteditObject->setCursorPosition(movePosition); - texteditObject->moveCursorSelection(cursorPosition, mode); - - QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); - QCOMPARE(texteditObject->selectionStart(), selectionStart); - QCOMPARE(texteditObject->selectionEnd(), selectionEnd); - } -} - -void tst_qquicktextedit::moveCursorSelectionSequence_data() -{ - QTest::addColumn("testStr"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("movePosition1"); - QTest::addColumn("movePosition2"); - QTest::addColumn("selection1Start"); - QTest::addColumn("selection1End"); - QTest::addColumn("selection2Start"); - QTest::addColumn("selection2End"); - - QTest::newRow("the { f^ox} jumped|ltr") - << standard[0] - << 9 << 13 << 17 - << 4 << 15 - << 4 << 19; - QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") - << standard[0] - << 13 << 9 << 17 - << 9 << 15 - << 10 << 19; - QTest::newRow("the { ^}fox jumped|ltr") - << standard[0] - << 9 << 13 << 16 - << 4 << 15 - << 4 << 16; - QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") - << standard[0] - << 13 << 9 << 16 - << 9 << 15 - << 10 << 16; - QTest::newRow("the {} fox jumped|ltr") - << standard[0] - << 9 << 13 << 15 - << 4 << 15 - << 4 << 15; - QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") - << standard[0] - << 13 << 9 << 15 - << 9 << 15 - << 10 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 10 - << 4 << 15 - << 4 << 10; - QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl") - << standard[0] - << 13 << 9 << 10 - << 9 << 15 - << 10 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 9 - << 4 << 15 - << 4 << 9; - QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") - << standard[0] - << 13 << 9 << 9 - << 9 << 15 - << 9 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 7 - << 4 << 15 - << 4 << 9; - QTest::newRow("the { fox|rtl") - << standard[0] - << 13 << 9 << 7 - << 9 << 15 - << 4 << 15; - QTest::newRow("the {<^quick}( bro)wn> fox|ltr") - << standard[0] - << 9 << 13 << 4 - << 4 << 15 - << 4 << 9; - QTest::newRow("the {<^quick}( bro)wn> fox|rtl") - << standard[0] - << 13 << 9 << 4 - << 9 << 15 - << 4 << 15; - QTest::newRow("the{^ fox|ltr") - << standard[0] - << 9 << 13 << 3 - << 4 << 15 - << 3 << 9; - QTest::newRow("the{^ fox|rtl") - << standard[0] - << 13 << 9 << 3 - << 9 << 15 - << 3 << 15; - QTest::newRow("{t^he fox|ltr") - << standard[0] - << 9 << 13 << 1 - << 4 << 15 - << 0 << 9; - QTest::newRow("{t^he fox|rtl") - << standard[0] - << 13 << 9 << 1 - << 9 << 15 - << 0 << 15; - - QTest::newRow("{, w^orld}!|ltr") - << standard[2] - << 2 << 4 << 8 - << 0 << 5 - << 0 << 12; - QTest::newRow("{, w^orld}!|rtl") - << standard[2] - << 4 << 2 << 8 - << 0 << 5 - << 0 << 12; - - QTest::newRow("!{dlro^w ,}|ltr") - << standard[3] - << 9 << 11 << 5 - << 8 << 13 - << 1 << 13; - QTest::newRow("!{dlro^w ,}|rtl") - << standard[3] - << 11 << 9 << 5 - << 8 << 13 - << 1 << 13; -} - -void tst_qquicktextedit::moveCursorSelectionSequence() -{ - QFETCH(QString, testStr); - QFETCH(int, cursorPosition); - QFETCH(int, movePosition1); - QFETCH(int, movePosition2); - QFETCH(int, selection1Start); - QFETCH(int, selection1End); - QFETCH(int, selection2Start); - QFETCH(int, selection2End); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; - QDeclarativeComponent texteditComponent(&engine); - texteditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *texteditObject = qobject_cast(texteditComponent.create()); - QVERIFY(texteditObject != 0); - - texteditObject->setCursorPosition(cursorPosition); - - texteditObject->moveCursorSelection(movePosition1, QQuickTextEdit::SelectWords); - QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); - QCOMPARE(texteditObject->selectionStart(), selection1Start); - QCOMPARE(texteditObject->selectionEnd(), selection1End); - - texteditObject->moveCursorSelection(movePosition2, QQuickTextEdit::SelectWords); - QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); - QCOMPARE(texteditObject->selectionStart(), selection2Start); - QCOMPARE(texteditObject->selectionEnd(), selection2End); -} - - -void tst_qquicktextedit::mouseSelection_data() -{ - QTest::addColumn("qmlfile"); - QTest::addColumn("from"); - QTest::addColumn("to"); - QTest::addColumn("selectedText"); - - // import installed - QTest::newRow("on") << TESTDATA("mouseselection_true.qml") << 4 << 9 << "45678"; - QTest::newRow("off") << TESTDATA("mouseselection_false.qml") << 4 << 9 << QString(); - QTest::newRow("default") << TESTDATA("mouseselection_default.qml") << 4 << 9 << QString(); - QTest::newRow("off word selection") << TESTDATA("mouseselection_false_words.qml") << 4 << 9 << QString(); - QTest::newRow("on word selection (4,9)") << TESTDATA("mouseselection_true_words.qml") << 4 << 9 << "0123456789"; - QTest::newRow("on word selection (2,13)") << TESTDATA("mouseselection_true_words.qml") << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (2,30)") << TESTDATA("mouseselection_true_words.qml") << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (9,13)") << TESTDATA("mouseselection_true_words.qml") << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (9,30)") << TESTDATA("mouseselection_true_words.qml") << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (13,2)") << TESTDATA("mouseselection_true_words.qml") << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (20,2)") << TESTDATA("mouseselection_true_words.qml") << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (12,9)") << TESTDATA("mouseselection_true_words.qml") << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - QTest::newRow("on word selection (30,9)") << TESTDATA("mouseselection_true_words.qml") << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -} - -void tst_qquicktextedit::mouseSelection() -{ - QFETCH(QString, qmlfile); - QFETCH(int, from); - QFETCH(int, to); - QFETCH(QString, selectedText); - - QQuickView canvas(QUrl::fromLocalFile(qmlfile)); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); - QVERIFY(textEditObject != 0); - - // press-and-drag-and-release from x1 to x2 - QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint(); - QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint(); - QTest::mousePress(&canvas, Qt::LeftButton, 0, p1); - QTest::mouseMove(&canvas, p2); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, p2); - QTest::qWait(50); - QTRY_COMPARE(textEditObject->selectedText(), selectedText); - - // Clicking and shift to clicking between the same points should select the same text. - textEditObject->setCursorPosition(0); - QTest::mouseClick(&canvas, Qt::LeftButton, Qt::NoModifier, p1); - QTest::mouseClick(&canvas, Qt::LeftButton, Qt::ShiftModifier, p2); - QTest::qWait(50); - QTRY_COMPARE(textEditObject->selectedText(), selectedText); -} - -void tst_qquicktextedit::dragMouseSelection() -{ - QString qmlfile = TESTDATA("mouseselection_true.qml"); - - QQuickView canvas(QUrl::fromLocalFile(qmlfile)); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); - QVERIFY(textEditObject != 0); - - // press-and-drag-and-release from x1 to x2 - int x1 = 10; - int x2 = 70; - int y = textEditObject->height()/2; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2, y)); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QTest::qWait(300); - QString str1; - QTRY_VERIFY((str1 = textEditObject->selectedText()).length() > 3); - - // press and drag the current selection. - x1 = 40; - x2 = 100; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2, y)); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QTest::qWait(300); - QString str2; - QTRY_VERIFY((str2 = textEditObject->selectedText()).length() > 3); - - QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and not the first moved. -} - -void tst_qquicktextedit::mouseSelectionMode_data() -{ - QTest::addColumn("qmlfile"); - QTest::addColumn("selectWords"); - - // import installed - QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true; - QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false; - QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false; -} - -void tst_qquicktextedit::mouseSelectionMode() -{ - QFETCH(QString, qmlfile); - QFETCH(bool, selectWords); - - QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - QQuickView canvas(QUrl::fromLocalFile(qmlfile)); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); - QVERIFY(textEditObject != 0); - - // press-and-drag-and-release from x1 to x2 - int x1 = 10; - int x2 = 70; - int y = textEditObject->height()/2; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2, y)); - //QTest::mouseMove(canvas, QPoint(x2,y)); // doesn't work -// QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); -// QGuiApplication::sendEvent(&canvas, &mv); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QString str = textEditObject->selectedText(); - if (selectWords) { - QTRY_COMPARE(textEditObject->selectedText(), text); - } else { - QTRY_VERIFY(textEditObject->selectedText().length() > 3); - QVERIFY(str != text); - } -} - -void tst_qquicktextedit::inputMethodHints() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethodhints.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); - QVERIFY(textEditObject != 0); - QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText); - textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly); - QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly); -} - -void tst_qquicktextedit::positionAt() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); - QVERIFY(canvas.rootObject() != 0); - canvas.show(); - canvas.requestActivateWindow(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - QQuickTextEdit *texteditObject = qobject_cast(canvas.rootObject()); - QVERIFY(texteditObject != 0); - - QFontMetrics fm(texteditObject->font()); - const int y0 = fm.height() / 2; - const int y1 = fm.height() * 3 / 2; - - int pos = texteditObject->positionAt(texteditObject->width()/2, y0); - int widthBegin = 0; - int widthEnd = 0; - if (!qmlDisableDistanceField()) { - QTextLayout layout(texteditObject->text()); - - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - - widthBegin = floor(line.cursorToX(pos - 1)); - widthEnd = ceil(line.cursorToX(pos + 1)); - } else { - widthBegin = fm.width(texteditObject->text().left(pos - 1)); - widthEnd = fm.width(texteditObject->text().left(pos + 1)); - } - - QVERIFY(widthBegin <= texteditObject->width() / 2); - QVERIFY(widthEnd >= texteditObject->width() / 2); - - const qreal x0 = texteditObject->positionToRectangle(pos).x(); - const qreal x1 = texteditObject->positionToRectangle(pos + 1).x(); - - QString preeditText = texteditObject->text().mid(0, pos); - texteditObject->setText(texteditObject->text().mid(pos)); - texteditObject->setCursorPosition(0); - - QInputMethodEvent inputEvent(preeditText, QList()); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent); - - // Check all points within the preedit text return the same position. - QCOMPARE(texteditObject->positionAt(0, y0), 0); - QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0); - QCOMPARE(texteditObject->positionAt(x0, y0), 0); - - // Verify positioning returns to normal after the preedit text. - QCOMPARE(texteditObject->positionAt(x1, y0), 1); - QCOMPARE(texteditObject->positionToRectangle(1).x(), x1); - - QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0); -} - -void tst_qquicktextedit::cursorDelegate() -{ - QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml"))); - view.show(); - view.requestActivateWindow(); - QQuickTextEdit *textEditObject = view.rootObject()->findChild("textEditObject"); - QVERIFY(textEditObject != 0); - QVERIFY(textEditObject->findChild("cursorInstance")); - //Test Delegate gets created - textEditObject->setFocus(true); - QQuickItem* delegateObject = textEditObject->findChild("cursorInstance"); - QVERIFY(delegateObject); - QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello")); - //Test Delegate gets moved - for (int i=0; i<= textEditObject->text().length(); i++) { - textEditObject->setCursorPosition(i); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - } - // Clear preedit text; - QInputMethodEvent event; - QGuiApplication::sendEvent(&view, &event); - - - // Test delegate gets moved on mouse press. - textEditObject->setSelectByMouse(true); - textEditObject->setCursorPosition(0); - const QPoint point1 = textEditObject->positionToRectangle(5).center().toPoint(); - QTest::mouseClick(&view, Qt::LeftButton, 0, point1); - QTest::qWait(50); - QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - - // Test delegate gets moved on mouse drag - textEditObject->setCursorPosition(0); - const QPoint point2 = textEditObject->positionToRectangle(10).center().toPoint(); - QTest::mousePress(&view, Qt::LeftButton, 0, point1); - QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); - QGuiApplication::sendEvent(&view, &mv); - QTest::mouseRelease(&view, Qt::LeftButton, 0, point2); - QTest::qWait(50); - QTRY_COMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - - textEditObject->setReadOnly(true); - textEditObject->setCursorPosition(0); - QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); - QTest::qWait(50); - QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - - textEditObject->setCursorPosition(0); - QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); - QTest::qWait(50); - QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - - textEditObject->setCursorPosition(0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); - //Test Delegate gets deleted - textEditObject->setCursorDelegate(0); - QVERIFY(!textEditObject->findChild("cursorInstance")); -} - -void tst_qquicktextedit::cursorVisible() -{ - QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QQuickTextEdit edit; - QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); - - QCOMPARE(edit.isCursorVisible(), false); - - edit.setCursorVisible(true); - QCOMPARE(edit.isCursorVisible(), true); - QCOMPARE(spy.count(), 1); - - edit.setCursorVisible(false); - QCOMPARE(edit.isCursorVisible(), false); - QCOMPARE(spy.count(), 2); - - edit.setFocus(true); - QCOMPARE(edit.isCursorVisible(), false); - QCOMPARE(spy.count(), 2); - - edit.setParentItem(view.rootObject()); - QCOMPARE(edit.isCursorVisible(), true); - QCOMPARE(spy.count(), 3); - - edit.setFocus(false); - QCOMPARE(edit.isCursorVisible(), false); - QCOMPARE(spy.count(), 4); - - edit.setFocus(true); - QCOMPARE(edit.isCursorVisible(), true); - QCOMPARE(spy.count(), 5); - - QQuickView alternateView; - alternateView.show(); - alternateView.requestActivateWindow(); - QTest::qWaitForWindowShown(&alternateView); - - QCOMPARE(edit.isCursorVisible(), false); - QCOMPARE(spy.count(), 6); - - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QCOMPARE(edit.isCursorVisible(), true); - QCOMPARE(spy.count(), 7); -} - -void tst_qquicktextedit::delegateLoading_data() -{ - QTest::addColumn("qmlfile"); - QTest::addColumn("error"); - - // import installed - QTest::newRow("pass") << "cursorHttpTestPass.qml" << ""; - QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection "; - QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type "; -} - -void tst_qquicktextedit::delegateLoading() -{ - QFETCH(QString, qmlfile); - QFETCH(QString, error); - - TestHTTPServer server(42332); - server.serveDirectory(TESTDATA("httpfail"), TestHTTPServer::Disconnect); - server.serveDirectory(TESTDATA("httpslow"), TestHTTPServer::Delay); - server.serveDirectory(TESTDATA("http")); - - QQuickView view(QUrl(QLatin1String("http://localhost:42332/") + qmlfile)); - view.show(); - view.requestActivateWindow(); - - if (!error.isEmpty()) { - QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); - QTRY_VERIFY(view.status()==QQuickView::Error); - QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test - } else { - QTRY_VERIFY(view.rootObject());//Wait for loading to finish. - QQuickTextEdit *textEditObject = view.rootObject()->findChild("textEditObject"); - // view.rootObject()->dumpObjectTree(); - QVERIFY(textEditObject != 0); - textEditObject->setFocus(true); - QQuickItem *delegate; - delegate = view.rootObject()->findChild("delegateOkay"); - QVERIFY(delegate); - delegate = view.rootObject()->findChild("delegateSlow"); - QVERIFY(delegate); - - delete delegate; - } - - - //A test should be added here with a component which is ready but component.create() returns null - //Not sure how to accomplish this with QQuickTextEdits cursor delegate - //###This was only needed for code coverage, and could be a case of overzealous defensive programming - //delegate = view.rootObject()->findChild("delegateErrorB"); - //QVERIFY(!delegate); -} - -/* -TextEdit element should only handle left/right keys until the cursor reaches -the extent of the text, then they should ignore the keys. -*/ -void tst_qquicktextedit::navigation() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickItem *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); -} - -void tst_qquicktextedit::copyAndPaste() { -#ifndef QT_NO_CLIPBOARD - -#ifdef Q_OS_MAC - { - PasteboardRef pasteboard; - OSStatus status = PasteboardCreate(0, &pasteboard); - if (status == noErr) - CFRelease(pasteboard); - else - QSKIP("This machine doesn't support the clipboard"); - } -#endif - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - // copy and paste - QCOMPARE(textEdit->text().length(), 12); - textEdit->select(0, textEdit->text().length());; - textEdit->copy(); - QCOMPARE(textEdit->selectedText(), QString("Hello world!")); - QCOMPARE(textEdit->selectedText().length(), 12); - textEdit->setCursorPosition(0); - QVERIFY(textEdit->canPaste()); - textEdit->paste(); - QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); - QCOMPARE(textEdit->text().length(), 24); - - // canPaste - QVERIFY(textEdit->canPaste()); - textEdit->setReadOnly(true); - QVERIFY(!textEdit->canPaste()); - textEdit->setReadOnly(false); - QVERIFY(textEdit->canPaste()); - - // QTBUG-12339 - // test that document and internal text attribute are in sync - QQuickItemPrivate* pri = QQuickItemPrivate::get(textEdit); - QQuickTextEditPrivate *editPrivate = static_cast(pri); - QCOMPARE(textEdit->text(), editPrivate->text); - - // select word - textEdit->setCursorPosition(0); - textEdit->selectWord(); - QCOMPARE(textEdit->selectedText(), QString("Hello")); - - // select all and cut - textEdit->selectAll(); - textEdit->cut(); - QCOMPARE(textEdit->text().length(), 0); - textEdit->paste(); - QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); - QCOMPARE(textEdit->text().length(), 24); -#endif -} - -void tst_qquicktextedit::canPaste() { -#ifndef QT_NO_CLIPBOARD - - QGuiApplication::clipboard()->setText("Some text"); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - // check initial value - QTBUG-17765 - QTextControl tc; - QCOMPARE(textEdit->canPaste(), tc.canPaste()); - -#endif -} - -void tst_qquicktextedit::canPasteEmpty() { -#ifndef QT_NO_CLIPBOARD - - QGuiApplication::clipboard()->clear(); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - // check initial value - QTBUG-17765 - QTextControl tc; - QCOMPARE(textEdit->canPaste(), tc.canPaste()); - -#endif -} - -void tst_qquicktextedit::readOnly() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextEdit *edit = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(edit != 0); - QTRY_VERIFY(edit->hasActiveFocus() == true); - QVERIFY(edit->isReadOnly() == true); - QString initial = edit->text(); - for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) - simulateKey(&canvas, k); - simulateKey(&canvas, Qt::Key_Return); - simulateKey(&canvas, Qt::Key_Space); - simulateKey(&canvas, Qt::Key_Escape); - QCOMPARE(edit->text(), initial); - - edit->setCursorPosition(3); - edit->setReadOnly(false); - QCOMPARE(edit->isReadOnly(), false); - QCOMPARE(edit->cursorPosition(), edit->text().length()); -} - -void tst_qquicktextedit::simulateKey(QQuickView *view, int key, Qt::KeyboardModifiers modifiers) -{ - QKeyEvent press(QKeyEvent::KeyPress, key, modifiers); - QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers); - - QGuiApplication::sendEvent(view, &press); - QGuiApplication::sendEvent(view, &release); -} - -void tst_qquicktextedit::textInput() -{ - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextEdit *edit = qobject_cast(view.rootObject()); - QVERIFY(edit); - QVERIFY(edit->hasActiveFocus() == true); - - // test that input method event is committed - QInputMethodEvent event; - event.setCommitString( "Hello world!", 0, 0); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); - QCOMPARE(edit->text(), QString("Hello world!")); - - // QTBUG-12339 - // test that document and internal text attribute are in sync - QQuickTextEditPrivate *editPrivate = static_cast(QQuickItemPrivate::get(edit)); - QCOMPARE(editPrivate->text, QString("Hello world!")); -} - -class PlatformInputContext : public QPlatformInputContext -{ -public: - PlatformInputContext() : m_visible(false) {} - - virtual void showInputPanel() - { - m_visible = true; - } - virtual void hideInputPanel() - { - m_visible = false; - } - virtual bool isInputPanelVisible() const - { - return m_visible; - } - - bool m_visible; -}; - -void tst_qquicktextedit::openInputPanel() -{ - PlatformInputContext platformInputContext; - QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); - inputPanelPrivate->testContext = &platformInputContext; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QQuickTextEdit *edit = qobject_cast(view.rootObject()); - QVERIFY(edit); - - // check default values - QVERIFY(edit->focusOnPress()); - QVERIFY(!edit->hasActiveFocus()); - qDebug() << &edit << qApp->inputPanel()->inputItem(); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should open on focus - QPoint centerPoint(view.width()/2, view.height()/2); - Qt::KeyboardModifiers noModifiers = 0; - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QVERIFY(edit->hasActiveFocus()); - QCOMPARE(qApp->inputPanel()->inputItem(), edit); - QCOMPARE(qApp->inputPanel()->visible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - - // input panel should be re-opened when pressing already focused TextEdit - qApp->inputPanel()->hide(); - QCOMPARE(qApp->inputPanel()->visible(), false); - QVERIFY(edit->hasActiveFocus()); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QCOMPARE(qApp->inputPanel()->visible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - - // input panel should stay visible if focus is lost to another text editor - QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); - QQuickTextEdit anotherEdit; - anotherEdit.setParentItem(view.rootObject()); - anotherEdit.setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), true); - QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherEdit)); - QCOMPARE(inputPanelVisibilitySpy.count(), 0); - - anotherEdit.setFocus(false); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - QCOMPARE(view.activeFocusItem(), view.rootItem()); - anotherEdit.setFocus(true); - - // input item should be null if focus is lost to an item that doesn't accept inputs - QQuickItem item; - item.setParentItem(view.rootObject()); - item.setFocus(true); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - QCOMPARE(view.activeFocusItem(), &item); - - qApp->inputPanel()->hide(); - - // input panel should not be opened if TextEdit is read only - edit->setReadOnly(true); - edit->setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should not be opened if focusOnPress is set to false - edit->setFocusOnPress(false); - edit->setFocus(false); - edit->setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should open when openSoftwareInputPanel is called - edit->openSoftwareInputPanel(); - QCOMPARE(qApp->inputPanel()->visible(), true); - - // input panel should close when closeSoftwareInputPanel is called - edit->closeSoftwareInputPanel(); - QCOMPARE(qApp->inputPanel()->visible(), false); - - inputPanelPrivate->testContext = 0; -} - -void tst_qquicktextedit::geometrySignals() -{ - QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml")); - QObject *o = component.create(); - QVERIFY(o); - QCOMPARE(o->property("bindingWidth").toInt(), 400); - QCOMPARE(o->property("bindingHeight").toInt(), 500); - delete o; -} - -void tst_qquicktextedit::pastingRichText_QTBUG_14003() -{ -#ifndef QT_NO_CLIPBOARD - QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.PlainText }"; - QDeclarativeComponent component(&engine); - component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickTextEdit *obj = qobject_cast(component.create()); - - QTRY_VERIFY(obj != 0); - QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); - - QMimeData *mData = new QMimeData; - mData->setHtml("Hello"); - QGuiApplication::clipboard()->setMimeData(mData); - - obj->paste(); - QTRY_VERIFY(obj->text() == ""); - QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); -#endif -} - -void tst_qquicktextedit::implicitSize_data() -{ - QTest::addColumn("text"); - QTest::addColumn("wrap"); - QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; - QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; - QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; - QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; -} - -void tst_qquicktextedit::implicitSize() -{ - QFETCH(QString, text); - QFETCH(QString, wrap); - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickTextEdit *textObject = qobject_cast(textComponent.create()); - - QVERIFY(textObject->width() < textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); - - textObject->resetWidth(); - QVERIFY(textObject->width() == textObject->implicitWidth()); - QVERIFY(textObject->height() == textObject->implicitHeight()); -} - -void tst_qquicktextedit::testQtQuick11Attributes() -{ - QFETCH(QString, code); - QFETCH(QString, warning); - QFETCH(QString, error); - - QDeclarativeEngine engine; - QObject *obj; - - QDeclarativeComponent valid(&engine); - valid.setData("import QtQuick 2.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); - obj = valid.create(); - QVERIFY(obj); - QVERIFY(valid.errorString().isEmpty()); - delete obj; - - QDeclarativeComponent invalid(&engine); - invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); - obj = invalid.create(); - QCOMPARE(invalid.errorString(), error); - delete obj; -} - -void tst_qquicktextedit::testQtQuick11Attributes_data() -{ - QTest::addColumn("code"); - QTest::addColumn("warning"); - QTest::addColumn("error"); - - QTest::newRow("canPaste") << "property bool foo: canPaste" - << ":1: ReferenceError: Can't find variable: canPaste" - << ""; - - QTest::newRow("lineCount") << "property int foo: lineCount" - << ":1: ReferenceError: Can't find variable: lineCount" - << ""; - - QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" - << ":1: ReferenceError: Can't find variable: moveCursorSelection" - << ""; - - QTest::newRow("deselect") << "Component.onCompleted: deselect()" - << ":1: ReferenceError: Can't find variable: deselect" - << ""; - - QTest::newRow("onLinkActivated") << "onLinkActivated: {}" - << "QDeclarativeComponent: Component is not ready" - << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n"; -} - -void tst_qquicktextedit::preeditCursorRectangle() -{ - QString preeditText = "super"; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextEdit *edit = qobject_cast(view.rootObject()); - QVERIFY(edit); - - QSignalSpy editSpy(edit, SIGNAL(cursorRectangleChanged())); - QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged())); - - QRect currentRect; - - QInputMethodQueryEvent query(Qt::ImCursorRectangle); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - QRect previousRect = query.value(Qt::ImCursorRectangle).toRect(); - - // Verify that the micro focus rect is positioned the same for position 0 as - // it would be if there was no preedit text. - QInputMethodEvent imEvent(preeditText, QList() - << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, preeditText.length(), QVariant())); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QCOMPARE(currentRect, previousRect); - QCOMPARE(editSpy.count(), 0); - QCOMPARE(panelSpy.count(), 0); - - // Verify that the micro focus rect moves to the left as the cursor position - // is incremented. - for (int i = 1; i <= 5; ++i) { - QInputMethodEvent imEvent(preeditText, QList() - << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, preeditText.length(), QVariant())); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QVERIFY(previousRect.left() < currentRect.left()); - QVERIFY(editSpy.count() > 0); editSpy.clear(); - QVERIFY(panelSpy.count() > 0); panelSpy.clear(); - previousRect = currentRect; - } - - // Verify that if there is no preedit cursor then the micro focus rect is the - // same as it would be if it were positioned at the end of the preedit text. - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - editSpy.clear(); - panelSpy.clear(); - { QInputMethodEvent imEvent(preeditText, QList()); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); } - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QCOMPARE(currentRect, previousRect); - QVERIFY(editSpy.count() > 0); - QVERIFY(panelSpy.count() > 0); -} - -void tst_qquicktextedit::inputMethodComposing() -{ - QString text = "supercalifragisiticexpialidocious!"; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextEdit *edit = qobject_cast(view.rootObject()); - QVERIFY(edit); - QSignalSpy spy(edit, SIGNAL(inputMethodComposingChanged())); - edit->setCursorPosition(12); - - QCOMPARE(edit->isInputMethodComposing(), false); - - { - QInputMethodEvent event(text.mid(3), QList()); - QGuiApplication::sendEvent(edit, &event); - } - - QCOMPARE(edit->isInputMethodComposing(), true); - QCOMPARE(spy.count(), 1); - - { - QInputMethodEvent event(text.mid(12), QList()); - QGuiApplication::sendEvent(edit, &event); - } - QCOMPARE(spy.count(), 1); - - { - QInputMethodEvent event; - QGuiApplication::sendEvent(edit, &event); - } - QCOMPARE(edit->isInputMethodComposing(), false); - QCOMPARE(spy.count(), 2); -} - -void tst_qquicktextedit::cursorRectangleSize() -{ - QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); - QVERIFY(canvas->rootObject() != 0); - QQuickTextEdit *textEdit = qobject_cast(canvas->rootObject()); - - // make sure cursor rectangle is not at (0,0) - textEdit->setX(10); - textEdit->setY(10); - textEdit->setCursorPosition(3); - QVERIFY(textEdit != 0); - textEdit->setFocus(true); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - - QInputMethodQueryEvent event(Qt::ImCursorRectangle); - qApp->sendEvent(qApp->inputPanel()->inputItem(), &event); - QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - - QRect cursorRectFromItem = textEdit->cursorRectangle(); - QRectF cursorRectFromPositionToRectangle = textEdit->positionToRectangle(textEdit->cursorPosition()); - - // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); - - // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); - - // item-canvas transform and input item transform match - QCOMPARE(QQuickItemPrivate::get(textEdit)->itemToCanvasTransform(), qApp->inputPanel()->inputItemTransform()); - - // input panel cursorRectangle property and tranformed item cursor rectangle match - QRectF sceneCursorRect = QQuickItemPrivate::get(textEdit)->itemToCanvasTransform().mapRect(cursorRectFromItem); - QCOMPARE(sceneCursorRect, qApp->inputPanel()->cursorRectangle()); - - delete canvas; -} - -void tst_qquicktextedit::getText_data() -{ - QTest::addColumn("text"); - QTest::addColumn("start"); - QTest::addColumn("end"); - QTest::addColumn("expectedText"); - - const QString richBoldText = QStringLiteral("This is some bold text"); - const QString plainBoldText = QStringLiteral("This is some bold text"); - - QTest::newRow("all plain text") - << standard.at(0) - << 0 << standard.at(0).length() - << standard.at(0); - - QTest::newRow("plain text sub string") - << standard.at(0) - << 0 << 12 - << standard.at(0).mid(0, 12); - - QTest::newRow("plain text sub string reversed") - << standard.at(0) - << 12 << 0 - << standard.at(0).mid(0, 12); - - QTest::newRow("plain text cropped beginning") - << standard.at(0) - << -3 << 4 - << standard.at(0).mid(0, 4); - - QTest::newRow("plain text cropped end") - << standard.at(0) - << 23 << standard.at(0).length() + 8 - << standard.at(0).mid(23); - - QTest::newRow("plain text cropped beginning and end") - << standard.at(0) - << -9 << standard.at(0).length() + 4 - << standard.at(0); - - QTest::newRow("all rich text") - << richBoldText - << 0 << plainBoldText.length() - << plainBoldText; - - QTest::newRow("rich text sub string") - << richBoldText - << 14 << 21 - << plainBoldText.mid(14, 7); -} - -void tst_qquicktextedit::getText() -{ - QFETCH(QString, text); - QFETCH(int, start); - QFETCH(int, end); - QFETCH(QString, expectedText); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - QCOMPARE(textEdit->getText(start, end), expectedText); -} - -void tst_qquicktextedit::getFormattedText_data() -{ - QTest::addColumn("text"); - QTest::addColumn("textFormat"); - QTest::addColumn("start"); - QTest::addColumn("end"); - QTest::addColumn("expectedText"); - - const QString richBoldText = QStringLiteral("This is some bold text"); - const QString plainBoldText = QStringLiteral("This is some bold text"); - - QTest::newRow("all plain text") - << standard.at(0) - << QQuickTextEdit::PlainText - << 0 << standard.at(0).length() - << standard.at(0); - - QTest::newRow("plain text sub string") - << standard.at(0) - << QQuickTextEdit::PlainText - << 0 << 12 - << standard.at(0).mid(0, 12); - - QTest::newRow("plain text sub string reversed") - << standard.at(0) - << QQuickTextEdit::PlainText - << 12 << 0 - << standard.at(0).mid(0, 12); - - QTest::newRow("plain text cropped beginning") - << standard.at(0) - << QQuickTextEdit::PlainText - << -3 << 4 - << standard.at(0).mid(0, 4); - - QTest::newRow("plain text cropped end") - << standard.at(0) - << QQuickTextEdit::PlainText - << 23 << standard.at(0).length() + 8 - << standard.at(0).mid(23); - - QTest::newRow("plain text cropped beginning and end") - << standard.at(0) - << QQuickTextEdit::PlainText - << -9 << standard.at(0).length() + 4 - << standard.at(0); - - QTest::newRow("all rich (Auto) text") - << richBoldText - << QQuickTextEdit::AutoText - << 0 << plainBoldText.length() - << QString("This is some \\<.*\\>bold\\ text"); - - QTest::newRow("all rich (Rich) text") - << richBoldText - << QQuickTextEdit::RichText - << 0 << plainBoldText.length() - << QString("This is some \\<.*\\>bold\\ text"); - - QTest::newRow("all rich (Plain) text") - << richBoldText - << QQuickTextEdit::PlainText - << 0 << richBoldText.length() - << richBoldText; - - QTest::newRow("rich (Auto) text sub string") - << richBoldText - << QQuickTextEdit::AutoText - << 14 << 21 - << QString("\\<.*\\>old\\ tex"); - - QTest::newRow("rich (Rich) text sub string") - << richBoldText - << QQuickTextEdit::RichText - << 14 << 21 - << QString("\\<.*\\>old\\ tex"); - - QTest::newRow("rich (Plain) text sub string") - << richBoldText - << QQuickTextEdit::PlainText - << 17 << 27 - << richBoldText.mid(17, 10); -} - -void tst_qquicktextedit::getFormattedText() -{ - QFETCH(QString, text); - QFETCH(QQuickTextEdit::TextFormat, textFormat); - QFETCH(int, start); - QFETCH(int, end); - QFETCH(QString, expectedText); - - QString componentStr = "import QtQuick 2.0\nTextEdit {}"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - textEdit->setTextFormat(textFormat); - textEdit->setText(text); - - if (textFormat == QQuickTextEdit::RichText - || (textFormat == QQuickTextEdit::AutoText && Qt::mightBeRichText(text))) { - QVERIFY(textEdit->getFormattedText(start, end).contains(QRegExp(expectedText))); - } else { - QCOMPARE(textEdit->getFormattedText(start, end), expectedText); - } -} - -void tst_qquicktextedit::insert_data() -{ - QTest::addColumn("text"); - QTest::addColumn("textFormat"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("insertPosition"); - QTest::addColumn("insertText"); - QTest::addColumn("expectedText"); - QTest::addColumn("expectedSelectionStart"); - QTest::addColumn("expectedSelectionEnd"); - QTest::addColumn("expectedCursorPosition"); - QTest::addColumn("selectionChanged"); - QTest::addColumn("cursorPositionChanged"); - - QTest::newRow("at cursor position (beginning)") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 5 << 5 << 5 - << false << true; - - QTest::newRow("at cursor position (end)") - << standard.at(0) << QQuickTextEdit::PlainText - << standard.at(0).length() << standard.at(0).length() << standard.at(0).length() - << QString("Hello") - << standard.at(0) + QString("Hello") - << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5 - << false << true; - - QTest::newRow("at cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 18 << 18 << 18 - << QString("Hello") - << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) - << 23 << 23 << 23 - << false << true; - - QTest::newRow("after cursor position (beginning)") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 << 18 - << QString("Hello") - << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("before cursor position (end)") - << standard.at(0) << QQuickTextEdit::PlainText - << standard.at(0).length() << standard.at(0).length() << 18 - << QString("Hello") - << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) - << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5 - << false << true; - - QTest::newRow("before cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 18 << 18 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 23 << 23 << 23 - << false << true; - - QTest::newRow("after cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 18 << 18 << standard.at(0).length() - << QString("Hello") - << standard.at(0) + QString("Hello") - << 18 << 18 << 18 - << false << false; - - QTest::newRow("before selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 19 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 19 << 24 << 24 - << false << true; - - QTest::newRow("before reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 19 << 14 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 19 << 24 << 19 - << false << true; - - QTest::newRow("after selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 19 << standard.at(0).length() - << QString("Hello") - << standard.at(0) + QString("Hello") - << 14 << 19 << 19 - << false << false; - - QTest::newRow("after reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 19 << 14 << standard.at(0).length() - << QString("Hello") - << standard.at(0) + QString("Hello") - << 14 << 19 << 14 - << false << false; - - QTest::newRow("into selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 19 << 18 - << QString("Hello") - << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) - << 14 << 24 << 24 - << true << true; - - QTest::newRow("into reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 19 << 14 << 18 - << QString("Hello") - << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) - << 14 << 24 << 14 - << true << false; - - QTest::newRow("rich text into plain text") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 12 << 12 << 12 - << false << true; - - QTest::newRow("rich text into rich text") - << standard.at(0) << QQuickTextEdit::RichText - << 0 << 0 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 5 << 5 << 5 - << false << true; - - QTest::newRow("rich text into auto text") - << standard.at(0) << QQuickTextEdit::AutoText - << 0 << 0 << 0 - << QString("Hello") - << QString("Hello") + standard.at(0) - << 5 << 5 << 5 - << false << true; - - QTest::newRow("before start") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 << -3 - << QString("Hello") - << standard.at(0) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("past end") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 << standard.at(0).length() + 3 - << QString("Hello") - << standard.at(0) - << 0 << 0 << 0 - << false << false; -} - -void tst_qquicktextedit::insert() -{ - QFETCH(QString, text); - QFETCH(QQuickTextEdit::TextFormat, textFormat); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(int, insertPosition); - QFETCH(QString, insertText); - QFETCH(QString, expectedText); - QFETCH(int, expectedSelectionStart); - QFETCH(int, expectedSelectionEnd); - QFETCH(int, expectedCursorPosition); - QFETCH(bool, selectionChanged); - QFETCH(bool, cursorPositionChanged); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - textEdit->setTextFormat(textFormat); - textEdit->select(selectionStart, selectionEnd); - - QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged())); - QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged())); - QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged())); - QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString))); - QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged())); - - textEdit->insert(insertPosition, insertText); - - if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && ( - Qt::mightBeRichText(text) || Qt::mightBeRichText(insertText)))) { - QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText); - } else { - QCOMPARE(textEdit->text(), expectedText); - - } - QCOMPARE(textEdit->length(), expectedText.length()); - - QCOMPARE(textEdit->selectionStart(), expectedSelectionStart); - QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); - QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); - - if (selectionStart > selectionEnd) - qSwap(selectionStart, selectionEnd); - - QEXPECT_FAIL("into selection", "selectionChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("into reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue); - QCOMPARE(selectionSpy.count() > 0, selectionChanged); - QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); - QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); - QCOMPARE(textSpy.count() > 0, text != expectedText); - QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); -} - -void tst_qquicktextedit::remove_data() -{ - QTest::addColumn("text"); - QTest::addColumn("textFormat"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("removeStart"); - QTest::addColumn("removeEnd"); - QTest::addColumn("expectedText"); - QTest::addColumn("expectedSelectionStart"); - QTest::addColumn("expectedSelectionEnd"); - QTest::addColumn("expectedCursorPosition"); - QTest::addColumn("selectionChanged"); - QTest::addColumn("cursorPositionChanged"); - - const QString richBoldText = QStringLiteral("This is some bold text"); - const QString plainBoldText = QStringLiteral("This is some bold text"); - - QTest::newRow("from cursor position (beginning)") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << 0 << 5 - << standard.at(0).mid(5) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("to cursor position (beginning)") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << 5 << 0 - << standard.at(0).mid(5) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("to cursor position (end)") - << standard.at(0) << QQuickTextEdit::PlainText - << standard.at(0).length() << standard.at(0).length() - << standard.at(0).length() << standard.at(0).length() - 5 - << standard.at(0).mid(0, standard.at(0).length() - 5) - << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 - << false << true; - - QTest::newRow("to cursor position (end)") - << standard.at(0) << QQuickTextEdit::PlainText - << standard.at(0).length() << standard.at(0).length() - << standard.at(0).length() - 5 << standard.at(0).length() - << standard.at(0).mid(0, standard.at(0).length() - 5) - << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 - << false << true; - - QTest::newRow("from cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 18 << 18 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 18 << 18 << 18 - << false << false; - - QTest::newRow("to cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 23 << 23 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 18 << 18 << 18 - << false << true; - - QTest::newRow("after cursor position (beginning)") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("before cursor position (end)") - << standard.at(0) << QQuickTextEdit::PlainText - << standard.at(0).length() << standard.at(0).length() - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 - << false << true; - - QTest::newRow("before cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 23 << 23 - << 0 << 5 - << standard.at(0).mid(5) - << 18 << 18 << 18 - << false << true; - - QTest::newRow("after cursor position (middle)") - << standard.at(0) << QQuickTextEdit::PlainText - << 18 << 18 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 18 << 18 << 18 - << false << false; - - QTest::newRow("before selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 19 - << 0 << 5 - << standard.at(0).mid(5) - << 9 << 14 << 14 - << false << true; - - QTest::newRow("before reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 19 << 14 - << 0 << 5 - << standard.at(0).mid(5) - << 9 << 14 << 9 - << false << true; - - QTest::newRow("after selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 19 - << standard.at(0).length() - 5 << standard.at(0).length() - << standard.at(0).mid(0, standard.at(0).length() - 5) - << 14 << 19 << 19 - << false << false; - - QTest::newRow("after reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 19 << 14 - << standard.at(0).length() - 5 << standard.at(0).length() - << standard.at(0).mid(0, standard.at(0).length() - 5) - << 14 << 19 << 14 - << false << false; - - QTest::newRow("from selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 14 << 24 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 14 << 19 << 19 - << true << true; - - QTest::newRow("from reversed selection") - << standard.at(0) << QQuickTextEdit::PlainText - << 24 << 14 - << 18 << 23 - << standard.at(0).mid(0, 18) + standard.at(0).mid(23) - << 14 << 19 << 14 - << true << false; - - QTest::newRow("plain text cropped beginning") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << -3 << 4 - << standard.at(0).mid(4) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("plain text cropped end") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << 23 << standard.at(0).length() + 8 - << standard.at(0).mid(0, 23) - << 0 << 0 << 0 - << false << false; - - QTest::newRow("plain text cropped beginning and end") - << standard.at(0) << QQuickTextEdit::PlainText - << 0 << 0 - << -9 << standard.at(0).length() + 4 - << QString() - << 0 << 0 << 0 - << false << false; - - QTest::newRow("all rich text") - << richBoldText << QQuickTextEdit::RichText - << 0 << 0 - << 0 << plainBoldText.length() - << QString() - << 0 << 0 << 0 - << false << false; - - QTest::newRow("rick text sub string") - << richBoldText << QQuickTextEdit::RichText - << 0 << 0 - << 14 << 21 - << plainBoldText.mid(0, 14) + plainBoldText.mid(21) - << 0 << 0 << 0 - << false << false; -} - -void tst_qquicktextedit::remove() -{ - QFETCH(QString, text); - QFETCH(QQuickTextEdit::TextFormat, textFormat); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(int, removeStart); - QFETCH(int, removeEnd); - QFETCH(QString, expectedText); - QFETCH(int, expectedSelectionStart); - QFETCH(int, expectedSelectionEnd); - QFETCH(int, expectedCursorPosition); - QFETCH(bool, selectionChanged); - QFETCH(bool, cursorPositionChanged); - - QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - textEdit->setTextFormat(textFormat); - textEdit->select(selectionStart, selectionEnd); - - QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged())); - QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged())); - QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged())); - QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString))); - QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged())); - - textEdit->remove(removeStart, removeEnd); - - if (textFormat == QQuickTextEdit::RichText - || (textFormat == QQuickTextEdit::AutoText && Qt::mightBeRichText(text))) { - QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText); - } else { - QCOMPARE(textEdit->text(), expectedText); - } - QCOMPARE(textEdit->length(), expectedText.length()); - - if (selectionStart > selectionEnd) // - qSwap(selectionStart, selectionEnd); - - QCOMPARE(textEdit->selectionStart(), expectedSelectionStart); - QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); - QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); - - QEXPECT_FAIL("from selection", "selectionChanged signal isn't emitted on edits within selection", Continue); - QEXPECT_FAIL("from reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue); - QCOMPARE(selectionSpy.count() > 0, selectionChanged); - QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); - QEXPECT_FAIL("from reversed selection", "selectionEndChanged signal not emitted", Continue); - QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); - QCOMPARE(textSpy.count() > 0, text != expectedText); - - - if (cursorPositionChanged) // - QVERIFY(cursorPositionSpy.count() > 0); -} - - -void tst_qquicktextedit::keySequence_data() -{ - QTest::addColumn("text"); - QTest::addColumn("sequence"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("expectedText"); - QTest::addColumn("selectedText"); - - // standard[0] == "the [4]quick [10]brown [16]fox [20]jumped [27]over [32]the [36]lazy [41]dog" - - QTest::newRow("select all") - << standard.at(0) << QKeySequence(QKeySequence::SelectAll) << 0 << 0 - << 44 << standard.at(0) << standard.at(0); - QTest::newRow("select end of line") - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfLine) << 5 << 5 - << 44 << standard.at(0) << standard.at(0).mid(5); - QTest::newRow("select end of document") - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfDocument) << 3 << 3 - << 44 << standard.at(0) << standard.at(0).mid(3); - QTest::newRow("select end of block") - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfBlock) << 18 << 18 - << 44 << standard.at(0) << standard.at(0).mid(18); - QTest::newRow("delete end of line") - << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfLine) << 24 << 24 - << 24 << standard.at(0).mid(0, 24) << QString(); - QTest::newRow("move to start of line") - << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfLine) << 31 << 31 - << 0 << standard.at(0) << QString(); - QTest::newRow("move to start of block") - << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfBlock) << 25 << 25 - << 0 << standard.at(0) << QString(); - QTest::newRow("move to next char") - << standard.at(0) << QKeySequence(QKeySequence::MoveToNextChar) << 12 << 12 - << 13 << standard.at(0) << QString(); - QTest::newRow("move to previous char") - << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousChar) << 3 << 3 - << 2 << standard.at(0) << QString(); - QTest::newRow("select next char") - << standard.at(0) << QKeySequence(QKeySequence::SelectNextChar) << 23 << 23 - << 24 << standard.at(0) << standard.at(0).mid(23, 1); - QTest::newRow("select previous char") - << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousChar) << 19 << 19 - << 18 << standard.at(0) << standard.at(0).mid(18, 1); - QTest::newRow("move to next word") - << standard.at(0) << QKeySequence(QKeySequence::MoveToNextWord) << 7 << 7 - << 10 << standard.at(0) << QString(); - QTest::newRow("move to previous word") - << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousWord) << 7 << 7 - << 4 << standard.at(0) << QString(); - QTest::newRow("select previous word") - << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousWord) << 11 << 11 - << 10 << standard.at(0) << standard.at(0).mid(10, 1); - QTest::newRow("delete (selection)") - << standard.at(0) << QKeySequence(QKeySequence::Delete) << 12 << 15 - << 12 << (standard.at(0).mid(0, 12) + standard.at(0).mid(15)) << QString(); - QTest::newRow("delete (no selection)") - << standard.at(0) << QKeySequence(QKeySequence::Delete) << 15 << 15 - << 15 << (standard.at(0).mid(0, 15) + standard.at(0).mid(16)) << QString(); - QTest::newRow("delete end of word") - << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfWord) << 24 << 24 - << 24 << (standard.at(0).mid(0, 24) + standard.at(0).mid(27)) << QString(); - QTest::newRow("delete start of word") - << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 - << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString(); -} - -void tst_qquicktextedit::keySequence() -{ - QFETCH(QString, text); - QFETCH(QKeySequence, sequence); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(int, cursorPosition); - QFETCH(QString, expectedText); - QFETCH(QString, selectedText); - - if (sequence.isEmpty()) { - QSKIP("Key sequence is undefined"); - } - - QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true; text: \"" + text + "\" }"; - QDeclarativeComponent textEditComponent(&engine); - textEditComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); - QVERIFY(textEdit != 0); - - QQuickCanvas canvas; - textEdit->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - textEdit->select(selectionStart, selectionEnd); - - simulateKeys(&canvas, sequence); - - QCOMPARE(textEdit->cursorPosition(), cursorPosition); - QCOMPARE(textEdit->text(), expectedText); - QCOMPARE(textEdit->selectedText(), selectedText); -} - -#define NORMAL 0 -#define REPLACE_UNTIL_END 1 - -void tst_qquicktextedit::undo_data() -{ - QTest::addColumn("insertString"); - QTest::addColumn("insertIndex"); - QTest::addColumn("insertMode"); - QTest::addColumn("expectedString"); - QTest::addColumn("use_keys"); - - for (int i=0; i<2; i++) { - QString keys_str = "keyboard"; - bool use_keys = true; - if (i==0) { - keys_str = "insert"; - use_keys = false; - } - - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "1"; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "5"; - - insertIndex << 1; - insertMode << NORMAL; - insertString << "3"; - - insertIndex << 1; - insertMode << NORMAL; - insertString << "2"; - - insertIndex << 3; - insertMode << NORMAL; - insertString << "4"; - - expectedString << "12345"; - expectedString << "1235"; - expectedString << "135"; - expectedString << "15"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_numbers").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "World"; // World - - insertIndex << 0; - insertMode << NORMAL; - insertString << "Hello"; // HelloWorld - - insertIndex << 0; - insertMode << NORMAL; - insertString << "Well"; // WellHelloWorld - - insertIndex << 9; - insertMode << NORMAL; - insertString << "There"; // WellHelloThereWorld; - - expectedString << "WellHelloThereWorld"; - expectedString << "WellHelloWorld"; - expectedString << "HelloWorld"; - expectedString << "World"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "Ensuring"; - - insertIndex << -1; - insertMode << NORMAL; - insertString << " instan"; - - insertIndex << 9; - insertMode << NORMAL; - insertString << "an "; - - insertIndex << 10; - insertMode << REPLACE_UNTIL_END; - insertString << " unique instance."; - - expectedString << "Ensuring a unique instance."; - expectedString << "Ensuring a "; // ### Not present in TextInput. - expectedString << "Ensuring an instan"; - expectedString << "Ensuring instan"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_patterns").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - } -} - -void tst_qquicktextedit::undo() -{ - QFETCH(QStringList, insertString); - QFETCH(IntList, insertIndex); - QFETCH(IntList, insertMode); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - int i; - -// STEP 1: First build up an undo history by inserting or typing some strings... - for (i = 0; i < insertString.size(); ++i) { - if (insertIndex[i] > -1) - textInput->setCursorPosition(insertIndex[i]); - - // experimental stuff - if (insertMode[i] == REPLACE_UNTIL_END) { - textInput->select(insertIndex[i], insertIndex[i] + 8); - - // This is what I actually want... - // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier); - } - - for (int j = 0; j < insertString.at(i).length(); j++) - QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); - } - -// STEP 2: Next call undo several times and see if we can restore to the previous state - for (i = 0; i < expectedString.size() - 1; ++i) { - QCOMPARE(textInput->text(), expectedString[i]); - simulateKeys(&canvas, QKeySequence::Undo); - } - -// STEP 3: Verify that we have undone everything - QVERIFY(textInput->text().isEmpty()); -} - -void tst_qquicktextedit::redo_data() -{ - QTest::addColumn("insertString"); - QTest::addColumn("insertIndex"); - QTest::addColumn("expectedString"); - - { - IntList insertIndex; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertString << "World"; // World - insertIndex << 0; - insertString << "Hello"; // HelloWorld - insertIndex << 0; - insertString << "Well"; // WellHelloWorld - insertIndex << 9; - insertString << "There"; // WellHelloThereWorld; - - expectedString << "World"; - expectedString << "HelloWorld"; - expectedString << "WellHelloWorld"; - expectedString << "WellHelloThereWorld"; - - QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString; - } -} - -void tst_qquicktextedit::redo() -{ - QFETCH(QStringList, insertString); - QFETCH(IntList, insertIndex); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - int i; - // inserts the diff strings at diff positions - for (i = 0; i < insertString.size(); ++i) { - if (insertIndex[i] > -1) - textInput->setCursorPosition(insertIndex[i]); - for (int j = 0; j < insertString.at(i).length(); j++) - QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); - } - - // undo everything - while (!textInput->text().isEmpty()) - simulateKeys(&canvas, QKeySequence::Undo); - - for (i = 0; i < expectedString.size(); ++i) { - simulateKeys(&canvas, QKeySequence::Redo); - QCOMPARE(textInput->text() , expectedString[i]); - } -} - -void tst_qquicktextedit::undo_keypressevents_data() -{ - QTest::addColumn("keys"); - QTest::addColumn("expectedString"); - - { - KeyList keys; - QStringList expectedString; - - keys << "AFRAID" - << Qt::Key_Home - << "VERY" - << Qt::Key_Left - << Qt::Key_Left - << Qt::Key_Left - << Qt::Key_Left - << "BE" - << Qt::Key_End - << "!"; - - expectedString << "BEVERYAFRAID!"; - expectedString << "BEVERYAFRAID"; - expectedString << "VERYAFRAID"; - expectedString << "AFRAID"; - - QTest::newRow("Inserts and moving cursor") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting '1234' - keys << "1234" << Qt::Key_Home - // skipping '12' - << Qt::Key_Right << Qt::Key_Right - // selecting '34' - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - // deleting '34' - << Qt::Key_Delete; - - expectedString << "12"; - expectedString << "1234"; - - QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'AB12' - keys << "AB12" - << Qt::Key_Home - // selecting 'AB' - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - << Qt::Key_Delete - << QKeySequence::Undo - // ### Text is selected in text input -// << Qt::Key_Right - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - << Qt::Key_Delete; - - expectedString << "AB"; - expectedString << "AB12"; - - QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'ABCD' - keys << "abcd" - //move left two - << Qt::Key_Left << Qt::Key_Left - // inserting '1234' - << "1234" - // selecting '1234' - << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) - // overwriting '1234' with '5' - << "5" - // undoing deletion of 'AB' - << QKeySequence::Undo - // ### Text is selected in text input - << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) - // overwriting '1234' with '6' - << "6"; - - expectedString << "ab6cd"; - // for versions previous to 3.2 we overwrite needed two undo operations - expectedString << "ab1234cd"; - expectedString << "abcd"; - - QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'ABC' - keys << "ABC" - // removes 'C' - << Qt::Key_Backspace; - - expectedString << "AB"; - expectedString << "ABC"; - - QTest::newRow("Inserts,backspace") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - keys << "ABC" - // removes 'C' - << Qt::Key_Backspace - // inserting 'Z' - << "Z"; - - expectedString << "ABZ"; - expectedString << "AB"; - expectedString << "ABC"; - - QTest::newRow("Inserts,backspace,inserts") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting '123' - keys << "123" << Qt::Key_Home - // selecting '123' - << (Qt::Key_End | Qt::ShiftModifier) - // overwriting '123' with 'ABC' - << "ABC"; - - expectedString << "ABC"; - // ### One operation in TextInput. - expectedString << "A"; - expectedString << "123"; - - QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString; - } -} - -void tst_qquicktextedit::undo_keypressevents() -{ - QFETCH(KeyList, keys); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - simulateKeys(&canvas, keys); - - for (int i = 0; i < expectedString.size(); ++i) { - QCOMPARE(textInput->text() , expectedString[i]); - simulateKeys(&canvas, QKeySequence::Undo); - } - QVERIFY(textInput->text().isEmpty()); -} - -void tst_qquicktextedit::emptytags_QTBUG_22058() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-22058.qml"))); - QVERIFY(canvas.rootObject() != 0); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QQuickTextEdit *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("inputField"))); - QVERIFY(input->hasActiveFocus()); - - QInputMethodEvent event("", QList()); - event.setCommitString("Bold<"); - QGuiApplication::sendEvent(input, &event); - QCOMPARE(input->text(), QString("Bold<")); - event.setCommitString(">"); - QEXPECT_FAIL("", "Entering empty tags into a TextEdit asserts - QTBUG-22058", Abort); - QVERIFY(false); - QGuiApplication::sendEvent(input, &event); - QCOMPARE(input->text(), QString("Bold<>")); -} - -QTEST_MAIN(tst_qquicktextedit) - -#include "tst_qquicktextedit.moc" diff --git a/tests/auto/declarative/qquicktextinput/data/cursorTest.qml b/tests/auto/declarative/qquicktextinput/data/cursorTest.qml deleted file mode 100644 index 71a420ee7c..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/cursorTest.qml +++ /dev/null @@ -1,9 +0,0 @@ -import QtQuick 2.0 - -Rectangle { id:rect; width: 300; height: 300; color: "white" - property string contextualProperty: "Hello" - TextInput { text: "Hello world!"; id: textInputObject; objectName: "textInputObject" - resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ] - cursorDelegate: cursor - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/cursorVisible.qml b/tests/auto/declarative/qquicktextinput/data/cursorVisible.qml deleted file mode 100644 index 49e9386947..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/cursorVisible.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 100 - height: 20 -} diff --git a/tests/auto/declarative/qquicktextinput/data/echoMode.qml b/tests/auto/declarative/qquicktextinput/data/echoMode.qml deleted file mode 100644 index f8a6cf1c89..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/echoMode.qml +++ /dev/null @@ -1,11 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property QtObject myInput: input - - width: 400; height: 200; color: "green" - - TextInput { id: input; focus: true - text: "ABCDefgh" - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/geometrySignals.qml b/tests/auto/declarative/qquicktextinput/data/geometrySignals.qml deleted file mode 100644 index 90855a61cf..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/geometrySignals.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 400; height: 500; - property int bindingWidth: text.width - property int bindingHeight: text.height - - TextEdit { - id: text - anchors.fill: parent - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/halign_center.png b/tests/auto/declarative/qquicktextinput/data/halign_center.png deleted file mode 100644 index 53e09a8e5b..0000000000 Binary files a/tests/auto/declarative/qquicktextinput/data/halign_center.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextinput/data/halign_left.png b/tests/auto/declarative/qquicktextinput/data/halign_left.png deleted file mode 100644 index 247acbc9df..0000000000 Binary files a/tests/auto/declarative/qquicktextinput/data/halign_left.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextinput/data/halign_right.png b/tests/auto/declarative/qquicktextinput/data/halign_right.png deleted file mode 100644 index 691bc75c89..0000000000 Binary files a/tests/auto/declarative/qquicktextinput/data/halign_right.png and /dev/null differ diff --git a/tests/auto/declarative/qquicktextinput/data/horizontalAlignment.qml b/tests/auto/declarative/qquicktextinput/data/horizontalAlignment.qml deleted file mode 100644 index e0fef4c11e..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/horizontalAlignment.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 70; height: 70; - - property alias horizontalAlignment: text.horizontalAlignment - property string text: "Test" - - Rectangle { - anchors.centerIn: parent - width: 60 - height: 20 - color: "green" - - TextInput { - id: text - anchors.fill: parent - text: top.text - } - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/horizontalAlignment_RightToLeft.qml b/tests/auto/declarative/qquicktextinput/data/horizontalAlignment_RightToLeft.qml deleted file mode 100644 index 5f88025536..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/horizontalAlignment_RightToLeft.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - id: top - width: 200; height: 70; - - property alias horizontalAlignment: text.horizontalAlignment - property string text: "اختبا" - - Rectangle { - anchors.centerIn: parent - width: 180 - height: 20 - color: "green" - - TextInput { - id: text - objectName: "text" - anchors.fill: parent - text: top.text - focus: true - } - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/inputContext.qml b/tests/auto/declarative/qquicktextinput/data/inputContext.qml deleted file mode 100644 index dfc80990c6..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/inputContext.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextInput { - width: 200 - text: "supercalifra" - focus: true - cursorPosition: 12 -} diff --git a/tests/auto/declarative/qquicktextinput/data/inputMethodEvent.qml b/tests/auto/declarative/qquicktextinput/data/inputMethodEvent.qml deleted file mode 100644 index 7aefdf28f4..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/inputMethodEvent.qml +++ /dev/null @@ -1,6 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - autoScroll: false -} diff --git a/tests/auto/declarative/qquicktextinput/data/inputmethods.qml b/tests/auto/declarative/qquicktextinput/data/inputmethods.qml deleted file mode 100644 index 711e89144c..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/inputmethods.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput { - text: "Hello world!" - inputMethodHints: Qt.ImhNoPredictiveText - Keys.onLeftPressed: {} -} diff --git a/tests/auto/declarative/qquicktextinput/data/masks.qml b/tests/auto/declarative/qquicktextinput/data/masks.qml deleted file mode 100644 index 589b6a3c15..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/masks.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput{ - focus: true - objectName: "myInput" - inputMask: "HHHHhhhh; " -} diff --git a/tests/auto/declarative/qquicktextinput/data/maxLength.qml b/tests/auto/declarative/qquicktextinput/data/maxLength.qml deleted file mode 100644 index cca537ed6b..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/maxLength.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput{ - focus: true - objectName: "myInput" - maximumLength: 10 -} diff --git a/tests/auto/declarative/qquicktextinput/data/mouseselection_true.qml b/tests/auto/declarative/qquicktextinput/data/mouseselection_true.qml deleted file mode 100644 index 974041b04a..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/mouseselection_true.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true -} diff --git a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_characters.qml b/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_characters.qml deleted file mode 100644 index f7c658b618..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_characters.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true - mouseSelectionMode: TextInput.SelectCharacters -} diff --git a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_default.qml b/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_default.qml deleted file mode 100644 index 974041b04a..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_default.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true -} diff --git a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_words.qml b/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_words.qml deleted file mode 100644 index 20e777e470..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/mouseselectionmode_words.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - selectByMouse: true - mouseSelectionMode: TextInput.SelectWords -} diff --git a/tests/auto/declarative/qquicktextinput/data/navigation.qml b/tests/auto/declarative/qquicktextinput/data/navigation.qml deleted file mode 100644 index 3a7d07b3c7..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/navigation.qml +++ /dev/null @@ -1,24 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property variant myInput: input - - width: 800; height: 600; color: "blue" - - Item { - id: firstItem; - KeyNavigation.right: input - } - - TextInput { id: input; focus: true - text: "Needs some text" - KeyNavigation.left: firstItem - KeyNavigation.right: lastItem - KeyNavigation.up: firstItem - KeyNavigation.down: lastItem - } - Item { - id: lastItem - KeyNavigation.left: input - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/openInputPanel.qml b/tests/auto/declarative/qquicktextinput/data/openInputPanel.qml deleted file mode 100644 index ca5cb263aa..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/openInputPanel.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput { - width: 100; height: 100 - text: "Hello world" - focus: false -} diff --git a/tests/auto/declarative/qquicktextinput/data/positionAt.qml b/tests/auto/declarative/qquicktextinput/data/positionAt.qml deleted file mode 100644 index 1840462c87..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/positionAt.qml +++ /dev/null @@ -1,8 +0,0 @@ -import QtQuick 2.0 - -TextInput{ - focus: true - objectName: "myInput" - width: 50 - text: "AAAAAAAAAAAAAAAAAAAAAAAAAAAA" -} diff --git a/tests/auto/declarative/qquicktextinput/data/preeditAutoScroll.qml b/tests/auto/declarative/qquicktextinput/data/preeditAutoScroll.qml deleted file mode 100644 index 9d98a2e220..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/preeditAutoScroll.qml +++ /dev/null @@ -1,7 +0,0 @@ -import QtQuick 2.0 - -TextInput { - focus: true - text: "super" - autoScroll: true -} diff --git a/tests/auto/declarative/qquicktextinput/data/qtbug-19956double.qml b/tests/auto/declarative/qquicktextinput/data/qtbug-19956double.qml deleted file mode 100644 index e9b80fceb2..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/qtbug-19956double.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -TextInput { - id: textinput - property real topvalue: 30 - property real bottomvalue: 10 - height: 50 - width: 200 - text: "20" - validator: DoubleValidator { - id: doublevalidator - bottom: bottomvalue - top: topvalue - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/qtbug-19956int.qml b/tests/auto/declarative/qquicktextinput/data/qtbug-19956int.qml deleted file mode 100644 index 0d70eedb80..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/qtbug-19956int.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -TextInput { - id: textinput - property real topvalue: 30 - property real bottomvalue: 10 - height: 50 - width: 200 - text: "20" - validator: IntValidator { - id: intvalidator - bottom: bottomvalue - top: topvalue - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/qtbug-19956regexp.qml b/tests/auto/declarative/qquicktextinput/data/qtbug-19956regexp.qml deleted file mode 100644 index b5af13cc4c..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/qtbug-19956regexp.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -TextInput { - id: textinput - property variant regexvalue - height: 50 - width: 200 - text: "abc" - validator: RegExpValidator { - id: regexpvalidator - regExp: regexvalue - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/readOnly.qml b/tests/auto/declarative/qquicktextinput/data/readOnly.qml deleted file mode 100644 index 9cda7fbd1d..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/readOnly.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - property variant myInput: input - - width: 800; height: 600; color: "blue" - - TextInput { id: input; focus: true - readOnly: true - text: "I am the very model of a modern major general.\n" - } -} diff --git a/tests/auto/declarative/qquicktextinput/data/validators.qml b/tests/auto/declarative/qquicktextinput/data/validators.qml deleted file mode 100644 index 0a074ce7dc..0000000000 --- a/tests/auto/declarative/qquicktextinput/data/validators.qml +++ /dev/null @@ -1,22 +0,0 @@ -import QtQuick 2.0 - -Item { - property variant intInput: intInput - property variant dblInput: dblInput - property variant strInput: strInput - - width: 800; height: 600; - - Column{ - TextInput { id: intInput; - validator: IntValidator{top: 11; bottom: 2} - } - TextInput { id: dblInput; - validator: DoubleValidator{top: 12.12; bottom: 2.93; decimals: 2; notation: DoubleValidator.StandardNotation} - } - TextInput { id: strInput; - validator: RegExpValidator { regExp: /[a-zA-z]{2,4}/ } - } - } - -} diff --git a/tests/auto/declarative/qquicktextinput/qquicktextinput.pro b/tests/auto/declarative/qquicktextinput/qquicktextinput.pro deleted file mode 100644 index 9c74559cb2..0000000000 --- a/tests/auto/declarative/qquicktextinput/qquicktextinput.pro +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquicktextinput -macx:CONFIG -= app_bundle - -SOURCES += tst_qquicktextinput.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -QT += core-private gui-private v8-private declarative-private opengl-private testlib diff --git a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp deleted file mode 100644 index a6a9add5d5..0000000000 --- a/tests/auto/declarative/qquicktextinput/tst_qquicktextinput.cpp +++ /dev/null @@ -1,3310 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include "../shared/util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef Q_OS_MAC -#include -#endif - -#include "qplatformdefs.h" - -Q_DECLARE_METATYPE(QQuickTextInput::SelectionMode) -DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) - -QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) -{ - // XXX This will be replaced by some clever persistent platform image store. - QString persistent_dir = TESTDATA(""); - QString arch = "unknown-architecture"; // QTest needs to help with this. - - QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; - - if (!QFile::exists(expectfile)) { - actual.save(expectfile); - qWarning() << "created" << expectfile; - } - - return expectfile; -} - -typedef QPair Key; - -class tst_qquicktextinput : public QObject - -{ - Q_OBJECT -public: - tst_qquicktextinput(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void cleanup(); - void text(); - void width(); - void font(); - void color(); - void selection(); - void isRightToLeft_data(); - void isRightToLeft(); - void moveCursorSelection_data(); - void moveCursorSelection(); - void moveCursorSelectionSequence_data(); - void moveCursorSelectionSequence(); - void dragMouseSelection(); - void mouseSelectionMode_data(); - void mouseSelectionMode(); - void tripleClickSelectsAll(); - - void horizontalAlignment_data(); - void horizontalAlignment(); - void horizontalAlignment_RightToLeft(); - - void positionAt(); - - void maxLength(); - void masks(); - void validators(); - void inputMethods(); - - void passwordCharacter(); - void cursorDelegate(); - void cursorVisible(); - void cursorRectangle(); - void navigation(); - void navigation_RTL(); - void copyAndPaste(); - void copyAndPasteKeySequence(); - void canPasteEmpty(); - void canPaste(); - void readOnly(); - - void openInputPanel(); - void setHAlignClearCache(); - void focusOutClearSelection(); - - void echoMode(); -#ifdef QT_GUI_PASSWORD_ECHO_DELAY - void passwordEchoDelay(); -#endif - void geometrySignals(); - void testQtQuick11Attributes(); - void testQtQuick11Attributes_data(); - - void preeditAutoScroll(); - void preeditCursorRectangle(); - void inputContextMouseHandler(); - void inputMethodComposing(); - void cursorRectangleSize(); - - void keySequence_data(); - void keySequence(); - - void undo_data(); - void undo(); - void redo_data(); - void redo(); - void undo_keypressevents_data(); - void undo_keypressevents(); - - void QTBUG_19956(); - void QTBUG_19956_data(); - void QTBUG_19956_regexp(); - -private: - void simulateKey(QQuickView *, int key); - - void simulateKeys(QWindow *window, const QList &keys); - void simulateKeys(QWindow *window, const QKeySequence &sequence); - - QDeclarativeEngine engine; - QStringList standard; - QStringList colorStrings; -}; - -typedef QList IntList; -Q_DECLARE_METATYPE(IntList) - -typedef QList KeyList; -Q_DECLARE_METATYPE(KeyList) - -void tst_qquicktextinput::simulateKeys(QWindow *window, const QList &keys) -{ - for (int i = 0; i < keys.count(); ++i) { - const int key = keys.at(i).first; - const int modifiers = key & Qt::KeyboardModifierMask; - const QString text = !keys.at(i).second.isNull() ? QString(keys.at(i).second) : QString(); - - QKeyEvent press(QEvent::KeyPress, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); - QKeyEvent release(QEvent::KeyRelease, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); - - QGuiApplication::sendEvent(window, &press); - QGuiApplication::sendEvent(window, &release); - } -} - -void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequence) -{ - for (uint i = 0; i < sequence.count(); ++i) { - const int key = sequence[i]; - const int modifiers = key & Qt::KeyboardModifierMask; - - QTest::keyClick(window, Qt::Key(key & ~modifiers), Qt::KeyboardModifiers(modifiers)); - } -} - -QList &operator <<(QList &keys, const QKeySequence &sequence) -{ - for (uint i = 0; i < sequence.count(); ++i) - keys << Key(sequence[i], QChar()); - return keys; -} - -template QList &operator <<(QList &keys, const char (&characters)[N]) -{ - for (int i = 0; i < N - 1; ++i) { - int key = QTest::asciiToKey(characters[i]); - QChar character = QLatin1Char(characters[i]); - keys << Key(key, character); - } - return keys; -} - -QList &operator <<(QList &keys, Qt::Key key) -{ - keys << Key(key, QChar()); - return keys; -} - -void tst_qquicktextinput::initTestCase() -{ -} - -void tst_qquicktextinput::cleanupTestCase() -{ -} - -void tst_qquicktextinput::cleanup() -{ - // ensure not even skipped tests with custom input context leave it dangling - QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); - inputPanelPrivate->testContext = 0; -} - -tst_qquicktextinput::tst_qquicktextinput() -{ - standard << "the quick brown fox jumped over the lazy dog" - << "It's supercalifragisiticexpialidocious!" - << "Hello, world!" - << "!dlrow ,olleH" - << " spacey text "; - - colorStrings << "aliceblue" - << "antiquewhite" - << "aqua" - << "darkkhaki" - << "darkolivegreen" - << "dimgray" - << "palevioletred" - << "lightsteelblue" - << "#000000" - << "#AAAAAA" - << "#FFFFFF" - << "#2AC05F"; -} - -void tst_qquicktextinput::text() -{ - { - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData("import QtQuick 2.0\nTextInput { text: \"\" }", QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->text(), QString("")); - - delete textinputObject; - } - - for (int i = 0; i < standard.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->text(), standard.at(i)); - - delete textinputObject; - } - -} - -void tst_qquicktextinput::width() -{ - // uses Font metrics to find the width for standard - { - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData("import QtQuick 2.0\nTextInput { text: \"\" }", QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->width(), 0.0); - - delete textinputObject; - } - - bool requiresUnhintedMetrics = !qmlDisableDistanceField(); - - for (int i = 0; i < standard.size(); i++) - { - QFont f; - qreal metricWidth = 0.0; - if (requiresUnhintedMetrics) { - QString s = standard.at(i); - s.replace(QLatin1Char('\n'), QChar::LineSeparator); - - QTextLayout layout(s); - layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); - { - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - } - - layout.beginLayout(); - forever { - QTextLine line = layout.createLine(); - if (!line.isValid()) - break; - } - - layout.endLayout(); - - metricWidth = ceil(layout.boundingRect().width()); - } else { - QFontMetricsF fm(f); - metricWidth = fm.width(standard.at(i)); - } - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - int delta = abs(int(int(textinputObject->width()) - metricWidth)); - QVERIFY(delta <= 3.0); // As best as we can hope for cross-platform. - - delete textinputObject; - } -} - -void tst_qquicktextinput::font() -{ - //test size, then bold, then italic, then family - { - QString componentStr = "import QtQuick 2.0\nTextInput { font.pointSize: 40; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->font().pointSize(), 40); - QCOMPARE(textinputObject->font().bold(), false); - QCOMPARE(textinputObject->font().italic(), false); - - delete textinputObject; - } - - { - QString componentStr = "import QtQuick 2.0\nTextInput { font.bold: true; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->font().bold(), true); - QCOMPARE(textinputObject->font().italic(), false); - - delete textinputObject; - } - - { - QString componentStr = "import QtQuick 2.0\nTextInput { font.italic: true; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->font().italic(), true); - QCOMPARE(textinputObject->font().bold(), false); - - delete textinputObject; - } - - { - QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"Helvetica\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->font().family(), QString("Helvetica")); - QCOMPARE(textinputObject->font().bold(), false); - QCOMPARE(textinputObject->font().italic(), false); - - delete textinputObject; - } - - { - QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->font().family(), QString("")); - - delete textinputObject; - } -} - -void tst_qquicktextinput::color() -{ - //test color - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextInput { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->color(), QColor(colorStrings.at(i))); - - delete textinputObject; - } - - //test selection color - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextInput { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->selectionColor(), QColor(colorStrings.at(i))); - - delete textinputObject; - } - - //test selected text color - for (int i = 0; i < colorStrings.size(); i++) - { - QString componentStr = "import QtQuick 2.0\nTextInput { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->selectedTextColor(), QColor(colorStrings.at(i))); - - delete textinputObject; - } - - { - QString colorStr = "#AA001234"; - QColor testColor("#001234"); - testColor.setAlpha(170); - - QString componentStr = "import QtQuick 2.0\nTextInput { color: \"" + colorStr + "\"; text: \"Hello World\" }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - - QVERIFY(textinputObject != 0); - QCOMPARE(textinputObject->color(), testColor); - - delete textinputObject; - } -} - -void tst_qquicktextinput::selection() -{ - QString testStr = standard[0]; - QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - - - //Test selection follows cursor - for (int i=0; i<= testStr.size(); i++) { - textinputObject->setCursorPosition(i); - QCOMPARE(textinputObject->cursorPosition(), i); - QCOMPARE(textinputObject->selectionStart(), i); - QCOMPARE(textinputObject->selectionEnd(), i); - QVERIFY(textinputObject->selectedText().isNull()); - } - - textinputObject->setCursorPosition(0); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); - QVERIFY(textinputObject->selectedText().isNull()); - - // Verify invalid positions are ignored. - textinputObject->setCursorPosition(-1); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); - QVERIFY(textinputObject->selectedText().isNull()); - - textinputObject->setCursorPosition(textinputObject->text().count()+1); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); - QVERIFY(textinputObject->selectedText().isNull()); - - //Test selection - for (int i=0; i<= testStr.size(); i++) { - textinputObject->select(0,i); - QCOMPARE(testStr.mid(0,i), textinputObject->selectedText()); - } - for (int i=0; i<= testStr.size(); i++) { - textinputObject->select(i,testStr.size()); - QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText()); - } - - textinputObject->setCursorPosition(0); - QVERIFY(textinputObject->cursorPosition() == 0); - QVERIFY(textinputObject->selectionStart() == 0); - QVERIFY(textinputObject->selectionEnd() == 0); - QVERIFY(textinputObject->selectedText().isNull()); - - //Test Error Ignoring behaviour - textinputObject->setCursorPosition(0); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(-10,0); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(100,110); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(0,-10); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(0,100); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(0,10); - QVERIFY(textinputObject->selectedText().size() == 10); - textinputObject->select(-10,10); - QVERIFY(textinputObject->selectedText().size() == 10); - textinputObject->select(100,101); - QVERIFY(textinputObject->selectedText().size() == 10); - textinputObject->select(0,-10); - QVERIFY(textinputObject->selectedText().size() == 10); - textinputObject->select(0,100); - QVERIFY(textinputObject->selectedText().size() == 10); - - textinputObject->deselect(); - QVERIFY(textinputObject->selectedText().isNull()); - textinputObject->select(0,10); - QVERIFY(textinputObject->selectedText().size() == 10); - textinputObject->deselect(); - QVERIFY(textinputObject->selectedText().isNull()); - - // test input method selection - QSignalSpy selectionSpy(textinputObject, SIGNAL(selectedTextChanged())); - textinputObject->setFocus(true); - { - QList attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 12, 5, QVariant()); - QInputMethodEvent event("", attributes); - QApplication::sendEvent(textinputObject, &event); - } - QCOMPARE(selectionSpy.count(), 1); - QCOMPARE(textinputObject->selectionStart(), 12); - QCOMPARE(textinputObject->selectionEnd(), 17); - - delete textinputObject; -} - -void tst_qquicktextinput::isRightToLeft_data() -{ - QTest::addColumn("text"); - QTest::addColumn("emptyString"); - QTest::addColumn("firstCharacter"); - QTest::addColumn("lastCharacter"); - QTest::addColumn("middleCharacter"); - QTest::addColumn("startString"); - QTest::addColumn("midString"); - QTest::addColumn("endString"); - - const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; - QTest::newRow("Empty") << "" << false << false << false << false << false << false << false; - QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false; - QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false; - QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true; - QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true; - QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false; -} - -void tst_qquicktextinput::isRightToLeft() -{ - QFETCH(QString, text); - QFETCH(bool, emptyString); - QFETCH(bool, firstCharacter); - QFETCH(bool, lastCharacter); - QFETCH(bool, middleCharacter); - QFETCH(bool, startString); - QFETCH(bool, midString); - QFETCH(bool, endString); - - QQuickTextInput textInput; - textInput.setText(text); - - // first test that the right string is delivered to the QString::isRightToLeft() - QCOMPARE(textInput.isRightToLeft(0,0), text.mid(0,0).isRightToLeft()); - QCOMPARE(textInput.isRightToLeft(0,1), text.mid(0,1).isRightToLeft()); - QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft()); - QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft()); - QCOMPARE(textInput.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft()); - QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft()); - if (text.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, ": QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start."); - QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft()); - - // then test that the feature actually works - QCOMPARE(textInput.isRightToLeft(0,0), emptyString); - QCOMPARE(textInput.isRightToLeft(0,1), firstCharacter); - QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), lastCharacter); - QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter); - QCOMPARE(textInput.isRightToLeft(0,text.count()/4), startString); - QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), midString); - if (text.isEmpty()) - QTest::ignoreMessage(QtWarningMsg, ": QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start."); - QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), endString); -} - -void tst_qquicktextinput::moveCursorSelection_data() -{ - QTest::addColumn("testStr"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("movePosition"); - QTest::addColumn("mode"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("reversible"); - - // () contains the text selected by the cursor. - // <> contains the actual selection. - - QTest::newRow("(t)he|characters") - << standard[0] << 0 << 1 << QQuickTextInput::SelectCharacters << 0 << 1 << true; - QTest::newRow("do(g)|characters") - << standard[0] << 43 << 44 << QQuickTextInput::SelectCharacters << 43 << 44 << true; - QTest::newRow("jum(p)ed|characters") - << standard[0] << 23 << 24 << QQuickTextInput::SelectCharacters << 23 << 24 << true; - QTest::newRow("jumped( )over|characters") - << standard[0] << 26 << 27 << QQuickTextInput::SelectCharacters << 26 << 27 << true; - QTest::newRow("(the )|characters") - << standard[0] << 0 << 4 << QQuickTextInput::SelectCharacters << 0 << 4 << true; - QTest::newRow("( dog)|characters") - << standard[0] << 40 << 44 << QQuickTextInput::SelectCharacters << 40 << 44 << true; - QTest::newRow("( jumped )|characters") - << standard[0] << 19 << 27 << QQuickTextInput::SelectCharacters << 19 << 27 << true; - QTest::newRow("th(e qu)ick|characters") - << standard[0] << 2 << 6 << QQuickTextInput::SelectCharacters << 2 << 6 << true; - QTest::newRow("la(zy d)og|characters") - << standard[0] << 38 << 42 << QQuickTextInput::SelectCharacters << 38 << 42 << true; - QTest::newRow("jum(ped ov)er|characters") - << standard[0] << 23 << 29 << QQuickTextInput::SelectCharacters << 23 << 29 << true; - QTest::newRow("()the|characters") - << standard[0] << 0 << 0 << QQuickTextInput::SelectCharacters << 0 << 0 << true; - QTest::newRow("dog()|characters") - << standard[0] << 44 << 44 << QQuickTextInput::SelectCharacters << 44 << 44 << true; - QTest::newRow("jum()ped|characters") - << standard[0] << 23 << 23 << QQuickTextInput::SelectCharacters << 23 << 23 << true; - - QTest::newRow("<(t)he>|words") - << standard[0] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 3 << true; - QTest::newRow("|words") - << standard[0] << 43 << 44 << QQuickTextInput::SelectWords << 41 << 44 << true; - QTest::newRow("|words") - << standard[0] << 23 << 24 << QQuickTextInput::SelectWords << 20 << 26 << true; - QTest::newRow("over|words,ltr") - << standard[0] << 26 << 27 << QQuickTextInput::SelectWords << 20 << 27 << false; - QTest::newRow("jumped<( )over>|words,rtl") - << standard[0] << 27 << 26 << QQuickTextInput::SelectWords << 26 << 31 << false; - QTest::newRow("<(the )>quick|words,ltr") - << standard[0] << 0 << 4 << QQuickTextInput::SelectWords << 0 << 4 << false; - QTest::newRow("<(the )quick>|words,rtl") - << standard[0] << 4 << 0 << QQuickTextInput::SelectWords << 0 << 9 << false; - QTest::newRow("|words,ltr") - << standard[0] << 40 << 44 << QQuickTextInput::SelectWords << 36 << 44 << false; - QTest::newRow("lazy<( dog)>|words,rtl") - << standard[0] << 44 << 40 << QQuickTextInput::SelectWords << 40 << 44 << false; - QTest::newRow("over|words,ltr") - << standard[0] << 19 << 27 << QQuickTextInput::SelectWords << 16 << 27 << false; - QTest::newRow("fox<( jumped )over>|words,rtl") - << standard[0] << 27 << 19 << QQuickTextInput::SelectWords << 19 << 31 << false; - QTest::newRow("|words") - << standard[0] << 2 << 6 << QQuickTextInput::SelectWords << 0 << 9 << true; - QTest::newRow("") - << standard[0] << 38 << 42 << QQuickTextInput::SelectWords << 36 << 44 << true; - QTest::newRow("|words") - << standard[0] << 23 << 29 << QQuickTextInput::SelectWords << 20 << 31 << true; - QTest::newRow("<()>the|words") - << standard[0] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true; - QTest::newRow("dog<()>|words") - << standard[0] << 44 << 44 << QQuickTextInput::SelectWords << 44 << 44 << true; - QTest::newRow("jum<()>ped|words") - << standard[0] << 23 << 23 << QQuickTextInput::SelectWords << 23 << 23 << true; - - QTest::newRow("Hello<(,)> |words") - << standard[2] << 5 << 6 << QQuickTextInput::SelectWords << 5 << 6 << true; - QTest::newRow("Hello<(, )>world|words,ltr") - << standard[2] << 5 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false; - QTest::newRow("Hello<(, )world>|words,rtl") - << standard[2] << 7 << 5 << QQuickTextInput::SelectWords << 5 << 12 << false; - QTest::newRow("world|words,ltr") - << standard[2] << 3 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false; - QTest::newRow("|words,rtl") - << standard[2] << 7 << 3 << QQuickTextInput::SelectWords << 0 << 12 << false; - QTest::newRow(",|words") - << standard[2] << 3 << 5 << QQuickTextInput::SelectWords << 0 << 5 << true; - QTest::newRow("Hello<()>,|words") - << standard[2] << 5 << 5 << QQuickTextInput::SelectWords << 5 << 5 << true; - QTest::newRow("Hello,<()>|words") - << standard[2] << 6 << 6 << QQuickTextInput::SelectWords << 6 << 6 << true; - QTest::newRow("Hello<,( )>world|words,ltr") - << standard[2] << 6 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false; - QTest::newRow("Hello,<( )world>|words,rtl") - << standard[2] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false; - QTest::newRow("Hello<,( world)>|words,ltr") - << standard[2] << 6 << 12 << QQuickTextInput::SelectWords << 5 << 12 << false; - QTest::newRow("Hello,<( world)>|words,rtl") - << standard[2] << 12 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false; - QTest::newRow("Hello<,( world!)>|words,ltr") - << standard[2] << 6 << 13 << QQuickTextInput::SelectWords << 5 << 13 << false; - QTest::newRow("Hello,<( world!)>|words,rtl") - << standard[2] << 13 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false; - QTest::newRow("Hello<(, world!)>|words") - << standard[2] << 5 << 13 << QQuickTextInput::SelectWords << 5 << 13 << true; - // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings. - // QTBUG-11365 - // QTest::newRow("world<(!)>|words") - // << standard[2] << 12 << 13 << QQuickTextInput::SelectWords << 12 << 13 << true; - QTest::newRow("world!<()>)|words") - << standard[2] << 13 << 13 << QQuickTextInput::SelectWords << 13 << 13 << true; - QTest::newRow("world<()>!)|words") - << standard[2] << 12 << 12 << QQuickTextInput::SelectWords << 12 << 12 << true; - - QTest::newRow("<(,)>olleH |words") - << standard[3] << 7 << 8 << QQuickTextInput::SelectWords << 7 << 8 << true; - QTest::newRow("olleH|words,ltr") - << standard[3] << 6 << 8 << QQuickTextInput::SelectWords << 1 << 8 << false; - QTest::newRow("dlrow<( ,)>olleH|words,rtl") - << standard[3] << 8 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false; - QTest::newRow("|words,ltr") - << standard[3] << 6 << 10 << QQuickTextInput::SelectWords << 1 << 13 << false; - QTest::newRow("dlrow<( ,ol)leH>|words,rtl") - << standard[3] << 10 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false; - QTest::newRow(",<(ol)leH>,|words") - << standard[3] << 8 << 10 << QQuickTextInput::SelectWords << 8 << 13 << true; - QTest::newRow(",<()>olleH|words") - << standard[3] << 8 << 8 << QQuickTextInput::SelectWords << 8 << 8 << true; - QTest::newRow("<()>,olleH|words") - << standard[3] << 7 << 7 << QQuickTextInput::SelectWords << 7 << 7 << true; - QTest::newRow(",olleH|words,ltr") - << standard[3] << 6 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false; - QTest::newRow("dlrow<( ),>olleH|words,rtl") - << standard[3] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false; - QTest::newRow("<(dlrow )>,olleH|words,ltr") - << standard[3] << 1 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false; - QTest::newRow("<(dlrow ),>olleH|words,rtl") - << standard[3] << 7 << 1 << QQuickTextInput::SelectWords << 1 << 8 << false; - QTest::newRow("<(!dlrow )>,olleH|words,ltr") - << standard[3] << 0 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false; - QTest::newRow("<(!dlrow ),>olleH|words,rtl") - << standard[3] << 7 << 0 << QQuickTextInput::SelectWords << 0 << 8 << false; - QTest::newRow("(!dlrow ,)olleH|words") - << standard[3] << 0 << 8 << QQuickTextInput::SelectWords << 0 << 8 << true; - QTest::newRow("<(!)>dlrow|words") - << standard[3] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << true; - QTest::newRow("<()>!dlrow|words") - << standard[3] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true; - QTest::newRow("!<()>dlrow|words") - << standard[3] << 1 << 1 << QQuickTextInput::SelectWords << 1 << 1 << true; - - QTest::newRow(" text |words") - << standard[4] << 1 << 4 << QQuickTextInput::SelectWords << 1 << 7 << true; - QTest::newRow(" spacey |words") - << standard[4] << 11 << 13 << QQuickTextInput::SelectWords << 10 << 14 << false; // Should be reversible. QTBUG-11365 - QTest::newRow("<( )>spacey text |words|ltr") - << standard[4] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << false; - QTest::newRow("<( )spacey> text |words|rtl") - << standard[4] << 1 << 0 << QQuickTextInput::SelectWords << 0 << 7 << false; - QTest::newRow("spacey |words|ltr") - << standard[4] << 14 << 15 << QQuickTextInput::SelectWords << 10 << 15 << false; -// QTBUG-11365 -// QTest::newRow("spacey text<( )>|words|rtl") -// << standard[4] << 15 << 14 << QQuickTextInput::SelectWords << 14 << 15 << false; - QTest::newRow("<()> spacey text |words") - << standard[4] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << false; - QTest::newRow(" spacey text <()>|words") - << standard[4] << 15 << 15 << QQuickTextInput::SelectWords << 15 << 15 << false; -} - -void tst_qquicktextinput::moveCursorSelection() -{ - QFETCH(QString, testStr); - QFETCH(int, cursorPosition); - QFETCH(int, movePosition); - QFETCH(QQuickTextInput::SelectionMode, mode); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(bool, reversible); - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - - textinputObject->setCursorPosition(cursorPosition); - textinputObject->moveCursorSelection(movePosition, mode); - - QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); - QCOMPARE(textinputObject->selectionStart(), selectionStart); - QCOMPARE(textinputObject->selectionEnd(), selectionEnd); - - if (reversible) { - textinputObject->setCursorPosition(movePosition); - textinputObject->moveCursorSelection(cursorPosition, mode); - - QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); - QCOMPARE(textinputObject->selectionStart(), selectionStart); - QCOMPARE(textinputObject->selectionEnd(), selectionEnd); - } - - delete textinputObject; -} - -void tst_qquicktextinput::moveCursorSelectionSequence_data() -{ - QTest::addColumn("testStr"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("movePosition1"); - QTest::addColumn("movePosition2"); - QTest::addColumn("selection1Start"); - QTest::addColumn("selection1End"); - QTest::addColumn("selection2Start"); - QTest::addColumn("selection2End"); - - // () contains the text selected by the cursor. - // <> contains the actual selection. - // ^ is the revised cursor position. - // {} contains the revised selection. - - QTest::newRow("the { f^ox} jumped|ltr") - << standard[0] - << 9 << 13 << 17 - << 4 << 15 - << 4 << 19; - QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") - << standard[0] - << 13 << 9 << 17 - << 9 << 15 - << 10 << 19; - QTest::newRow("the { ^}fox jumped|ltr") - << standard[0] - << 9 << 13 << 16 - << 4 << 15 - << 4 << 16; - QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") - << standard[0] - << 13 << 9 << 16 - << 9 << 15 - << 10 << 16; - QTest::newRow("the {} fox jumped|ltr") - << standard[0] - << 9 << 13 << 15 - << 4 << 15 - << 4 << 15; - QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") - << standard[0] - << 13 << 9 << 15 - << 9 << 15 - << 10 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 10 - << 4 << 15 - << 4 << 10; - QTest::newRow("the quick<( {^bro)wn>} fox|rtl") - << standard[0] - << 13 << 9 << 10 - << 9 << 15 - << 10 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 9 - << 4 << 15 - << 4 << 9; - QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") - << standard[0] - << 13 << 9 << 9 - << 9 << 15 - << 9 << 15; - QTest::newRow("the { fox|ltr") - << standard[0] - << 9 << 13 << 7 - << 4 << 15 - << 4 << 9; - QTest::newRow("the { fox|rtl") - << standard[0] - << 13 << 9 << 7 - << 9 << 15 - << 4 << 15; - QTest::newRow("the {<^quick}( bro)wn> fox|ltr") - << standard[0] - << 9 << 13 << 4 - << 4 << 15 - << 4 << 9; - QTest::newRow("the {<^quick}( bro)wn> fox|rtl") - << standard[0] - << 13 << 9 << 4 - << 9 << 15 - << 4 << 15; - QTest::newRow("the{^ fox|ltr") - << standard[0] - << 9 << 13 << 3 - << 4 << 15 - << 3 << 9; - QTest::newRow("the{^ fox|rtl") - << standard[0] - << 13 << 9 << 3 - << 9 << 15 - << 3 << 15; - QTest::newRow("{t^he fox|ltr") - << standard[0] - << 9 << 13 << 1 - << 4 << 15 - << 0 << 9; - QTest::newRow("{t^he fox|rtl") - << standard[0] - << 13 << 9 << 1 - << 9 << 15 - << 0 << 15; - - QTest::newRow("{, w^orld}!|ltr") - << standard[2] - << 2 << 4 << 8 - << 0 << 5 - << 0 << 12; - QTest::newRow("{, w^orld}!|rtl") - << standard[2] - << 4 << 2 << 8 - << 0 << 5 - << 0 << 12; - - QTest::newRow("!{dlro^w ,}|ltr") - << standard[3] - << 9 << 11 << 5 - << 8 << 13 - << 1 << 13; - QTest::newRow("!{dlro^w ,}|rtl") - << standard[3] - << 11 << 9 << 5 - << 8 << 13 - << 1 << 13; - - QTest::newRow("{<(^} sp)acey> text |ltr") - << standard[4] - << 0 << 3 << 0 - << 0 << 7 - << 0 << 0; - QTest::newRow("{<( ^}sp)acey> text |ltr") - << standard[4] - << 0 << 3 << 1 - << 0 << 7 - << 0 << 1; - QTest::newRow("<( {s^p)acey>} text |rtl") - << standard[4] - << 3 << 0 << 2 - << 0 << 7 - << 1 << 7; - QTest::newRow("<( {^sp)acey>} text |rtl") - << standard[4] - << 3 << 0 << 1 - << 0 << 7 - << 1 << 7; - - QTest::newRow(" spacey }|rtl") - << standard[4] - << 15 << 12 << 15 - << 10 << 15 - << 15 << 15; -// QTBUG-11365 -// QTest::newRow(" spacey }|rtl") -// << standard[4] -// << 15 << 12 << 14 -// << 10 << 15 -// << 14 << 15; - QTest::newRow(" spacey {|ltr") - << standard[4] - << 12 << 15 << 13 - << 10 << 15 - << 10 << 14; -// QTBUG-11365 -// QTest::newRow(" spacey {|ltr") -// << standard[4] -// << 12 << 15 << 14 -// << 10 << 15 -// << 10 << 14; -} - -void tst_qquicktextinput::moveCursorSelectionSequence() -{ - QFETCH(QString, testStr); - QFETCH(int, cursorPosition); - QFETCH(int, movePosition1); - QFETCH(int, movePosition2); - QFETCH(int, selection1Start); - QFETCH(int, selection1End); - QFETCH(int, selection2Start); - QFETCH(int, selection2End); - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; - QDeclarativeComponent textinputComponent(&engine); - textinputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); - QVERIFY(textinputObject != 0); - - textinputObject->setCursorPosition(cursorPosition); - - textinputObject->moveCursorSelection(movePosition1, QQuickTextInput::SelectWords); - QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); - QCOMPARE(textinputObject->selectionStart(), selection1Start); - QCOMPARE(textinputObject->selectionEnd(), selection1End); - - textinputObject->moveCursorSelection(movePosition2, QQuickTextInput::SelectWords); - QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); - QCOMPARE(textinputObject->selectionStart(), selection2Start); - QCOMPARE(textinputObject->selectionEnd(), selection2End); - - delete textinputObject; -} - -void tst_qquicktextinput::dragMouseSelection() -{ - QString qmlfile = TESTDATA("mouseselection_true.qml"); - - QQuickView canvas(QUrl::fromLocalFile(qmlfile)); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *textInputObject = qobject_cast(canvas.rootObject()); - QVERIFY(textInputObject != 0); - - // press-and-drag-and-release from x1 to x2 - int x1 = 10; - int x2 = 70; - int y = textInputObject->height()/2; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2, y)); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QTest::qWait(100); - QString str1; - QVERIFY((str1 = textInputObject->selectedText()).length() > 3); - QVERIFY(str1.length() > 3); - - // press and drag the current selection. - x1 = 40; - x2 = 100; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2, y)); - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QTest::qWait(300); - QString str2 = textInputObject->selectedText(); - QVERIFY(str2.length() > 3); - - QVERIFY(str1 != str2); -} - -void tst_qquicktextinput::mouseSelectionMode_data() -{ - QTest::addColumn("qmlfile"); - QTest::addColumn("selectWords"); - - // import installed - QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true; - QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false; - QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false; -} - -void tst_qquicktextinput::mouseSelectionMode() -{ - QFETCH(QString, qmlfile); - QFETCH(bool, selectWords); - - QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - QQuickView canvas(QUrl::fromLocalFile(qmlfile)); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *textInputObject = qobject_cast(canvas.rootObject()); - QVERIFY(textInputObject != 0); - - // press-and-drag-and-release from x1 to x2 - int x1 = 10; - int x2 = 70; - int y = textInputObject->height()/2; - QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); - QTest::mouseMove(&canvas, QPoint(x2,y)); // doesn't work - QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); - QTest::qWait(300); - if (selectWords) { - QTRY_COMPARE(textInputObject->selectedText(), text); - } else { - QTRY_VERIFY(textInputObject->selectedText().length() > 3); - QVERIFY(textInputObject->selectedText() != text); - } -} - -void tst_qquicktextinput::horizontalAlignment_data() -{ - QTest::addColumn("hAlign"); - QTest::addColumn("expectfile"); - - QTest::newRow("L") << int(Qt::AlignLeft) << "halign_left"; - QTest::newRow("R") << int(Qt::AlignRight) << "halign_right"; - QTest::newRow("C") << int(Qt::AlignHCenter) << "halign_center"; -} - -void tst_qquicktextinput::horizontalAlignment() -{ - QSKIP("Image comparison of text is almost guaranteed to fail during development"); - - QFETCH(int, hAlign); - QFETCH(QString, expectfile); - - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment.qml"))); - - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - QObject *ob = canvas.rootObject(); - QVERIFY(ob != 0); - ob->setProperty("horizontalAlignment",hAlign); - QImage actual = canvas.grabFrameBuffer(); - - expectfile = createExpectedFileIfNotFound(expectfile, actual); - - QImage expect(expectfile); - - QCOMPARE(actual,expect); -} - -void tst_qquicktextinput::horizontalAlignment_RightToLeft() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml"))); - QQuickTextInput *textInput = canvas.rootObject()->findChild("text"); - QVERIFY(textInput != 0); - canvas.show(); - - const QString rtlText = textInput->text(); - - QQuickTextInputPrivate *textInputPrivate = QQuickTextInputPrivate::get(textInput); - QVERIFY(textInputPrivate != 0); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // implicit alignment should follow the reading direction of RTL text - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // explicitly left aligned - textInput->setHAlign(QQuickTextInput::AlignLeft); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); - - // explicitly right aligned - textInput->setHAlign(QQuickTextInput::AlignRight); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // explicitly center aligned - textInput->setHAlign(QQuickTextInput::AlignHCenter); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignHCenter); - QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); - QVERIFY(-textInputPrivate->hscroll + textInputPrivate->width > canvas.width()/2); - - // reseted alignment should go back to following the text reading direction - textInput->resetHAlign(); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // mirror the text item - QQuickItemPrivate::get(textInput)->setLayoutMirror(true); - - // mirrored implicit alignment should continue to follow the reading direction of the text - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // explicitly right aligned behaves as left aligned - textInput->setHAlign(QQuickTextInput::AlignRight); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignLeft); - QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); - - // mirrored explicitly left aligned behaves as right aligned - textInput->setHAlign(QQuickTextInput::AlignLeft); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); - QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignRight); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - // disable mirroring - QQuickItemPrivate::get(textInput)->setLayoutMirror(false); - QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); - textInput->resetHAlign(); - - // English text should be implicitly left aligned - textInput->setText("Hello world!"); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); - QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); - - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - // If there is no commited text, the preedit text should determine the alignment. - textInput->setText(QString()); - { QInputMethodEvent ev(rtlText, QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - { QInputMethodEvent ev("Hello world!", QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); - - // Clear pre-edit text. TextInput should maybe do this itself on setText, but that may be - // redundant as an actual input method may take care of it. - { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } - -#ifdef Q_OS_MAC - // empty text with implicit alignment follows the system locale-based - // keyboard input direction from QGuiApplication::keyboardInputDirection - QEXPECT_FAIL("", "QTBUG-18040", Abort); -#endif - textInput->setText(""); - QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight); - if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight) - QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); - else - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - textInput->setHAlign(QQuickTextInput::AlignRight); - QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); - QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); - - -#ifdef Q_OS_MAC - QEXPECT_FAIL("", "QTBUG-18040", Abort); // alignment of TextInput with no text set to it -#endif - QString componentStr = "import QtQuick 2.0\nTextInput {}"; - QDeclarativeComponent textComponent(&engine); - textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); - QQuickTextInput *textObject = qobject_cast(textComponent.create()); - QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? - QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight); - delete textObject; -} - -void tst_qquicktextinput::positionAt() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); - QVERIFY(canvas.rootObject() != 0); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); - QVERIFY(textinputObject != 0); - - // Check autoscrolled... - QFontMetrics fm(textinputObject->font()); - - int pos = textinputObject->positionAt(textinputObject->width()/2); - int textWidth = 0; - int textLeftWidthBegin = 0; - int textLeftWidthEnd = 0; - if (!qmlDisableDistanceField()) { - QTextLayout layout(textinputObject->text()); - - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - - textLeftWidthBegin = floor(line.cursorToX(pos - 1)); - textLeftWidthEnd = ceil(line.cursorToX(pos + 1)); - textWidth = floor(line.horizontalAdvance()); - } else { - textWidth = fm.width(textinputObject->text()); - textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1)); - textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1)); - } - - QVERIFY(textLeftWidthBegin <= textWidth - textinputObject->width() / 2); - QVERIFY(textLeftWidthEnd >= textWidth - textinputObject->width() / 2); - - int x = textinputObject->positionToRectangle(pos + 1).x() - 1; - QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1); - QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos); - - // Check without autoscroll... - textinputObject->setAutoScroll(false); - pos = textinputObject->positionAt(textinputObject->width()/2); - - if (!qmlDisableDistanceField()) { - QTextLayout layout(textinputObject->text()); - - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - - textLeftWidthBegin = floor(line.cursorToX(pos - 1)); - textLeftWidthEnd = ceil(line.cursorToX(pos + 1)); - } else { - textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1)); - textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1)); - } - - QVERIFY(textLeftWidthBegin <= textinputObject->width() / 2); - QVERIFY(textLeftWidthEnd >= textinputObject->width() / 2); - - x = textinputObject->positionToRectangle(pos + 1).x() - 1; - QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1); - QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos); - - const qreal x0 = textinputObject->positionToRectangle(pos).x(); - const qreal x1 = textinputObject->positionToRectangle(pos + 1).x(); - - QString preeditText = textinputObject->text().mid(0, pos); - textinputObject->setText(textinputObject->text().mid(pos)); - textinputObject->setCursorPosition(0); - - QInputMethodEvent inputEvent(preeditText, QList()); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent); - - // Check all points within the preedit text return the same position. - QCOMPARE(textinputObject->positionAt(0), 0); - QCOMPARE(textinputObject->positionAt(x0 / 2), 0); - QCOMPARE(textinputObject->positionAt(x0), 0); - - // Verify positioning returns to normal after the preedit text. - QCOMPARE(textinputObject->positionAt(x1), 1); - QCOMPARE(textinputObject->positionToRectangle(1).x(), x1); -} - -void tst_qquicktextinput::maxLength() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("maxLength.qml"))); - QVERIFY(canvas.rootObject() != 0); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); - QVERIFY(textinputObject != 0); - QVERIFY(textinputObject->text().isEmpty()); - QVERIFY(textinputObject->maxLength() == 10); - foreach (const QString &str, standard) { - QVERIFY(textinputObject->text().length() <= 10); - textinputObject->setText(str); - QVERIFY(textinputObject->text().length() <= 10); - } - - textinputObject->setText(""); - QTRY_VERIFY(textinputObject->hasActiveFocus() == true); - for (int i=0; i<20; i++) { - QTRY_COMPARE(textinputObject->text().length(), qMin(i,10)); - //simulateKey(&canvas, Qt::Key_A); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - } -} - -void tst_qquicktextinput::masks() -{ - //Not a comprehensive test of the possible masks, that's done elsewhere (QLineEdit) - //QString componentStr = "import QtQuick 2.0\nTextInput { inputMask: 'HHHHhhhh'; }"; - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("masks.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); - QVERIFY(textinputObject != 0); - QTRY_VERIFY(textinputObject->hasActiveFocus() == true); - QVERIFY(textinputObject->text().length() == 0); - QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; ")); - for (int i=0; i<10; i++) { - QTRY_COMPARE(qMin(i,8), textinputObject->text().length()); - QCOMPARE(i>=4, textinputObject->hasAcceptableInput()); - //simulateKey(&canvas, Qt::Key_A); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - } -} - -void tst_qquicktextinput::validators() -{ - // Note that this test assumes that the validators are working properly - // so you may need to run their tests first. All validators are checked - // here to ensure that their exposure to QML is working. - - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("validators.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *intInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("intInput"))); - QVERIFY(intInput); - intInput->setFocus(true); - QTRY_VERIFY(intInput->hasActiveFocus()); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(intInput->text(), QLatin1String("1")); - QCOMPARE(intInput->hasAcceptableInput(), false); - QTest::keyPress(&canvas, Qt::Key_2); - QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(intInput->text(), QLatin1String("1")); - QCOMPARE(intInput->hasAcceptableInput(), false); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QCOMPARE(intInput->text(), QLatin1String("11")); - QCOMPARE(intInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_0); - QTest::keyRelease(&canvas, Qt::Key_0, Qt::NoModifier ,10); - QTest::qWait(50); - QCOMPARE(intInput->text(), QLatin1String("11")); - QCOMPARE(intInput->hasAcceptableInput(), true); - - QQuickTextInput *dblInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("dblInput"))); - QTRY_VERIFY(dblInput); - dblInput->setFocus(true); - QVERIFY(dblInput->hasActiveFocus() == true); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("1")); - QCOMPARE(dblInput->hasAcceptableInput(), false); - QTest::keyPress(&canvas, Qt::Key_2); - QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("12")); - QCOMPARE(dblInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_Period); - QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("12.")); - QCOMPARE(dblInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("12.1")); - QCOMPARE(dblInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("12.11")); - QCOMPARE(dblInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(dblInput->text(), QLatin1String("12.11")); - QCOMPARE(dblInput->hasAcceptableInput(), true); - - QQuickTextInput *strInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("strInput"))); - QTRY_VERIFY(strInput); - strInput->setFocus(true); - QVERIFY(strInput->hasActiveFocus() == true); - QTest::keyPress(&canvas, Qt::Key_1); - QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("")); - QCOMPARE(strInput->hasAcceptableInput(), false); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("a")); - QCOMPARE(strInput->hasAcceptableInput(), false); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("aa")); - QCOMPARE(strInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("aaa")); - QCOMPARE(strInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("aaaa")); - QCOMPARE(strInput->hasAcceptableInput(), true); - QTest::keyPress(&canvas, Qt::Key_A); - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QTest::qWait(50); - QTRY_COMPARE(strInput->text(), QLatin1String("aaaa")); - QCOMPARE(strInput->hasAcceptableInput(), true); -} - -void tst_qquicktextinput::inputMethods() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethods.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - - // test input method hints - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *input = qobject_cast(canvas.rootObject()); - QVERIFY(input != 0); - QVERIFY(input->inputMethodHints() & Qt::ImhNoPredictiveText); - input->setInputMethodHints(Qt::ImhUppercaseOnly); - QVERIFY(input->inputMethodHints() & Qt::ImhUppercaseOnly); - - input->setFocus(true); - QVERIFY(input->hasActiveFocus() == true); - // test that input method event is committed - QInputMethodEvent event; - event.setCommitString( "My ", -12, 0); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); - QCOMPARE(input->text(), QString("My Hello world!")); - - input->setCursorPosition(2); - event.setCommitString("Your", -2, 2); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); - QCOMPARE(input->text(), QString("Your Hello world!")); - QCOMPARE(input->cursorPosition(), 4); - - input->setCursorPosition(7); - event.setCommitString("Goodbye", -2, 5); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); - QCOMPARE(input->text(), QString("Your Goodbye world!")); - QCOMPARE(input->cursorPosition(), 12); - - input->setCursorPosition(8); - event.setCommitString("Our", -8, 4); - QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); - QCOMPARE(input->text(), QString("Our Goodbye world!")); - QCOMPARE(input->cursorPosition(), 7); - - // test that basic tentative commit gets to text property on preedit state - input->setText(""); - QList attributes; - QInputMethodEvent preeditEvent("test", attributes); - preeditEvent.setTentativeCommitString("test"); - QApplication::sendEvent(input, &preeditEvent); - QCOMPARE(input->text(), QString("test")); - - // tentative commit not allowed present in surrounding text - QInputMethodQueryEvent queryEvent(Qt::ImSurroundingText); - QApplication::sendEvent(input, &queryEvent); - QCOMPARE(queryEvent.value(Qt::ImSurroundingText).toString(), QString("")); - - // if text with tentative commit does not validate, not allowed to be part of text property - input->setText(""); // ensure input state is reset - QValidator *validator = new QIntValidator(0, 100); - input->setValidator(validator); - QApplication::sendEvent(input, &preeditEvent); - QCOMPARE(input->text(), QString("")); - input->setValidator(0); - delete validator; -} - -/* -TextInput element should only handle left/right keys until the cursor reaches -the extent of the text, then they should ignore the keys. - -*/ -void tst_qquicktextinput::navigation() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - input->setCursorPosition(0); - QTRY_VERIFY(input->hasActiveFocus() == true); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); - //QT-2944: If text is selected, ensure we deselect upon cursor motion - input->setCursorPosition(input->text().length()); - input->select(0,input->text().length()); - QVERIFY(input->selectionStart() != input->selectionEnd()); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->selectionStart() == input->selectionEnd()); - QVERIFY(input->selectionStart() == input->text().length()); - QVERIFY(input->hasActiveFocus() == true); - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); - - // Up and Down should NOT do Home/End, even on Mac OS X (QTBUG-10438). - input->setCursorPosition(2); - QCOMPARE(input->cursorPosition(),2); - simulateKey(&canvas, Qt::Key_Up); - QCOMPARE(input->cursorPosition(),2); - simulateKey(&canvas, Qt::Key_Down); - QCOMPARE(input->cursorPosition(),2); -} - -void tst_qquicktextinput::navigation_RTL() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; - input->setText(QString::fromUtf16(arabic_str, 11)); - - input->setCursorPosition(0); - QTRY_VERIFY(input->hasActiveFocus() == true); - - // move off - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == false); - - // move back - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == true); - - input->setCursorPosition(input->text().length()); - QVERIFY(input->hasActiveFocus() == true); - - // move off - simulateKey(&canvas, Qt::Key_Left); - QVERIFY(input->hasActiveFocus() == false); - - // move back - simulateKey(&canvas, Qt::Key_Right); - QVERIFY(input->hasActiveFocus() == true); -} - -void tst_qquicktextinput::copyAndPaste() { -#ifndef QT_NO_CLIPBOARD - -#ifdef Q_OS_MAC - { - PasteboardRef pasteboard; - OSStatus status = PasteboardCreate(0, &pasteboard); - if (status == noErr) - CFRelease(pasteboard); - else - QSKIP("This machine doesn't support the clipboard"); - } -#endif - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - // copy and paste - QCOMPARE(textInput->text().length(), 12); - textInput->select(0, textInput->text().length());; - textInput->copy(); - QCOMPARE(textInput->selectedText(), QString("Hello world!")); - QCOMPARE(textInput->selectedText().length(), 12); - textInput->setCursorPosition(0); - QVERIFY(textInput->canPaste()); - textInput->paste(); - QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); - QCOMPARE(textInput->text().length(), 24); - - // can paste - QVERIFY(textInput->canPaste()); - textInput->setReadOnly(true); - QVERIFY(!textInput->canPaste()); - textInput->setReadOnly(false); - QVERIFY(textInput->canPaste()); - - // select word - textInput->setCursorPosition(0); - textInput->selectWord(); - QCOMPARE(textInput->selectedText(), QString("Hello")); - - // select all and cut - textInput->selectAll(); - textInput->cut(); - QCOMPARE(textInput->text().length(), 0); - textInput->paste(); - QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); - QCOMPARE(textInput->text().length(), 24); - - // clear copy buffer - QClipboard *clipboard = QGuiApplication::clipboard(); - QVERIFY(clipboard); - clipboard->clear(); - QVERIFY(!textInput->canPaste()); - - // test that copy functionality is disabled - // when echo mode is set to hide text/password mode - int index = 0; - while (index < 4) { - QQuickTextInput::EchoMode echoMode = QQuickTextInput::EchoMode(index); - textInput->setEchoMode(echoMode); - textInput->setText("My password"); - textInput->select(0, textInput->text().length());; - textInput->copy(); - if (echoMode == QQuickTextInput::Normal) { - QVERIFY(!clipboard->text().isEmpty()); - QCOMPARE(clipboard->text(), QString("My password")); - clipboard->clear(); - } else { - QVERIFY(clipboard->text().isEmpty()); - } - index++; - } - - delete textInput; -#endif -} - -void tst_qquicktextinput::copyAndPasteKeySequence() { -#ifndef QT_NO_CLIPBOARD - -#ifdef Q_OS_MAC - { - PasteboardRef pasteboard; - OSStatus status = PasteboardCreate(0, &pasteboard); - if (status == noErr) - CFRelease(pasteboard); - else - QSKIP("This machine doesn't support the clipboard"); - } -#endif - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - // copy and paste - QVERIFY(textInput->hasActiveFocus()); - QCOMPARE(textInput->text().length(), 12); - textInput->select(0, textInput->text().length()); - simulateKeys(&canvas, QKeySequence::Copy); - QCOMPARE(textInput->selectedText(), QString("Hello world!")); - QCOMPARE(textInput->selectedText().length(), 12); - textInput->setCursorPosition(0); - QVERIFY(textInput->canPaste()); - simulateKeys(&canvas, QKeySequence::Paste); - QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); - QCOMPARE(textInput->text().length(), 24); - - // select all and cut - simulateKeys(&canvas, QKeySequence::SelectAll); - simulateKeys(&canvas, QKeySequence::Cut); - QCOMPARE(textInput->text().length(), 0); - simulateKeys(&canvas, QKeySequence::Paste); - QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); - QCOMPARE(textInput->text().length(), 24); - - // clear copy buffer - QClipboard *clipboard = QGuiApplication::clipboard(); - QVERIFY(clipboard); - clipboard->clear(); - QVERIFY(!textInput->canPaste()); - - // test that copy functionality is disabled - // when echo mode is set to hide text/password mode - int index = 0; - while (index < 4) { - QQuickTextInput::EchoMode echoMode = QQuickTextInput::EchoMode(index); - textInput->setEchoMode(echoMode); - textInput->setText("My password"); - textInput->select(0, textInput->text().length());; - simulateKeys(&canvas, QKeySequence::Copy); - if (echoMode == QQuickTextInput::Normal) { - QVERIFY(!clipboard->text().isEmpty()); - QCOMPARE(clipboard->text(), QString("My password")); - clipboard->clear(); - } else { - QVERIFY(clipboard->text().isEmpty()); - } - index++; - } - - delete textInput; -#endif -} - -void tst_qquicktextinput::canPasteEmpty() { -#ifndef QT_NO_CLIPBOARD - - QGuiApplication::clipboard()->clear(); - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QLineControl lc; - bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0; - QCOMPARE(textInput->canPaste(), cp); - -#endif -} - -void tst_qquicktextinput::canPaste() { -#ifndef QT_NO_CLIPBOARD - - QGuiApplication::clipboard()->setText("Some text"); - - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QLineControl lc; - bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0; - QCOMPARE(textInput->canPaste(), cp); - -#endif -} - -void tst_qquicktextinput::passwordCharacter() -{ - QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - textInput->setPasswordCharacter("X"); - qreal implicitWidth = textInput->implicitWidth(); - textInput->setPasswordCharacter("."); - - // QTBUG-12383 content is updated and redrawn - QVERIFY(textInput->implicitWidth() < implicitWidth); - - delete textInput; -} - -void tst_qquicktextinput::cursorDelegate() -{ - QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml"))); - view.show(); - view.requestActivateWindow(); - QQuickTextInput *textInputObject = view.rootObject()->findChild("textInputObject"); - QVERIFY(textInputObject != 0); - QVERIFY(textInputObject->findChild("cursorInstance")); - //Test Delegate gets created - textInputObject->setFocus(true); - QQuickItem* delegateObject = textInputObject->findChild("cursorInstance"); - QVERIFY(delegateObject); - QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello")); - //Test Delegate gets moved - for (int i=0; i<= textInputObject->text().length(); i++) { - textInputObject->setCursorPosition(i); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); - } - textInputObject->setCursorPosition(0); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); - //Test Delegate gets deleted - textInputObject->setCursorDelegate(0); - QVERIFY(!textInputObject->findChild("cursorInstance")); -} - -void tst_qquicktextinput::cursorVisible() -{ - QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QQuickTextInput input; - QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool))); - - QCOMPARE(input.isCursorVisible(), false); - - input.setCursorVisible(true); - QCOMPARE(input.isCursorVisible(), true); - QCOMPARE(spy.count(), 1); - - input.setCursorVisible(false); - QCOMPARE(input.isCursorVisible(), false); - QCOMPARE(spy.count(), 2); - - input.setFocus(true); - QCOMPARE(input.isCursorVisible(), false); - QCOMPARE(spy.count(), 2); - - input.setParentItem(view.rootObject()); - QCOMPARE(input.isCursorVisible(), true); - QCOMPARE(spy.count(), 3); - - input.setFocus(false); - QCOMPARE(input.isCursorVisible(), false); - QCOMPARE(spy.count(), 4); - - input.setFocus(true); - QCOMPARE(input.isCursorVisible(), true); - QCOMPARE(spy.count(), 5); - - QQuickView alternateView; - alternateView.show(); - alternateView.requestActivateWindow(); - QTest::qWaitForWindowShown(&alternateView); - - QCOMPARE(input.isCursorVisible(), false); - QCOMPARE(spy.count(), 6); - - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QCOMPARE(input.isCursorVisible(), true); - QCOMPARE(spy.count(), 7); -} - -void tst_qquicktextinput::cursorRectangle() -{ - QSKIP("QTBUG-21689"); - - QString text = "Hello World!"; - - QQuickTextInput input; - input.setText(text); - QFontMetricsF fm(input.font()); - input.setWidth(fm.width(text.mid(0, 5))); - - QRect r; - - // some tolerance for different fonts. -#ifdef Q_OS_LINUX - const int error = 2; -#else - const int error = 5; -#endif - - - for (int i = 0; i <= 5; ++i) { - input.setCursorPosition(i); - r = input.cursorRectangle(); - int textWidth = fm.width(text.mid(0, i)); - - QVERIFY(r.left() < textWidth + error); - QVERIFY(r.right() > textWidth - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - } - - // Check the cursor rectangle remains within the input bounding rect when auto scrolling. - QVERIFY(r.left() < input.boundingRect().width()); - QVERIFY(r.right() >= input.width() - error); - - for (int i = 6; i < text.length(); ++i) { - input.setCursorPosition(i); - QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - } - - for (int i = text.length() - 2; i >= 0; --i) { - input.setCursorPosition(i); - r = input.cursorRectangle(); - QVERIFY(r.right() >= 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - } - - input.setText("Hi!"); - input.setHAlign(QQuickTextInput::AlignRight); - r = input.cursorRectangle(); - QVERIFY(r.left() < input.boundingRect().width()); - QVERIFY(r.right() >= input.width() - error); -} - -void tst_qquicktextinput::readOnly() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); - QVERIFY(input->isReadOnly() == true); - QString initial = input->text(); - for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) - simulateKey(&canvas, k); - simulateKey(&canvas, Qt::Key_Return); - simulateKey(&canvas, Qt::Key_Space); - simulateKey(&canvas, Qt::Key_Escape); - QCOMPARE(input->text(), initial); - - input->setCursorPosition(3); - input->setReadOnly(false); - QCOMPARE(input->isReadOnly(), false); - QCOMPARE(input->cursorPosition(), input->text().length()); -} - -void tst_qquicktextinput::echoMode() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml"))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QVERIFY(input != 0); - QTRY_VERIFY(input->hasActiveFocus() == true); - QString initial = input->text(); - Qt::InputMethodHints ref; - QCOMPARE(initial, QLatin1String("ABCDefgh")); - QCOMPARE(input->echoMode(), QQuickTextInput::Normal); - QCOMPARE(input->displayText(), input->text()); - //Normal - ref &= ~Qt::ImhHiddenText; - ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - QCOMPARE(input->inputMethodHints(), ref); - input->setEchoMode(QQuickTextInput::NoEcho); - QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), QLatin1String("")); - QCOMPARE(input->passwordCharacter(), QLatin1String("*")); - //NoEcho - ref |= Qt::ImhHiddenText; - ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - QCOMPARE(input->inputMethodHints(), ref); - input->setEchoMode(QQuickTextInput::Password); - //Password - ref |= Qt::ImhHiddenText; - ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), QLatin1String("********")); - QCOMPARE(input->inputMethodHints(), ref); - input->setPasswordCharacter(QChar('Q')); - QCOMPARE(input->passwordCharacter(), QLatin1String("Q")); - QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); - input->setEchoMode(QQuickTextInput::PasswordEchoOnEdit); - //PasswordEchoOnEdit - ref &= ~Qt::ImhHiddenText; - ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); - QCOMPARE(input->inputMethodHints(), ref); - QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ")); - QTest::keyPress(&canvas, Qt::Key_A);//Clearing previous entry is part of PasswordEchoOnEdit - QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); - QCOMPARE(input->text(), QLatin1String("a")); - QCOMPARE(input->displayText(), QLatin1String("a")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("a")); - input->setFocus(false); - QVERIFY(input->hasActiveFocus() == false); - QCOMPARE(input->displayText(), QLatin1String("Q")); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q")); - input->setFocus(true); - QVERIFY(input->hasActiveFocus()); - QInputMethodEvent inputEvent; - inputEvent.setCommitString(initial); - QGuiApplication::sendEvent(input, &inputEvent); - QCOMPARE(input->text(), initial); - QCOMPARE(input->displayText(), initial); - QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial); -} - -#ifdef QT_GUI_PASSWORD_ECHO_DELAY -void tst_qdeclarativetextinput::passwordEchoDelay() -{ - QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml"))); - canvas.show(); - canvas.setFocus(); - QGuiApplication::setActiveWindow(&canvas); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); - - QVERIFY(canvas.rootObject() != 0); - - QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); - - QChar fillChar = QLatin1Char('*'); - - input->setEchoMode(QDeclarativeTextInput::Password); - QCOMPARE(input->displayText(), QString(8, fillChar)); - input->setText(QString()); - QCOMPARE(input->displayText(), QString()); - - QTest::keyPress(&canvas, '0'); - QTest::keyPress(&canvas, '1'); - QTest::keyPress(&canvas, '2'); - QCOMPARE(input->displayText(), QString(2, fillChar) + QLatin1Char('2')); - QTest::keyPress(&canvas, '3'); - QTest::keyPress(&canvas, '4'); - QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4')); - QTest::keyPress(&canvas, Qt::Key_Backspace); - QCOMPARE(input->displayText(), QString(4, fillChar)); - QTest::keyPress(&canvas, '4'); - QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4')); - QTest::qWait(QT_GUI_PASSWORD_ECHO_DELAY); - QTRY_COMPARE(input->displayText(), QString(5, fillChar)); - QTest::keyPress(&canvas, '5'); - QCOMPARE(input->displayText(), QString(5, fillChar) + QLatin1Char('5')); - input->setFocus(false); - QVERIFY(!input->hasFocus()); - QCOMPARE(input->displayText(), QString(6, fillChar)); - input->setFocus(true); - QTRY_VERIFY(input->hasFocus()); - QCOMPARE(input->displayText(), QString(6, fillChar)); - QTest::keyPress(&canvas, '6'); - QCOMPARE(input->displayText(), QString(6, fillChar) + QLatin1Char('6')); - - QInputMethodEvent ev; - ev.setCommitString(QLatin1String("7")); - QGuiApplication::sendEvent(&canvas, &ev); - QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7')); -} -#endif - - -void tst_qquicktextinput::simulateKey(QQuickView *view, int key) -{ - QKeyEvent press(QKeyEvent::KeyPress, key, 0); - QKeyEvent release(QKeyEvent::KeyRelease, key, 0); - - QGuiApplication::sendEvent(view, &press); - QGuiApplication::sendEvent(view, &release); -} - -class PlatformInputContext : public QPlatformInputContext -{ -public: - PlatformInputContext() - : m_visible(false), m_action(QInputPanel::Click), m_cursorPosition(0), - m_invokeActionCallCount(0) - { - } - - virtual void showInputPanel() - { - m_visible = true; - } - virtual void hideInputPanel() - { - m_visible = false; - } - virtual bool isInputPanelVisible() const - { - return m_visible; - } - virtual void invokeAction(QInputPanel::Action action, int cursorPosition) - { - m_invokeActionCallCount++; - m_action = action; - m_cursorPosition = cursorPosition; - } - - bool m_visible; - QInputPanel::Action m_action; - int m_cursorPosition; - int m_invokeActionCallCount; -}; - -void tst_qquicktextinput::openInputPanel() -{ - PlatformInputContext platformInputContext; - QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); - inputPanelPrivate->testContext = &platformInputContext; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QQuickTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - - // check default values - QVERIFY(input->focusOnPress()); - QVERIFY(!input->hasActiveFocus()); - qDebug() << &input << qApp->inputPanel()->inputItem(); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should open on focus - QPoint centerPoint(view.width()/2, view.height()/2); - Qt::KeyboardModifiers noModifiers = 0; - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QVERIFY(input->hasActiveFocus()); - QCOMPARE(qApp->inputPanel()->inputItem(), input); - QCOMPARE(qApp->inputPanel()->visible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - - // input panel should be re-opened when pressing already focused TextInput - qApp->inputPanel()->hide(); - QCOMPARE(qApp->inputPanel()->visible(), false); - QVERIFY(input->hasActiveFocus()); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QCOMPARE(qApp->inputPanel()->visible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - - // input panel should stay visible if focus is lost to another text inputor - QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); - QQuickTextInput anotherInput; - anotherInput.setParentItem(view.rootObject()); - anotherInput.setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), true); - QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherInput)); - QCOMPARE(inputPanelVisibilitySpy.count(), 0); - - anotherInput.setFocus(false); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - QCOMPARE(view.activeFocusItem(), view.rootItem()); - anotherInput.setFocus(true); - - // input item should be null if focus is lost to an item that doesn't accept inputs - QQuickItem item; - item.setParentItem(view.rootObject()); - item.setFocus(true); - QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); - QCOMPARE(view.activeFocusItem(), &item); - - qApp->inputPanel()->hide(); - - // input panel should not be opened if TextInput is read only - input->setReadOnly(true); - input->setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - QGuiApplication::processEvents(); - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should not be opened if focusOnPress is set to false - input->setFocusOnPress(false); - input->setFocus(false); - input->setFocus(true); - QCOMPARE(qApp->inputPanel()->visible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); - QCOMPARE(qApp->inputPanel()->visible(), false); - - // input panel should open when openSoftwareInputPanel is called - input->openSoftwareInputPanel(); - QCOMPARE(qApp->inputPanel()->visible(), true); - - // input panel should close when closeSoftwareInputPanel is called - input->closeSoftwareInputPanel(); - QCOMPARE(qApp->inputPanel()->visible(), false); -} - -class MyTextInput : public QQuickTextInput -{ -public: - MyTextInput(QQuickItem *parent = 0) : QQuickTextInput(parent) - { - nbPaint = 0; - } - virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) - { - nbPaint++; - return QQuickTextInput::updatePaintNode(node, data); - } - int nbPaint; -}; - -void tst_qquicktextinput::setHAlignClearCache() -{ - QQuickView view; - MyTextInput input; - input.setText("Hello world"); - input.setParentItem(view.rootItem()); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(input.nbPaint, 1); - input.setHAlign(QQuickTextInput::AlignRight); - //Changing the alignment should trigger a repaint - QTRY_COMPARE(input.nbPaint, 2); -} - -void tst_qquicktextinput::focusOutClearSelection() -{ - QQuickView view; - QQuickTextInput input; - QQuickTextInput input2; - input.setText(QLatin1String("Hello world")); - input.setFocus(true); - input2.setParentItem(view.rootItem()); - input.setParentItem(view.rootItem()); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - input.select(2,5); - //The selection should work - QTRY_COMPARE(input.selectedText(), QLatin1String("llo")); - input2.setFocus(true); - QGuiApplication::processEvents(); - //The input lost the focus selection should be cleared - QTRY_COMPARE(input.selectedText(), QLatin1String("")); -} - -void tst_qquicktextinput::geometrySignals() -{ - QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml")); - QObject *o = component.create(); - QVERIFY(o); - QCOMPARE(o->property("bindingWidth").toInt(), 400); - QCOMPARE(o->property("bindingHeight").toInt(), 500); - delete o; -} - -void tst_qquicktextinput::testQtQuick11Attributes() -{ - QFETCH(QString, code); - QFETCH(QString, warning); - QFETCH(QString, error); - - QDeclarativeEngine engine; - QObject *obj; - - QDeclarativeComponent valid(&engine); - valid.setData("import QtQuick 2.0; TextInput { " + code.toUtf8() + " }", QUrl("")); - obj = valid.create(); - QVERIFY(obj); - QVERIFY(valid.errorString().isEmpty()); - delete obj; - - QDeclarativeComponent invalid(&engine); - invalid.setData("import QtQuick 1.0; TextInput { " + code.toUtf8() + " }", QUrl("")); - QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); - obj = invalid.create(); - QCOMPARE(invalid.errorString(), error); - delete obj; -} - -void tst_qquicktextinput::testQtQuick11Attributes_data() -{ - QTest::addColumn("code"); - QTest::addColumn("warning"); - QTest::addColumn("error"); - - QTest::newRow("canPaste") << "property bool foo: canPaste" - << ":1: ReferenceError: Can't find variable: canPaste" - << ""; - - QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" - << ":1: ReferenceError: Can't find variable: moveCursorSelection" - << ""; - - QTest::newRow("deselect") << "Component.onCompleted: deselect()" - << ":1: ReferenceError: Can't find variable: deselect" - << ""; -} - -static void sendPreeditText(const QString &text, int cursor) -{ - QInputMethodEvent event(text, QList() - << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, text.length(), QVariant())); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); -} - -void tst_qquicktextinput::preeditAutoScroll() -{ - QString preeditText = "califragisiticexpialidocious!"; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("preeditAutoScroll.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - QVERIFY(input->hasActiveFocus()); - - input->setWidth(input->implicitWidth()); - - QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged())); - int cursorRectangleChanges = 0; - - // test the text is scrolled so the preedit is visible. - sendPreeditText(preeditText.mid(0, 3), 1); - QVERIFY(input->positionAt(0) != 0); - QVERIFY(input->cursorRectangle().left() < input->boundingRect().width()); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - - // test the text is scrolled back when the preedit is removed. - QInputMethodEvent imEvent; - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - QCOMPARE(input->positionAt(0), 0); - QCOMPARE(input->positionAt(input->width()), 5); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - - QTextLayout layout(preeditText); - if (!qmlDisableDistanceField()) { - QTextOption option; - option.setUseDesignMetrics(true); - layout.setTextOption(option); - } - layout.beginLayout(); - QTextLine line = layout.createLine(); - layout.endLayout(); - - // test if the preedit is larger than the text input that the - // character preceding the cursor is still visible. - qreal x = input->positionToRectangle(0).x(); - for (int i = 0; i < 3; ++i) { - sendPreeditText(preeditText, i + 1); - int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i)); - QVERIFY(input->cursorRectangle().right() >= width - 3); - QVERIFY(input->positionToRectangle(0).x() < x); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - x = input->positionToRectangle(0).x(); - } - for (int i = 1; i >= 0; --i) { - sendPreeditText(preeditText, i + 1); - int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i)); - QVERIFY(input->cursorRectangle().right() >= width - 3); - QVERIFY(input->positionToRectangle(0).x() > x); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - x = input->positionToRectangle(0).x(); - } - - // Test incrementing the preedit cursor doesn't cause further - // scrolling when right most text is visible. - sendPreeditText(preeditText, preeditText.length() - 3); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - x = input->positionToRectangle(0).x(); - for (int i = 2; i >= 0; --i) { - sendPreeditText(preeditText, preeditText.length() - i); - QCOMPARE(input->positionToRectangle(0).x(), x); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - } - for (int i = 1; i < 3; ++i) { - sendPreeditText(preeditText, preeditText.length() - i); - QCOMPARE(input->positionToRectangle(0).x(), x); - QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); - } - - // Test disabling auto scroll. - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - - input->setAutoScroll(false); - sendPreeditText(preeditText.mid(0, 3), 1); - QCOMPARE(input->positionAt(0), 0); - QCOMPARE(input->positionAt(input->width()), 5); -} - -void tst_qquicktextinput::preeditCursorRectangle() -{ - QString preeditText = "super"; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - - QRect currentRect; - - QInputMethodQueryEvent query(Qt::ImCursorRectangle); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - QRect previousRect = query.value(Qt::ImCursorRectangle).toRect(); - - // Verify that the micro focus rect is positioned the same for position 0 as - // it would be if there was no preedit text. - sendPreeditText(preeditText, 0); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QCOMPARE(currentRect, previousRect); - - QSignalSpy inputSpy(input, SIGNAL(cursorRectangleChanged())); - QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged())); - - // Verify that the micro focus rect moves to the left as the cursor position - // is incremented. - for (int i = 1; i <= 5; ++i) { - sendPreeditText(preeditText, i); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QVERIFY(previousRect.left() < currentRect.left()); - QVERIFY(inputSpy.count() > 0); inputSpy.clear(); - QVERIFY(panelSpy.count() > 0); panelSpy.clear(); - previousRect = currentRect; - } - - // Verify that if there is no preedit cursor then the micro focus rect is the - // same as it would be if it were positioned at the end of the preedit text. - sendPreeditText(preeditText, 0); - QInputMethodEvent imEvent(preeditText, QList()); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); - QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); - currentRect = query.value(Qt::ImCursorRectangle).toRect(); - QCOMPARE(currentRect, previousRect); - QVERIFY(inputSpy.count() > 0); - QVERIFY(panelSpy.count() > 0); -} - -void tst_qquicktextinput::inputContextMouseHandler() -{ - PlatformInputContext platformInputContext; - QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); - inputPanelPrivate->testContext = &platformInputContext; - - QString text = "supercalifragisiticexpialidocious!"; - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); - QQuickTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - - input->setFocus(true); - input->setText(""); - - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QFontMetricsF fm(input->font()); - const qreal y = fm.height() / 2; - QPoint position = QPointF(fm.width(text.mid(0, 2)), y).toPoint(); - - QInputMethodEvent inputEvent(text.mid(0, 5), QList()); - QApplication::sendEvent(input, &inputEvent); - - QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position); - QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position); - QGuiApplication::processEvents(); - - QCOMPARE(platformInputContext.m_action, QInputPanel::Click); - QCOMPARE(platformInputContext.m_invokeActionCallCount, 1); - QCOMPARE(platformInputContext.m_cursorPosition, 2); -} - -void tst_qquicktextinput::inputMethodComposing() -{ - QString text = "supercalifragisiticexpialidocious!"; - - QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - QQuickTextInput *input = qobject_cast(view.rootObject()); - QVERIFY(input); - QSignalSpy spy(input, SIGNAL(inputMethodComposingChanged())); - - QCOMPARE(input->isInputMethodComposing(), false); - { - QInputMethodEvent event(text.mid(3), QList()); - QGuiApplication::sendEvent(input, &event); - } - QCOMPARE(input->isInputMethodComposing(), true); - QCOMPARE(spy.count(), 1); - - { - QInputMethodEvent event(text.mid(12), QList()); - QGuiApplication::sendEvent(input, &event); - } - QCOMPARE(spy.count(), 1); - - { - QInputMethodEvent event; - QGuiApplication::sendEvent(input, &event); - } - QCOMPARE(input->isInputMethodComposing(), false); - QCOMPARE(spy.count(), 2); -} - -void tst_qquicktextinput::cursorRectangleSize() -{ - QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); - QVERIFY(canvas->rootObject() != 0); - QQuickTextInput *textInput = qobject_cast(canvas->rootObject()); - - // make sure cursor rectangle is not at (0,0) - textInput->setX(10); - textInput->setY(10); - textInput->setCursorPosition(3); - QVERIFY(textInput != 0); - textInput->setFocus(true); - canvas->show(); - canvas->requestActivateWindow(); - QTest::qWaitForWindowShown(canvas); - - QInputMethodQueryEvent event(Qt::ImCursorRectangle); - qApp->sendEvent(qApp->inputPanel()->inputItem(), &event); - QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - - QRect cursorRectFromItem = textInput->cursorRectangle(); - QRectF cursorRectFromPositionToRectangle = textInput->positionToRectangle(textInput->cursorPosition()); - - // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); - - // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); - - // item-canvas transform and input item transform match - QCOMPARE(QQuickItemPrivate::get(textInput)->itemToCanvasTransform(), qApp->inputPanel()->inputItemTransform()); - - // input panel cursorRectangle property and tranformed item cursor rectangle match - QRectF sceneCursorRect = QQuickItemPrivate::get(textInput)->itemToCanvasTransform().mapRect(cursorRectFromItem); - QCOMPARE(sceneCursorRect, qApp->inputPanel()->cursorRectangle()); - - delete canvas; -} - -void tst_qquicktextinput::tripleClickSelectsAll() -{ - QString qmlfile = TESTDATA("positionAt.qml"); - QQuickView view(QUrl::fromLocalFile(qmlfile)); - view.show(); - view.requestActivateWindow(); - QTest::qWaitForWindowShown(&view); - - QTRY_COMPARE(&view, qGuiApp->focusWindow()); - - QQuickTextInput* input = qobject_cast(view.rootObject()); - QVERIFY(input); - - QLatin1String hello("Hello world!"); - input->setSelectByMouse(true); - input->setText(hello); - - // Clicking on the same point inside TextInput three times in a row - // should trigger a triple click, thus selecting all the text. - QPoint pointInside = input->pos().toPoint() + QPoint(2,2); - QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); - QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside); - QGuiApplication::processEvents(); - QCOMPARE(input->selectedText(), hello); - - // Now it simulates user moving the mouse between the second and the third click. - // In this situation, we don't expect a triple click. - QPoint pointInsideButFar = QPoint(input->width(),input->height()) - QPoint(2,2); - QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); - QTest::mouseClick(&view, Qt::LeftButton, 0, pointInsideButFar); - QGuiApplication::processEvents(); - QVERIFY(input->selectedText().isEmpty()); - - // And now we press the third click too late, so no triple click event is triggered. - QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); - QGuiApplication::processEvents(); - QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 1); - QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside); - QGuiApplication::processEvents(); - QVERIFY(input->selectedText().isEmpty()); -} - -void tst_qquicktextinput::QTBUG_19956_data() -{ - QTest::addColumn("url"); - QTest::newRow("intvalidator") << "qtbug-19956int.qml"; - QTest::newRow("doublevalidator") << "qtbug-19956double.qml"; -} - -void tst_qquicktextinput::keySequence_data() -{ - QTest::addColumn("text"); - QTest::addColumn("sequence"); - QTest::addColumn("selectionStart"); - QTest::addColumn("selectionEnd"); - QTest::addColumn("cursorPosition"); - QTest::addColumn("expectedText"); - QTest::addColumn("selectedText"); - - // standard[0] == "the [4]quick [10]brown [16]fox [20]jumped [27]over [32]the [36]lazy [41]dog" - - QTest::newRow("select all") - << standard.at(0) << QKeySequence(QKeySequence::SelectAll) << 0 << 0 - << 44 << standard.at(0) << standard.at(0); - QTest::newRow("select end of line") - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfLine) << 5 << 5 - << 44 << standard.at(0) << standard.at(0).mid(5); - QTest::newRow("select end of document") // ### Not handled. - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfDocument) << 3 << 3 - << 3 << standard.at(0) << QString(); - QTest::newRow("select end of block") - << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfBlock) << 18 << 18 - << 44 << standard.at(0) << standard.at(0).mid(18); - QTest::newRow("delete end of line") - << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfLine) << 24 << 24 - << 24 << standard.at(0).mid(0, 24) << QString(); - QTest::newRow("move to start of line") - << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfLine) << 31 << 31 - << 0 << standard.at(0) << QString(); - QTest::newRow("move to start of block") - << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfBlock) << 25 << 25 - << 0 << standard.at(0) << QString(); - QTest::newRow("move to next char") - << standard.at(0) << QKeySequence(QKeySequence::MoveToNextChar) << 12 << 12 - << 13 << standard.at(0) << QString(); - QTest::newRow("move to previous char") - << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousChar) << 3 << 3 - << 2 << standard.at(0) << QString(); - QTest::newRow("select next char") - << standard.at(0) << QKeySequence(QKeySequence::SelectNextChar) << 23 << 23 - << 24 << standard.at(0) << standard.at(0).mid(23, 1); - QTest::newRow("select previous char") - << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousChar) << 19 << 19 - << 18 << standard.at(0) << standard.at(0).mid(18, 1); - QTest::newRow("move to next word") - << standard.at(0) << QKeySequence(QKeySequence::MoveToNextWord) << 7 << 7 - << 10 << standard.at(0) << QString(); - QTest::newRow("move to previous word") - << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousWord) << 7 << 7 - << 4 << standard.at(0) << QString(); - QTest::newRow("select previous word") - << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousWord) << 11 << 11 - << 10 << standard.at(0) << standard.at(0).mid(10, 1); - QTest::newRow("delete (selection)") - << standard.at(0) << QKeySequence(QKeySequence::Delete) << 12 << 15 - << 12 << (standard.at(0).mid(0, 12) + standard.at(0).mid(15)) << QString(); - QTest::newRow("delete (no selection)") - << standard.at(0) << QKeySequence(QKeySequence::Delete) << 15 << 15 - << 15 << (standard.at(0).mid(0, 15) + standard.at(0).mid(16)) << QString(); - QTest::newRow("delete end of word") - << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfWord) << 24 << 24 - << 24 << (standard.at(0).mid(0, 24) + standard.at(0).mid(27)) << QString(); - QTest::newRow("delete start of word") - << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 - << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString(); -} - -void tst_qquicktextinput::keySequence() -{ - QFETCH(QString, text); - QFETCH(QKeySequence, sequence); - QFETCH(int, selectionStart); - QFETCH(int, selectionEnd); - QFETCH(int, cursorPosition); - QFETCH(QString, expectedText); - QFETCH(QString, selectedText); - - if (sequence.isEmpty()) { - QSKIP("Key sequence is undefined"); - } - - QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; text: \"" + text + "\" }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - textInput->select(selectionStart, selectionEnd); - - simulateKeys(&canvas, sequence); - - QCOMPARE(textInput->cursorPosition(), cursorPosition); - QCOMPARE(textInput->text(), expectedText); - QCOMPARE(textInput->selectedText(), selectedText); -} - -#define NORMAL 0 -#define REPLACE_UNTIL_END 1 - -void tst_qquicktextinput::undo_data() -{ - QTest::addColumn("insertString"); - QTest::addColumn("insertIndex"); - QTest::addColumn("insertMode"); - QTest::addColumn("expectedString"); - QTest::addColumn("use_keys"); - - for (int i=0; i<2; i++) { - QString keys_str = "keyboard"; - bool use_keys = true; - if (i==0) { - keys_str = "insert"; - use_keys = false; - } - - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "1"; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "5"; - - insertIndex << 1; - insertMode << NORMAL; - insertString << "3"; - - insertIndex << 1; - insertMode << NORMAL; - insertString << "2"; - - insertIndex << 3; - insertMode << NORMAL; - insertString << "4"; - - expectedString << "12345"; - expectedString << "1235"; - expectedString << "135"; - expectedString << "15"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_numbers").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "World"; // World - - insertIndex << 0; - insertMode << NORMAL; - insertString << "Hello"; // HelloWorld - - insertIndex << 0; - insertMode << NORMAL; - insertString << "Well"; // WellHelloWorld - - insertIndex << 9; - insertMode << NORMAL; - insertString << "There"; // WellHelloThereWorld; - - expectedString << "WellHelloThereWorld"; - expectedString << "WellHelloWorld"; - expectedString << "HelloWorld"; - expectedString << "World"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - { - IntList insertIndex; - IntList insertMode; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertMode << NORMAL; - insertString << "Ensuring"; - - insertIndex << -1; - insertMode << NORMAL; - insertString << " instan"; - - insertIndex << 9; - insertMode << NORMAL; - insertString << "an "; - - insertIndex << 10; - insertMode << REPLACE_UNTIL_END; - insertString << " unique instance."; - - expectedString << "Ensuring a unique instance."; - expectedString << "Ensuring an instan"; - expectedString << "Ensuring instan"; - expectedString << ""; - - QTest::newRow(QString(keys_str + "_patterns").toLatin1()) << - insertString << - insertIndex << - insertMode << - expectedString << - bool(use_keys); - } - } -} - -void tst_qquicktextinput::undo() -{ - QFETCH(QStringList, insertString); - QFETCH(IntList, insertIndex); - QFETCH(IntList, insertMode); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - int i; - -// STEP 1: First build up an undo history by inserting or typing some strings... - for (i = 0; i < insertString.size(); ++i) { - if (insertIndex[i] > -1) - textInput->setCursorPosition(insertIndex[i]); - - // experimental stuff - if (insertMode[i] == REPLACE_UNTIL_END) { - textInput->select(insertIndex[i], insertIndex[i] + 8); - - // This is what I actually want... - // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier); - } - - for (int j = 0; j < insertString.at(i).length(); j++) - QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); - } - -// STEP 2: Next call undo several times and see if we can restore to the previous state - for (i = 0; i < expectedString.size() - 1; ++i) { - QCOMPARE(textInput->text(), expectedString[i]); - simulateKeys(&canvas, QKeySequence::Undo); - } - -// STEP 3: Verify that we have undone everything - QVERIFY(textInput->text().isEmpty()); -} - -void tst_qquicktextinput::redo_data() -{ - QTest::addColumn("insertString"); - QTest::addColumn("insertIndex"); - QTest::addColumn("expectedString"); - - { - IntList insertIndex; - QStringList insertString; - QStringList expectedString; - - insertIndex << -1; - insertString << "World"; // World - insertIndex << 0; - insertString << "Hello"; // HelloWorld - insertIndex << 0; - insertString << "Well"; // WellHelloWorld - insertIndex << 9; - insertString << "There"; // WellHelloThereWorld; - - expectedString << "World"; - expectedString << "HelloWorld"; - expectedString << "WellHelloWorld"; - expectedString << "WellHelloThereWorld"; - - QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString; - } -} - -void tst_qquicktextinput::redo() -{ - QFETCH(QStringList, insertString); - QFETCH(IntList, insertIndex); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - int i; - // inserts the diff strings at diff positions - for (i = 0; i < insertString.size(); ++i) { - if (insertIndex[i] > -1) - textInput->setCursorPosition(insertIndex[i]); - for (int j = 0; j < insertString.at(i).length(); j++) - QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); - } - - // undo everything - while (!textInput->text().isEmpty()) - simulateKeys(&canvas, QKeySequence::Undo); - - for (i = 0; i < expectedString.size(); ++i) { - simulateKeys(&canvas, QKeySequence::Redo); - QCOMPARE(textInput->text() , expectedString[i]); - } -} - -void tst_qquicktextinput::undo_keypressevents_data() -{ - QTest::addColumn("keys"); - QTest::addColumn("expectedString"); - - { - KeyList keys; - QStringList expectedString; - - keys << "AFRAID" - << Qt::Key_Home - << "VERY" - << Qt::Key_Left - << Qt::Key_Left - << Qt::Key_Left - << Qt::Key_Left - << "BE" - << Qt::Key_End - << "!"; - - expectedString << "BEVERYAFRAID!"; - expectedString << "BEVERYAFRAID"; - expectedString << "VERYAFRAID"; - expectedString << "AFRAID"; - - QTest::newRow("Inserts and moving cursor") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting '1234' - keys << "1234" << Qt::Key_Home - // skipping '12' - << Qt::Key_Right << Qt::Key_Right - // selecting '34' - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - // deleting '34' - << Qt::Key_Delete; - - expectedString << "12"; - expectedString << "1234"; - - QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'AB12' - keys << "AB12" - << Qt::Key_Home - // selecting 'AB' - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - << Qt::Key_Delete - << QKeySequence::Undo - << Qt::Key_Right -#ifdef Q_OS_WIN //Mac(?) has a specialcase to handle jumping to the end of a selection - << Qt::Key_Left -#endif - << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) - << Qt::Key_Delete; - - expectedString << "AB"; - expectedString << "AB12"; - - QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'ABCD' - keys << "abcd" - //move left two - << Qt::Key_Left << Qt::Key_Left - // inserting '1234' - << "1234" - // selecting '1234' - << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) - // overwriting '1234' with '5' - << "5" - // undoing deletion of 'AB' - << QKeySequence::Undo - // overwriting '1234' with '6' - << "6"; - - expectedString << "ab6cd"; - // for versions previous to 3.2 we overwrite needed two undo operations - expectedString << "ab1234cd"; - expectedString << "abcd"; - - QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting 'ABC' - keys << "ABC" - // removes 'C' - << Qt::Key_Backspace; - - expectedString << "AB"; - expectedString << "ABC"; - - QTest::newRow("Inserts,backspace") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - keys << "ABC" - // removes 'C' - << Qt::Key_Backspace - // inserting 'Z' - << "Z"; - - expectedString << "ABZ"; - expectedString << "AB"; - expectedString << "ABC"; - - QTest::newRow("Inserts,backspace,inserts") << keys << expectedString; - } { - KeyList keys; - QStringList expectedString; - - // inserting '123' - keys << "123" << Qt::Key_Home - // selecting '123' - << (Qt::Key_End | Qt::ShiftModifier) - // overwriting '123' with 'ABC' - << "ABC"; - - expectedString << "ABC"; - // for versions previous to 3.2 we overwrite needed two undo operations - expectedString << "123"; - - QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString; - } -} - -void tst_qquicktextinput::undo_keypressevents() -{ - QFETCH(KeyList, keys); - QFETCH(QStringList, expectedString); - - QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; - QDeclarativeComponent textInputComponent(&engine); - textInputComponent.setData(componentStr.toLatin1(), QUrl()); - QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); - QVERIFY(textInput != 0); - - QQuickCanvas canvas; - textInput->setParentItem(canvas.rootItem()); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); - - simulateKeys(&canvas, keys); - - for (int i = 0; i < expectedString.size(); ++i) { - QCOMPARE(textInput->text() , expectedString[i]); - simulateKeys(&canvas, QKeySequence::Undo); - } - QVERIFY(textInput->text().isEmpty()); -} - -void tst_qquicktextinput::QTBUG_19956() -{ - QFETCH(QString, url); - - QQuickView canvas(QUrl::fromLocalFile(TESTDATA(url))); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *input = qobject_cast(canvas.rootObject()); - QVERIFY(input); - input->setFocus(true); - QVERIFY(input->hasActiveFocus()); - - QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 30); - QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10); - QCOMPARE(canvas.rootObject()->property("text").toString(), QString("20")); - QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("topvalue", 15); - QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 15); - QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("topvalue", 25); - QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 25); - QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("bottomvalue", 21); - QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 21); - QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("bottomvalue", 10); - QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10); - QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); -} - -void tst_qquicktextinput::QTBUG_19956_regexp() -{ - QUrl url = QUrl::fromLocalFile(TESTDATA("qtbug-19956regexp.qml")); - - QString warning = url.toString() + ":11: Unable to assign [undefined] to QRegExp"; - QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - - QQuickView canvas(url); - canvas.show(); - canvas.requestActivateWindow(); - QTest::qWaitForWindowShown(&canvas); - QVERIFY(canvas.rootObject() != 0); - QQuickTextInput *input = qobject_cast(canvas.rootObject()); - QVERIFY(input); - input->setFocus(true); - QVERIFY(input->hasActiveFocus()); - - canvas.rootObject()->setProperty("regexvalue", QRegExp("abc")); - QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc")); - QCOMPARE(canvas.rootObject()->property("text").toString(), QString("abc")); - QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("regexvalue", QRegExp("abcd")); - QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abcd")); - QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); - - canvas.rootObject()->setProperty("regexvalue", QRegExp("abc")); - QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc")); - QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); -} - -QTEST_MAIN(tst_qquicktextinput) - -#include "tst_qquicktextinput.moc" diff --git a/tests/auto/declarative/qquickview/data/error1.qml b/tests/auto/declarative/qquickview/data/error1.qml deleted file mode 100644 index 09df679555..0000000000 --- a/tests/auto/declarative/qquickview/data/error1.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 - -Rectangle { - nonExistentProperty: 5 -} diff --git a/tests/auto/declarative/qquickview/data/resizemodeitem.qml b/tests/auto/declarative/qquickview/data/resizemodeitem.qml deleted file mode 100644 index ed73009b26..0000000000 --- a/tests/auto/declarative/qquickview/data/resizemodeitem.qml +++ /dev/null @@ -1,5 +0,0 @@ -import QtQuick 2.0 -Item { - width: 200 - height: 200 -} diff --git a/tests/auto/declarative/qquickview/qquickview.pro b/tests/auto/declarative/qquickview/qquickview.pro deleted file mode 100644 index c5cc3ce6a7..0000000000 --- a/tests/auto/declarative/qquickview/qquickview.pro +++ /dev/null @@ -1,11 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickview -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickview.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -QT += core-private gui-private declarative-private testlib diff --git a/tests/auto/declarative/qquickview/tst_qquickview.cpp b/tests/auto/declarative/qquickview/tst_qquickview.cpp deleted file mode 100644 index fc480b5fca..0000000000 --- a/tests/auto/declarative/qquickview/tst_qquickview.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include "../shared/util.h" -#include -#include - -class tst_QQuickView : public QObject -{ - Q_OBJECT -public: - tst_QQuickView(); - -private slots: - void resizemodeitem(); - void errors(); -}; - - -tst_QQuickView::tst_QQuickView() -{ -} - -void tst_QQuickView::resizemodeitem() -{ - QWindow window; - window.setGeometry(0, 0, 400, 400); - - QQuickView *canvas = new QQuickView(&window); - QVERIFY(canvas); - canvas->setResizeMode(QQuickView::SizeRootObjectToView); - QCOMPARE(QSize(0,0), canvas->initialSize()); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); - QQuickItem* item = qobject_cast(canvas->rootObject()); - QVERIFY(item); - window.show(); - - canvas->show(); - - // initial size from root object - QCOMPARE(item->width(), 200.0); - QCOMPARE(item->height(), 200.0); - QCOMPARE(canvas->size(), QSize(200, 200)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - QCOMPARE(canvas->size(), canvas->initialSize()); - - // size update from view - canvas->resize(QSize(80,100)); - - QTRY_COMPARE(item->width(), 80.0); - QCOMPARE(item->height(), 100.0); - QCOMPARE(canvas->size(), QSize(80, 100)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - - canvas->setResizeMode(QQuickView::SizeViewToRootObject); - - // size update from view disabled - canvas->resize(QSize(60,80)); - QCOMPARE(item->width(), 80.0); - QCOMPARE(item->height(), 100.0); - QTest::qWait(50); - QCOMPARE(canvas->size(), QSize(60, 80)); - - // size update from root object - item->setWidth(250); - item->setHeight(350); - QCOMPARE(item->width(), 250.0); - QCOMPARE(item->height(), 350.0); - QTRY_COMPARE(canvas->size(), QSize(250, 350)); - QCOMPARE(canvas->size(), QSize(250, 350)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - - // reset canvas - window.hide(); - delete canvas; - canvas = new QQuickView(&window); - QVERIFY(canvas); - canvas->setResizeMode(QQuickView::SizeViewToRootObject); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); - item = qobject_cast(canvas->rootObject()); - QVERIFY(item); - window.show(); - - canvas->show(); - - // initial size for root object - QCOMPARE(item->width(), 200.0); - QCOMPARE(item->height(), 200.0); - QCOMPARE(canvas->size(), canvas->sizeHint()); - QCOMPARE(canvas->size(), canvas->initialSize()); - - // size update from root object - item->setWidth(80); - item->setHeight(100); - QCOMPARE(item->width(), 80.0); - QCOMPARE(item->height(), 100.0); - QTRY_COMPARE(canvas->size(), QSize(80, 100)); - QCOMPARE(canvas->size(), QSize(80, 100)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - - // size update from root object disabled - canvas->setResizeMode(QQuickView::SizeRootObjectToView); - item->setWidth(60); - item->setHeight(80); - QCOMPARE(canvas->width(), 80); - QCOMPARE(canvas->height(), 100); - QCOMPARE(QSize(item->width(), item->height()), canvas->sizeHint()); - - // size update from view - canvas->resize(QSize(200,300)); - QTest::qWait(50); - QCOMPARE(item->width(), 200.0); - QCOMPARE(item->height(), 300.0); - QCOMPARE(canvas->size(), QSize(200, 300)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - - window.hide(); - delete canvas; - - // if we set a specific size for the view then it should keep that size - // for SizeRootObjectToView mode. - canvas = new QQuickView(&window); - canvas->resize(300, 300); - canvas->setResizeMode(QQuickView::SizeRootObjectToView); - QCOMPARE(QSize(0,0), canvas->initialSize()); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); - canvas->resize(300, 300); - item = qobject_cast(canvas->rootObject()); - QVERIFY(item); - window.show(); - - canvas->show(); - QTest::qWait(50); - - // initial size from root object - QCOMPARE(item->width(), 300.0); - QCOMPARE(item->height(), 300.0); - QCOMPARE(canvas->size(), QSize(300, 300)); - QCOMPARE(canvas->size(), canvas->sizeHint()); - QCOMPARE(canvas->initialSize(), QSize(200, 200)); // initial object size - - delete canvas; -} - -static void silentErrorsMsgHandler(QtMsgType, const char *) -{ -} - -void tst_QQuickView::errors() -{ - QQuickView *canvas = new QQuickView; - QVERIFY(canvas); - QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler); - canvas->setSource(QUrl::fromLocalFile(TESTDATA("error1.qml"))); - qInstallMsgHandler(old); - QVERIFY(canvas->status() == QQuickView::Error); - QVERIFY(canvas->errors().count() == 1); - delete canvas; -} - - -QTEST_MAIN(tst_QQuickView) - -#include "tst_qquickview.moc" diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/create.qml b/tests/auto/declarative/qquickvisualdatamodel/data/create.qml deleted file mode 100644 index 3475a0dace..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/create.qml +++ /dev/null @@ -1,25 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 200 - height: 200 - - model: VisualDataModel { - id: visualModel - - persistedItems.includeByDefault: true - - model: myModel - delegate: Item { - id: delegate - objectName: "delegate" - width: 200 - height: 20 - - property bool destroyed: false - - - Component.onDestruction: destroyed = true - } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml deleted file mode 100644 index ae3bd81d91..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/datalist-package.qml +++ /dev/null @@ -1,20 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: visualModel.parts.package - VisualDataModel { - id: visualModel - objectName: "visualModel" - model: myModel - delegate: Package { - Rectangle { - height: 25 - width: 100 - Package.name: "package" - Text { objectName: "display"; text: display } - } - } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/datalist.qml b/tests/auto/declarative/qquickvisualdatamodel/data/datalist.qml deleted file mode 100644 index 8ce59caddc..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/datalist.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: VisualDataModel { - id: visualModel - objectName: "visualModel" - model: myModel - delegate: Component { - Rectangle { - height: 25 - width: 100 - Text { objectName: "display"; text: display } - } - } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml deleted file mode 100644 index 70c6f9f995..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/groups-invalid.qml +++ /dev/null @@ -1,14 +0,0 @@ -import QtQuick 2.0 - -VisualDataModel { - id: visualModel - - objectName: "visualModel" - - groups: [ - VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, - VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" }, - VisualDataGroup { id: unnamed; objectName: "unnamed" }, - VisualDataGroup { id: capitalised; objectName: "capitalised"; name: "Capitalised" } - ] -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml deleted file mode 100644 index ea5ad5d3bd..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/groups-package.qml +++ /dev/null @@ -1,52 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - - function contains(array, value) { - for (var i = 0; i < array.length; ++i) - if (array[i] == value) - return true - return false - } - model: visualModel.parts.package - - VisualDataModel { - id: visualModel - - objectName: "visualModel" - - groups: [ - VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, - VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" } - ] - - model: myModel - delegate: Package { - id: delegate - - property variant test1: name - property variant test2: index - property variant test3: VisualDataModel.itemsIndex - property variant test4: VisualDataModel.inItems - property variant test5: VisualDataModel.visibleIndex - property variant test6: VisualDataModel.inVisible - property variant test7: VisualDataModel.selectedIndex - property variant test8: VisualDataModel.inSelected - property variant test9: VisualDataModel.groups - - function hide() { VisualDataModel.inVisible = false } - function select() { VisualDataModel.inSelected = true } - - Item { - Package.name: "package" - - objectName: "delegate" - width: 100 - height: 2 - } - } - } - -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml b/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml deleted file mode 100644 index 7502dd2502..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/groups.qml +++ /dev/null @@ -1,46 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - - function contains(array, value) { - for (var i = 0; i < array.length; ++i) - if (array[i] == value) - return true - return false - } - - model: visualModel - VisualDataModel { - id: visualModel - - objectName: "visualModel" - - groups: [ - VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, - VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" } - ] - - model: myModel - delegate: Item { - id: delegate - - objectName: "delegate" - width: 100 - height: 2 - property variant test1: name - property variant test2: index - property variant test3: VisualDataModel.itemsIndex - property variant test4: VisualDataModel.inItems - property variant test5: VisualDataModel.visibleIndex - property variant test6: VisualDataModel.inVisible - property variant test7: VisualDataModel.selectedIndex - property variant test8: VisualDataModel.inSelected - property variant test9: VisualDataModel.groups - - function hide() { VisualDataModel.inVisible = false } - function select() { VisualDataModel.inSelected = true } - } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml deleted file mode 100644 index 103c4d2eb6..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_listView.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - - model: myModel - delegate: Item { - objectName: "delegate" - width: 100 - height: 20 - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml deleted file mode 100644 index b47f22dc34..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_package.qml +++ /dev/null @@ -1,42 +0,0 @@ -import QtQuick 2.0 - -Item { - width: 100 - height: 100 - - ListView { - anchors.fill: parent - - model: visualModel.parts.list - } - VisualDataModel { - id: visualModel - - model: myModel - delegate: Package { - Item { - Package.name: "list" - width: 100 - height: 20 - } - - Item { - id: gridItem - Package.name: "grid" - width: 50 - height: 50 - } - Rectangle { - objectName: "delegate" - parent: gridItem - width: 20 - height: 20 - } - } - } - GridView { - anchors.fill: parent - - model: visualModel.parts.grid - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml deleted file mode 100644 index bc619124fd..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml +++ /dev/null @@ -1,18 +0,0 @@ -import QtQuick 2.0 - -PathView { - width: 100 - height: 100 - - model: myModel - delegate: Item { - objectName: "delegate" - width: 100 - height: 20 - } - - path: Path { - startX: 50; startY: 0 - PathLine { x: 50; y: 100 } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml b/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml deleted file mode 100644 index e97e0dad2e..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml +++ /dev/null @@ -1,15 +0,0 @@ -import QtQuick 2.0 - -Grid { - Repeater { - width: 100 - height: 100 - - model: myModel - delegate: Item { - objectName: "delegate" - width: 50 - height: 50 - } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties.qml b/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties.qml deleted file mode 100644 index 73b766f1af..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: myModel - delegate: Item { - objectName: "delegate" - width: 100 - height: 2 - property variant test1: name - property variant test2: model.name - property variant test3: modelData - property variant test4: model.modelData - property variant test5: modelData.name - property variant test6: model - property variant test7: index - property variant test8: model.index - property variant test9: model.modelData.name - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties2.qml b/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties2.qml deleted file mode 100644 index ea5c240b29..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/modelproperties2.qml +++ /dev/null @@ -1,21 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: myModel - delegate: Item { - objectName: "delegate" - property variant test1: display - property variant test2: model.display - property variant test3: modelData - property variant test4: model.modelData - property variant test5: modelData.display - property variant test6: model - property variant test7: index - property variant test8: model.index - property variant test9: model.modelData.display - width: 100 - height: 2 - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/objectlist.qml b/tests/auto/declarative/qquickvisualdatamodel/data/objectlist.qml deleted file mode 100644 index b3952a8a4d..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/objectlist.qml +++ /dev/null @@ -1,19 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - anchors.fill: parent - model: myModel - delegate: Component { - Rectangle { - height: 25 - width: 100 - color: model.modelData.color - Text { objectName: "name"; text: name; function getText() { return name } } - Text { objectName: "section"; text: parent.ListView.section } - } - } - section.property: "name" - section.criteria: ViewSection.FullString -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml b/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml deleted file mode 100644 index 71dc7d72d7..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/onChanged.qml +++ /dev/null @@ -1,87 +0,0 @@ -import QtQuick 2.0 - -VisualDataModel { - id: vm - - property var inserted - property var removed - - Component.onCompleted: { - vm.inserted = [] - vm.removed = [] - vi.inserted = [] - vi.removed = [] - si.inserted = [] - si.removed = [] - } - - function verify(changes, indexes, counts, moveIds) { - if (changes.length != indexes.length - || changes.length != counts.length - || changes.length != moveIds.length) { - console.log("invalid length", changes.length, indexes.length, counts.length, moveIds.length) - return false - } - - var valid = true; - for (var i = 0; i < changes.length; ++i) { - if (changes[i].index != indexes[i]) { - console.log(i, "incorrect index. actual:", changes[i].index, "expected:", indexes[i]) - valid = false; - } - if (changes[i].count != counts[i]) { - console.log(i, "incorrect count. actual:", changes[i].count, "expected:", counts[i]) - valid = false; - } - if (changes[i].moveId != moveIds[i]) { - console.log(i, "incorrect moveId. actual:", changes[i].moveId, "expected:", moveIds[i]) - valid = false; - } - } - return valid - } - - groups: [ - VisualDataGroup { - id: vi; - - property var inserted - property var removed - - name: "visible" - includeByDefault: true - - onChanged: { - vi.inserted = inserted - vi.removed = removed - } - }, - VisualDataGroup { - id: si; - - property var inserted - property var removed - - name: "selected" - onChanged: { - si.inserted = inserted - si.removed = removed - } - } - ] - - model: ListModel { - id: listModel - ListElement { number: "one" } - ListElement { number: "two" } - ListElement { number: "three" } - ListElement { number: "four" } - } - - delegate: Item {} - - items.onChanged: { - vm.inserted = inserted - vm.removed = removed - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/singlerole1.qml b/tests/auto/declarative/qquickvisualdatamodel/data/singlerole1.qml deleted file mode 100644 index c471893e1d..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/singlerole1.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: myModel - delegate: Component { - Text { objectName: "name"; text: name; function getText() { return name; } } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/singlerole2.qml b/tests/auto/declarative/qquickvisualdatamodel/data/singlerole2.qml deleted file mode 100644 index ab1798999d..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/singlerole2.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick 2.0 - -ListView { - width: 100 - height: 100 - model: myModel - delegate: Component { - Text { objectName: "name"; text: modelData; function getText() { return modelData } } - } -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/data/visualdatamodel.qml b/tests/auto/declarative/qquickvisualdatamodel/data/visualdatamodel.qml deleted file mode 100644 index 0d4d9e2e46..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/data/visualdatamodel.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.0 - -VisualDataModel { - function setRoot() { - rootIndex = modelIndex(0); - } - function setRootToParent() { - rootIndex = parentModelIndex(); - } - model: myModel - delegate: Item {} -} diff --git a/tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro b/tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro deleted file mode 100644 index 35e627c1ad..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/qquickvisualdatamodel.pro +++ /dev/null @@ -1,13 +0,0 @@ -CONFIG += testcase -TARGET = tst_qquickvisualdatamodel -macx:CONFIG -= app_bundle - -SOURCES += tst_qquickvisualdatamodel.cpp - -testDataFiles.files = data -testDataFiles.path = . -DEPLOYMENT += testDataFiles - -CONFIG += parallel_test - -QT += core-private gui-private v8-private declarative-private widgets testlib diff --git a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp deleted file mode 100644 index 0278b0cf2c..0000000000 --- a/tests/auto/declarative/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp +++ /dev/null @@ -1,1865 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "../shared/util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -template int lengthOf(const T (&)[N]) { return N; } - -static void initStandardTreeModel(QStandardItemModel *model) -{ - QStandardItem *item; - item = new QStandardItem(QLatin1String("Row 1 Item")); - model->insertRow(0, item); - - item = new QStandardItem(QLatin1String("Row 2 Item")); - item->setCheckable(true); - model->insertRow(1, item); - - QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item")); - item->setChild(0, childItem); - - item = new QStandardItem(QLatin1String("Row 3 Item")); - item->setIcon(QIcon()); - model->insertRow(2, item); -} - -class SingleRoleModel : public QAbstractListModel -{ - Q_OBJECT - -public: - SingleRoleModel(const QByteArray &role = "name", QObject * /* parent */ = 0) { - QHash roles; - roles.insert(Qt::DisplayRole , role); - setRoleNames(roles); - list << "one" << "two" << "three" << "four"; - } - - void emitMove(int sourceFirst, int sourceLast, int destinationChild) { - emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild); - emit endMoveRows(); - } - - QStringList list; - -public slots: - void set(int idx, QString string) { - list[idx] = string; - emit dataChanged(index(idx,0), index(idx,0)); - } - -protected: - int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const { - return list.count(); - } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { - if (role == Qt::DisplayRole) - return list.at(index.row()); - return QVariant(); - } -}; - - -class tst_qquickvisualdatamodel : public QObject -{ - Q_OBJECT -public: - tst_qquickvisualdatamodel(); - -private slots: - void initTestCase(); - void cleanupTestCase(); - void rootIndex(); - void updateLayout_data(); - void updateLayout(); - void childChanged_data(); - void childChanged(); - void objectListModel(); - void singleRole(); - void modelProperties(); - void noDelegate_data(); - void noDelegate(); - void itemsDestroyed_data(); - void itemsDestroyed(); - void qaimRowsMoved(); - void qaimRowsMoved_data(); - void remove_data(); - void remove(); - void move_data(); - void move(); - void groups_data(); - void groups(); - void invalidGroups(); - void get(); - void onChanged_data(); - void onChanged(); - void create(); - void incompleteModel(); - -private: - template void groups_verify( - const SingleRoleModel &model, - QQuickItem *contentItem, - const int (&mIndex)[N], - const int (&iIndex)[N], - const int (&vIndex)[N], - const int (&sIndex)[N], - const bool (&vMember)[N], - const bool (&sMember)[N]); - - template void get_verify( - const SingleRoleModel &model, - QQuickVisualDataModel *visualModel, - QQuickVisualDataGroup *visibleItems, - QQuickVisualDataGroup *selectedItems, - const int (&mIndex)[N], - const int (&iIndex)[N], - const int (&vIndex)[N], - const int (&sIndex)[N], - const bool (&vMember)[N], - const bool (&sMember)[N]); - - bool failed; - QDeclarativeEngine engine; - template - T *findItem(QQuickItem *parent, const QString &objectName, int index); -}; - -Q_DECLARE_METATYPE(QDeclarativeChangeSet) - -void tst_qquickvisualdatamodel::initTestCase() -{ - qRegisterMetaType(); -} - -void tst_qquickvisualdatamodel::cleanupTestCase() -{ - -} -class DataObject : public QObject -{ - Q_OBJECT - - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) - -public: - DataObject(QObject *parent=0) : QObject(parent) {} - DataObject(const QString &name, const QString &color, QObject *parent=0) - : QObject(parent), m_name(name), m_color(color) { } - - - QString name() const { return m_name; } - void setName(const QString &name) { - if (name != m_name) { - m_name = name; - emit nameChanged(); - } - } - - QString color() const { return m_color; } - void setColor(const QString &color) { - if (color != m_color) { - m_color = color; - emit colorChanged(); - } - } - -signals: - void nameChanged(); - void colorChanged(); - -private: - QString m_name; - QString m_color; -}; - -template static T evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - T result = expr.evaluate().value(); - if (expr.hasError()) - qWarning() << expr.error().toString(); - return result; -} - -template <> void evaluate(QObject *scope, const QString &expression) -{ - QDeclarativeExpression expr(qmlContext(scope), scope, expression); - expr.evaluate(); - if (expr.hasError()) - qWarning() << expr.error().toString(); -} - -tst_qquickvisualdatamodel::tst_qquickvisualdatamodel() -{ -} - -void tst_qquickvisualdatamodel::rootIndex() -{ - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml"))); - - QStandardItemModel model; - initStandardTreeModel(&model); - - engine.rootContext()->setContextProperty("myModel", &model); - - QQuickVisualDataModel *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QMetaObject::invokeMethod(obj, "setRoot"); - QVERIFY(qvariant_cast(obj->rootIndex()) == model.index(0,0)); - - QMetaObject::invokeMethod(obj, "setRootToParent"); - QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); - - QMetaObject::invokeMethod(obj, "setRoot"); - QVERIFY(qvariant_cast(obj->rootIndex()) == model.index(0,0)); - model.clear(); // will emit modelReset() - QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); - - delete obj; -} - -void tst_qquickvisualdatamodel::updateLayout_data() -{ - QTest::addColumn("source"); - - QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); - QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); -} - -void tst_qquickvisualdatamodel::updateLayout() -{ - QFETCH(QUrl, source); - - QQuickView view; - - QStandardItemModel model; - initStandardTreeModel(&model); - - view.rootContext()->setContextProperty("myModel", &model); - - view.setSource(source); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "display", 0); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 1 Item")); - name = findItem(contentItem, "display", 1); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 2 Item")); - name = findItem(contentItem, "display", 2); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 3 Item")); - - model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder); - - name = findItem(contentItem, "display", 0); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 3 Item")); - name = findItem(contentItem, "display", 1); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 2 Item")); - name = findItem(contentItem, "display", 2); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 1 Item")); -} - -void tst_qquickvisualdatamodel::childChanged_data() -{ - QTest::addColumn("source"); - - QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); - QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); -} - -void tst_qquickvisualdatamodel::childChanged() -{ - QFETCH(QUrl, source); - - QQuickView view; - - QStandardItemModel model; - initStandardTreeModel(&model); - - view.rootContext()->setContextProperty("myModel", &model); - - view.setSource(source); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *vdm = listview->findChild("visualModel"); - vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0)))); - QCOMPARE(listview->count(), 1); - - QQuickText *name = findItem(contentItem, "display", 0); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 2 Child Item")); - - model.item(1,0)->child(0,0)->setText("Row 2 updated child"); - - name = findItem(contentItem, "display", 0); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 2 updated child")); - - model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2"))); - QCOMPARE(listview->count(), 2); - - name = findItem(contentItem, "display", 1); - QVERIFY(name != 0); - QCOMPARE(name->text(), QString("Row 2 Child Item 2")); - - model.item(1,0)->takeRow(1); - name = findItem(contentItem, "display", 1); - QVERIFY(name == 0); - - vdm->setRootIndex(QVariant::fromValue(QModelIndex())); - QCOMPARE(listview->count(), 3); - name = findItem(contentItem, "display", 0); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 1 Item")); - name = findItem(contentItem, "display", 1); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 2 Item")); - name = findItem(contentItem, "display", 2); - QVERIFY(name); - QCOMPARE(name->text(), QString("Row 3 Item")); -} - -void tst_qquickvisualdatamodel::objectListModel() -{ - QQuickView view; - - QList dataList; - dataList.append(new DataObject("Item 1", "red")); - dataList.append(new DataObject("Item 2", "green")); - dataList.append(new DataObject("Item 3", "blue")); - dataList.append(new DataObject("Item 4", "yellow")); - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); - - view.setSource(QUrl::fromLocalFile(TESTDATA("objectlist.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "name", 0); - QCOMPARE(name->text(), QString("Item 1")); - - QQuickText *section = findItem(contentItem, "section", 0); - QCOMPARE(section->text(), QString("Item 1")); - - dataList[0]->setProperty("name", QLatin1String("Changed")); - QCOMPARE(name->text(), QString("Changed")); -} - -void tst_qquickvisualdatamodel::singleRole() -{ - { - QQuickView view; - - SingleRoleModel model; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole1.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "name", 1); - QCOMPARE(name->text(), QString("two")); - - model.set(1, "Changed"); - QCOMPARE(name->text(), QString("Changed")); - } - { - QQuickView view; - - SingleRoleModel model; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "name", 1); - QCOMPARE(name->text(), QString("two")); - - model.set(1, "Changed"); - QCOMPARE(name->text(), QString("Changed")); - } - { - QQuickView view; - - SingleRoleModel model("modelData"); - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickText *name = findItem(contentItem, "name", 1); - QCOMPARE(name->text(), QString("two")); - - model.set(1, "Changed"); - QCOMPARE(name->text(), QString("Changed")); - } -} - -void tst_qquickvisualdatamodel::modelProperties() -{ - { - QQuickView view; - - SingleRoleModel model; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickItem *delegate = findItem(contentItem, "delegate", 1); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(),QString("two")); - QCOMPARE(delegate->property("test2").toString(),QString("two")); - QCOMPARE(delegate->property("test3").toString(),QString("two")); - QCOMPARE(delegate->property("test4").toString(),QString("two")); - QVERIFY(!delegate->property("test9").isValid()); - QCOMPARE(delegate->property("test5").toString(),QString("")); - QVERIFY(delegate->property("test6").value() != 0); - QCOMPARE(delegate->property("test7").toInt(),1); - QCOMPARE(delegate->property("test8").toInt(),1); - } - - { - QQuickView view; - - QList dataList; - dataList.append(new DataObject("Item 1", "red")); - dataList.append(new DataObject("Item 2", "green")); - dataList.append(new DataObject("Item 3", "blue")); - dataList.append(new DataObject("Item 4", "yellow")); - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); - - view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickItem *delegate = findItem(contentItem, "delegate", 1); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(),QString("Item 2")); - QCOMPARE(delegate->property("test2").toString(),QString("Item 2")); - QVERIFY(qobject_cast(delegate->property("test3").value()) != 0); - QVERIFY(qobject_cast(delegate->property("test4").value()) != 0); - QCOMPARE(delegate->property("test5").toString(),QString("Item 2")); - QCOMPARE(delegate->property("test9").toString(),QString("Item 2")); - QVERIFY(delegate->property("test6").value() != 0); - QCOMPARE(delegate->property("test7").toInt(),1); - QCOMPARE(delegate->property("test8").toInt(),1); - } - - { - QQuickView view; - - QStandardItemModel model; - initStandardTreeModel(&model); - - view.rootContext()->setContextProperty("myModel", &model); - - QUrl source(QUrl::fromLocalFile(TESTDATA("modelproperties2.qml"))); - - //3 items, 3 i each - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); - QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); - - view.setSource(source); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickItem *delegate = findItem(contentItem, "delegate", 1); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item")); - QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item")); - QVERIFY(!delegate->property("test3").isValid()); - QVERIFY(!delegate->property("test4").isValid()); - QVERIFY(!delegate->property("test5").isValid()); - QVERIFY(!delegate->property("test9").isValid()); - QVERIFY(delegate->property("test6").value() != 0); - QCOMPARE(delegate->property("test7").toInt(),1); - QCOMPARE(delegate->property("test8").toInt(),1); - } - - //### should also test QStringList and QVariantList -} - -void tst_qquickvisualdatamodel::noDelegate_data() -{ - QTest::addColumn("source"); - - QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); - QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); -} - -void tst_qquickvisualdatamodel::noDelegate() -{ - QFETCH(QUrl, source); - - QQuickView view; - - QStandardItemModel model; - initStandardTreeModel(&model); - - view.rootContext()->setContextProperty("myModel", &model); - - view.setSource(source); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickVisualDataModel *vdm = listview->findChild("visualModel"); - QVERIFY(vdm != 0); - QCOMPARE(vdm->count(), 3); - - vdm->setDelegate(0); - QCOMPARE(vdm->count(), 0); -} - -void tst_qquickvisualdatamodel::itemsDestroyed_data() -{ - QTest::addColumn("source"); - - QTest::newRow("listView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_listView.qml")); - QTest::newRow("package") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_package.qml")); - QTest::newRow("pathView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_pathView.qml")); - QTest::newRow("repeater") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_repeater.qml")); -} - -void tst_qquickvisualdatamodel::itemsDestroyed() -{ - QFETCH(QUrl, source); - - QDeclarativeGuard delegate; - - { - QQuickView view; - QStandardItemModel model; - initStandardTreeModel(&model); - view.rootContext()->setContextProperty("myModel", &model); - view.setSource(source); - - view.show(); - QTest::qWaitForWindowShown(&view); - - QVERIFY(delegate = findItem(view.rootItem(), "delegate", 1)); - } - QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); - QVERIFY(!delegate); -} - -void tst_qquickvisualdatamodel::qaimRowsMoved() -{ - // Test parameters passed in QAIM::rowsMoved() signal are converted correctly - // when translated and emitted as the QListModelInterface::itemsMoved() signal - QFETCH(int, sourceFirst); - QFETCH(int, sourceLast); - QFETCH(int, destinationChild); - QFETCH(int, expectFrom); - QFETCH(int, expectTo); - QFETCH(int, expectCount); - - QDeclarativeEngine engine; - QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml"))); - - SingleRoleModel model; - model.list.clear(); - for (int i=0; i<30; i++) - model.list << ("item " + i); - engine.rootContext()->setContextProperty("myModel", &model); - - QQuickVisualDataModel *obj = qobject_cast(c.create()); - QVERIFY(obj != 0); - - QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool))); - model.emitMove(sourceFirst, sourceLast, destinationChild); - // QAbstractItemModel also emits the changed signal when items are moved. - QCOMPARE(spy.count(), 2); - - bool move = false; - for (int i = 0; i < 2; ++i) { - QCOMPARE(spy[1].count(), 2); - QDeclarativeChangeSet changeSet = spy[i][0].value(); - if (!changeSet.changes().isEmpty()) - continue; - move = true; - QCOMPARE(changeSet.removes().count(), 1); - QCOMPARE(changeSet.removes().at(0).index, expectFrom); - QCOMPARE(changeSet.removes().at(0).count, expectCount); - QCOMPARE(changeSet.inserts().count(), 1); - QCOMPARE(changeSet.inserts().at(0).index, expectTo); - QCOMPARE(changeSet.inserts().at(0).count, expectCount); - QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId); - QCOMPARE(spy[i][1].toBool(), false); - } - QVERIFY(move); - - delete obj; -} - -void tst_qquickvisualdatamodel::qaimRowsMoved_data() -{ - QTest::addColumn("sourceFirst"); - QTest::addColumn("sourceLast"); - QTest::addColumn("destinationChild"); - QTest::addColumn("expectFrom"); - QTest::addColumn("expectTo"); - QTest::addColumn("expectCount"); - - QTest::newRow("move 1 forward") - << 1 << 1 << 6 - << 1 << 5 << 1; - - QTest::newRow("move 1 backwards") - << 4 << 4 << 1 - << 4 << 1 << 1; - - QTest::newRow("move multiple forwards") - << 0 << 2 << 13 - << 0 << 10 << 3; - - QTest::newRow("move multiple forwards, with same to") - << 0 << 1 << 3 - << 0 << 1 << 2; - - QTest::newRow("move multiple backwards") - << 10 << 14 << 1 - << 10 << 1 << 5; -} - -void tst_qquickvisualdatamodel::remove_data() -{ - QTest::addColumn("source"); - QTest::addColumn("package delegate"); - - QTest::newRow("item delegate") - << QUrl::fromLocalFile(TESTDATA("groups.qml")) - << QString(); - QTest::newRow("package") - << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) - << QString("package."); -} - -void tst_qquickvisualdatamodel::remove() -{ - QQuickView view; - - SingleRoleModel model; - model.list = QStringList() - << "one" - << "two" - << "three" - << "four" - << "five" - << "six" - << "seven" - << "eight" - << "nine" - << "ten" - << "eleven" - << "twelve"; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); - QVERIFY(visualModel); - - { - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.remove(2)"); - QCOMPARE(listview->count(), 11); - QCOMPARE(visualModel->items()->count(), 11); - static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.remove(1, 4)"); - QCOMPARE(listview->count(), 7); - QCOMPARE(visualModel->items()->count(), 7); - static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); - evaluate(visualModel, "items.remove(-8, 4)"); - QCOMPARE(listview->count(), 7); - QCOMPARE(visualModel->items()->count(), 7); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); - evaluate(visualModel, "items.remove(12, 2)"); - QCOMPARE(listview->count(), 7); - QCOMPARE(visualModel->items()->count(), 7); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); - evaluate(visualModel, "items.remove(5, 3)"); - QCOMPARE(listview->count(), 7); - QCOMPARE(visualModel->items()->count(), 7); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: invalid count"); - evaluate(visualModel, "items.remove(5, -2)"); - QCOMPARE(listview->count(), 7); - QCOMPARE(visualModel->items()->count(), 7); - } -} - -void tst_qquickvisualdatamodel::move_data() -{ - QTest::addColumn("source"); - QTest::addColumn("package delegate"); - - QTest::newRow("item delegate") - << QUrl::fromLocalFile(TESTDATA("groups.qml")) - << QString(); - QTest::newRow("package") - << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) - << QString("package."); -} - -void tst_qquickvisualdatamodel::move() -{ - QQuickView view; - - SingleRoleModel model; - model.list = QStringList() - << "one" - << "two" - << "three" - << "four" - << "five" - << "six" - << "seven" - << "eight" - << "nine" - << "ten" - << "eleven" - << "twelve"; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); - QVERIFY(visualModel); - - { - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.move(2, 4)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.move(4, 2)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.move(8, 0, 4)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - evaluate(visualModel, "items.move(3, 4, 5)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 }; - static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - - for (int i = 0; i < lengthOf(mIndex); ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); - QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); - QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); - } - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: invalid count"); - evaluate(visualModel, "items.move(5, 2, -2)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); - evaluate(visualModel, "items.move(-6, 2, 1)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); - evaluate(visualModel, "items.move(15, 2, 1)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); - evaluate(visualModel, "items.move(11, 1, 3)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); - evaluate(visualModel, "items.move(2, -5, 1)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); - evaluate(visualModel, "items.move(2, 14, 1)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); - evaluate(visualModel, "items.move(2, 11, 4)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } -} - -void tst_qquickvisualdatamodel::groups_data() -{ - QTest::addColumn("source"); - QTest::addColumn("part"); - - QTest::newRow("item delegate") - << QUrl::fromLocalFile(TESTDATA("groups.qml")) - << QString(); - QTest::newRow("package") - << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) - << QString("visualModel.parts.package."); -} - -template void tst_qquickvisualdatamodel::groups_verify( - const SingleRoleModel &model, - QQuickItem *contentItem, - const int (&mIndex)[N], - const int (&iIndex)[N], - const int (&vIndex)[N], - const int (&sIndex)[N], - const bool (&vMember)[N], - const bool (&sMember)[N]) -{ - failed = true; - for (int i = 0; i < N; ++i) { - QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); - QVERIFY(delegate); - QCOMPARE(evaluate(delegate, "test1"), model.list.at(mIndex[i])); - QCOMPARE(evaluate(delegate, "test2") , mIndex[i]); - QCOMPARE(evaluate(delegate, "test3") , iIndex[i]); - QCOMPARE(evaluate(delegate, "test4"), true); - QCOMPARE(evaluate(delegate, "test5") , vIndex[i]); - QCOMPARE(evaluate(delegate, "test6"), vMember[i]); - QCOMPARE(evaluate(delegate, "test7") , sIndex[i]); - QCOMPARE(evaluate(delegate, "test8"), sMember[i]); - QCOMPARE(evaluate(delegate, "test9").contains("items") , QBool(true)); - QCOMPARE(evaluate(delegate, "test9").contains("visible") , QBool(vMember[i])); - QCOMPARE(evaluate(delegate, "test9").contains("selected"), QBool(sMember[i])); - } - failed = false; -} - -#define VERIFY_GROUPS \ - groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \ - QVERIFY(!failed) - - -void tst_qquickvisualdatamodel::groups() -{ - QFETCH(QUrl, source); - QFETCH(QString, part); - - QQuickView view; - - SingleRoleModel model; - model.list = QStringList() - << "one" - << "two" - << "three" - << "four" - << "five" - << "six" - << "seven" - << "eight" - << "nine" - << "ten" - << "eleven" - << "twelve"; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(source); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *visualModel = listview->findChild("visualModel"); - QVERIFY(visualModel); - - QQuickVisualDataGroup *visibleItems = listview->findChild("visibleItems"); - QVERIFY(visibleItems); - - QQuickVisualDataGroup *selectedItems = listview->findChild("selectedItems"); - QVERIFY(selectedItems); - - const bool f = false; - const bool t = true; - - { - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 0); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f }; - VERIFY_GROUPS; - } { - evaluate(visualModel, "items.addGroups(8, \"selected\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 1); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f }; - VERIFY_GROUPS; - } { - evaluate(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 4); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 }; - static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f }; - VERIFY_GROUPS; - } { - evaluate(visualModel, "items.setGroups(2, [\"items\", \"selected\"])"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 11); - QCOMPARE(selectedItems->count(), 5); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 }; - static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 }; - static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f }; - VERIFY_GROUPS; - } { - evaluate(selectedItems, "setGroups(0, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; - static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; - VERIFY_GROUPS; - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: invalid count"); - evaluate(visualModel, "items.addGroups(11, -4, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); - evaluate(visualModel, "items.addGroups(-1, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); - evaluate(visualModel, "items.addGroups(14, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); - evaluate(visualModel, "items.addGroups(11, 5, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: invalid count"); - evaluate(visualModel, "items.setGroups(11, -4, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); - evaluate(visualModel, "items.setGroups(-1, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); - evaluate(visualModel, "items.setGroups(14, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); - evaluate(visualModel, "items.setGroups(11, 5, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: invalid count"); - evaluate(visualModel, "items.removeGroups(11, -4, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); - evaluate(visualModel, "items.removeGroups(-1, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); - evaluate(visualModel, "items.removeGroups(14, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); - evaluate(visualModel, "items.removeGroups(11, 5, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - } { - evaluate(visualModel, part + "filterOnGroup = \"visible\""); - QCOMPARE(listview->count(), 9); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("visible")); - } { - evaluate(visualModel, part + "filterOnGroup = \"selected\""); - QCOMPARE(listview->count(), 2); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("selected")); - } { - evaluate(visualModel, part + "filterOnGroup = undefined"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("items")); - } { - QQuickItem *delegate = findItem(contentItem, "delegate", 5); - QVERIFY(delegate); - - evaluate(delegate, "hide()"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 8); - QCOMPARE(selectedItems->count(), 2); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; - static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; - VERIFY_GROUPS; - } { - QQuickItem *delegate = findItem(contentItem, "delegate", 5); - QVERIFY(delegate); - - evaluate(delegate, "select()"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 8); - QCOMPARE(selectedItems->count(), 3); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; - static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 }; - static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f }; - VERIFY_GROUPS; - } { - evaluate(visualModel, "items.move(2, 6, 3)"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 8); - QCOMPARE(selectedItems->count(), 3); - static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 }; - static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 }; - static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f }; - VERIFY_GROUPS; - } -} - -template void tst_qquickvisualdatamodel::get_verify( - const SingleRoleModel &model, - QQuickVisualDataModel *visualModel, - QQuickVisualDataGroup *visibleItems, - QQuickVisualDataGroup *selectedItems, - const int (&mIndex)[N], - const int (&iIndex)[N], - const int (&vIndex)[N], - const int (&sIndex)[N], - const bool (&vMember)[N], - const bool (&sMember)[N]) -{ - failed = true; - for (int i = 0; i < N; ++i) { - QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i])); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i])); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).inItems").arg(i)), true); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]); - QCOMPARE(evaluate(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]); - QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true); - QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]); - QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]); - - if (vMember[i]) { - QCOMPARE(evaluate(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i])); - QCOMPARE(evaluate(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i])); - QCOMPARE(evaluate(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]); - QCOMPARE(evaluate(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]); - QCOMPARE(evaluate(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true); - QCOMPARE(evaluate(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]); - QCOMPARE(evaluate(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]); - QCOMPARE(evaluate(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]); - QCOMPARE(evaluate(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]); - - QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true); - QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]); - QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]); - } - if (sMember[i]) { - QCOMPARE(evaluate(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i])); - QCOMPARE(evaluate(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i])); - QCOMPARE(evaluate(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]); - QCOMPARE(evaluate(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]); - QCOMPARE(evaluate(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true); - QCOMPARE(evaluate(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]); - QCOMPARE(evaluate(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]); - QCOMPARE(evaluate(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]); - QCOMPARE(evaluate(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]); - QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true); - QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]); - QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]); - } - } - failed = false; -} - -#define VERIFY_GET \ - get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \ - QVERIFY(!failed) - -void tst_qquickvisualdatamodel::get() -{ - QQuickView view; - - SingleRoleModel model; - model.list = QStringList() - << "one" - << "two" - << "three" - << "four" - << "five" - << "six" - << "seven" - << "eight" - << "nine" - << "ten" - << "eleven" - << "twelve"; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); - QVERIFY(visualModel); - - QQuickVisualDataGroup *visibleItems = visualModel->findChild("visibleItems"); - QVERIFY(visibleItems); - - QQuickVisualDataGroup *selectedItems = visualModel->findChild("selectedItems"); - QVERIFY(selectedItems); - - QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(ctxt->engine()); - QVERIFY(v8Engine); - - const bool f = false; - const bool t = true; - - { - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 0); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.addGroups(8, \"selected\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 1); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 12); - QCOMPARE(selectedItems->count(), 4); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 }; - static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.setGroups(2, [\"items\", \"selected\"])"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 11); - QCOMPARE(selectedItems->count(), 5); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 }; - static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 }; - static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f }; - VERIFY_GET; - } { - evaluate(selectedItems, "setGroups(0, 3, \"items\")"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; - static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.get(5).inVisible = false"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 8); - QCOMPARE(selectedItems->count(), 2); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; - static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.get(5).inSelected = true"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 8); - QCOMPARE(selectedItems->count(), 3); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; - static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 }; - static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f }; - VERIFY_GET; - } { - evaluate(visualModel, "items.get(5).groups = [\"visible\", \"items\"]"); - QCOMPARE(listview->count(), 12); - QCOMPARE(visualModel->items()->count(), 12); - QCOMPARE(visibleItems->count(), 9); - QCOMPARE(selectedItems->count(), 2); - static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; - static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; - static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; - static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; - static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; - VERIFY_GET; - } -} - -void tst_qquickvisualdatamodel::invalidGroups() -{ - QUrl source = QUrl::fromLocalFile(TESTDATA("groups-invalid.qml")); - QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8()); - - QDeclarativeComponent component(&engine, source); - QScopedPointer object(component.create()); - QVERIFY(object); - - QCOMPARE(evaluate(object.data(), "groups.length"), 4); - QCOMPARE(evaluate(object.data(), "groups[0].name"), QString("items")); - QCOMPARE(evaluate(object.data(), "groups[1].name"), QString("persistedItems")); - QCOMPARE(evaluate(object.data(), "groups[2].name"), QString("visible")); - QCOMPARE(evaluate(object.data(), "groups[3].name"), QString("selected")); -} - -void tst_qquickvisualdatamodel::onChanged_data() -{ - QTest::addColumn("expression"); - QTest::addColumn("tests"); - - QTest::newRow("item appended") - << QString("listModel.append({\"number\": \"five\"})") - << (QStringList() - << "verify(vm.removed, [], [], [])" - << "verify(vm.inserted, [4], [1], [undefined])" - << "verify(vi.removed, [], [], [])" - << "verify(vi.inserted, [4], [1], [undefined])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - QTest::newRow("item prepended") - << QString("listModel.insert(0, {\"number\": \"five\"})") - << (QStringList() - << "verify(vm.removed, [], [], [])" - << "verify(vm.inserted, [0], [1], [undefined])" - << "verify(vi.removed, [], [], [])" - << "verify(vi.inserted, [0], [1], [undefined])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - QTest::newRow("item inserted") - << QString("listModel.insert(2, {\"number\": \"five\"})") - << (QStringList() - << "verify(vm.removed, [], [], [])" - << "verify(vm.inserted, [2], [1], [undefined])" - << "verify(vi.removed, [], [], [])" - << "verify(vi.inserted, [2], [1], [undefined])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - - QTest::newRow("item removed tail") - << QString("listModel.remove(3)") - << (QStringList() - << "verify(vm.removed, [3], [1], [undefined])" - << "verify(vm.inserted, [], [], [])" - << "verify(vi.removed, [3], [1], [undefined])" - << "verify(vi.inserted, [], [], [])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - QTest::newRow("item removed head") - << QString("listModel.remove(0)") - << (QStringList() - << "verify(vm.removed, [0], [1], [undefined])" - << "verify(vm.inserted, [], [], [])" - << "verify(vi.removed, [0], [1], [undefined])" - << "verify(vi.inserted, [], [], [])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - QTest::newRow("item removed middle") - << QString("listModel.remove(1)") - << (QStringList() - << "verify(vm.removed, [1], [1], [undefined])" - << "verify(vm.inserted, [], [], [])" - << "verify(vi.removed, [1], [1], [undefined])" - << "verify(vi.inserted, [], [], [])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - - - QTest::newRow("item moved from tail") - << QString("listModel.move(3, 0, 1)") - << (QStringList() - << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])" - << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])" - << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])" - << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - QTest::newRow("item moved from head") - << QString("listModel.move(0, 2, 2)") - << (QStringList() - << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])" - << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])" - << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])" - << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); - - QTest::newRow("groups changed") - << QString("items.setGroups(1, 2, [\"items\", \"selected\"])") - << (QStringList() - << "verify(vm.inserted, [], [], [])" - << "verify(vm.removed, [], [], [])" - << "verify(vi.removed, [1], [2], [undefined])" - << "verify(vi.inserted, [], [], [])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [0], [2], [undefined])"); - - QTest::newRow("multiple removes") - << QString("{ vi.remove(1, 1); " - "vi.removeGroups(0, 2, \"items\") }") - << (QStringList() - << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])" - << "verify(vm.inserted, [], [], [])" - << "verify(vi.removed, [1], [1], [undefined])" - << "verify(vi.inserted, [], [], [])" - << "verify(si.removed, [], [], [])" - << "verify(si.inserted, [], [], [])"); -} - -void tst_qquickvisualdatamodel::onChanged() -{ - QFETCH(QString, expression); - QFETCH(QStringList, tests); - - QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("onChanged.qml"))); - QScopedPointer object(component.create()); - QVERIFY(object); - - evaluate(object.data(), expression); - - foreach (const QString &test, tests) { - bool passed = evaluate(object.data(), test); - if (!passed) - qWarning() << test; - QVERIFY(passed); - } -} - -void tst_qquickvisualdatamodel::create() -{ - QQuickView view; - - SingleRoleModel model; - model.list = QStringList() - << "one" - << "two" - << "three" - << "four" - << "five" - << "six" - << "seven" - << "eight" - << "nine" - << "ten" - << "eleven" - << "twelve" - << "thirteen" - << "fourteen" - << "fifteen" - << "sixteen" - << "seventeen" - << "eighteen" - << "nineteen" - << "twenty"; - - QDeclarativeContext *ctxt = view.rootContext(); - ctxt->setContextProperty("myModel", &model); - - view.setSource(QUrl::fromLocalFile(TESTDATA("create.qml"))); - - QQuickListView *listview = qobject_cast(view.rootObject()); - QVERIFY(listview != 0); - - QQuickItem *contentItem = listview->contentItem(); - QVERIFY(contentItem != 0); - - QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); - QVERIFY(visualModel); - - QCOMPARE(listview->count(), 20); - - QQuickItem *delegate; - - // persistedItems.includeByDefault is true, so all items belong to persistedItems initially. - QVERIFY(delegate = findItem(contentItem, "delegate", 1)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - - // changing include by default doesn't remove persistance. - evaluate(visualModel, "persistedItems.includeByDefault = false"); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - - // removing from persistedItems does. - evaluate(visualModel, "persistedItems.remove(0, 20)"); - QCOMPARE(listview->count(), 20); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); - - // Request an item instantiated by the view. - QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(1)"))); - QCOMPARE(delegate, findItem(contentItem, "delegate", 1)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); - - evaluate(delegate, "VisualDataModel.inPersistedItems = false"); - QCOMPARE(listview->count(), 20); - QCOMPARE(evaluate(delegate, "destroyed"), false); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); - - // Request an item not instantiated by the view. - QVERIFY(!findItem(contentItem, "delegate", 15)); - QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(15)"))); - QCOMPARE(delegate, findItem(contentItem, "delegate", 15)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); - - evaluate(visualModel, "persistedItems.remove(0)"); - QCOMPARE(evaluate(delegate, "destroyed"), true); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); - - // Request an item not instantiated by the view, then scroll the view so it will request it. - QVERIFY(!findItem(contentItem, "delegate", 16)); - QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(16)"))); - QCOMPARE(delegate, findItem(contentItem, "delegate", 16)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); - - evaluate(listview, "positionViewAtIndex(19, ListView.End)"); - QCOMPARE(listview->count(), 20); - evaluate(delegate, "VisualDataModel.groups = [\"items\"]"); - QCOMPARE(evaluate(delegate, "destroyed"), false); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); - - // Request and release an item instantiated by the view, then scroll the view so it releases it. - QVERIFY(findItem(contentItem, "delegate", 17)); - QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(17)"))); - QCOMPARE(delegate, findItem(contentItem, "delegate", 17)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); - - evaluate(visualModel, "items.removeGroups(17, \"persistedItems\")"); - QCOMPARE(evaluate(delegate, "destroyed"), false); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); - evaluate(listview, "positionViewAtIndex(1, ListView.Beginning)"); - QCOMPARE(listview->count(), 20); - QCOMPARE(evaluate(delegate, "destroyed"), true); - - // Adding an item to the persistedItems group won't instantiate it, but if later requested by - // the view it will be persisted. - evaluate(visualModel, "items.addGroups(18, \"persistedItems\")"); - QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); - QVERIFY(!findItem(contentItem, "delegate", 18)); - evaluate(listview, "positionViewAtIndex(19, ListView.End)"); - QCOMPARE(listview->count(), 20); - QVERIFY(delegate = findItem(contentItem, "delegate", 18)); - QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); - QCOMPARE(evaluate(delegate, "destroyed"), false); - evaluate(listview, "positionViewAtIndex(1, ListView.Beginning)"); - QCOMPARE(listview->count(), 20); - QCOMPARE(evaluate(delegate, "destroyed"), false); -} - - -void tst_qquickvisualdatamodel::incompleteModel() -{ - // VisualDataModel is first populated in componentComplete. Verify various functions are - // harmlessly ignored until then. - - QDeclarativeComponent component(&engine); - component.setData("import QtQuick 2.0\n VisualDataModel {}", QUrl::fromLocalFile(TESTDATA(""))); - - QScopedPointer object(component.beginCreate(engine.rootContext())); - - QQuickVisualDataModel *model = qobject_cast(object.data()); - QVERIFY(model); - - QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged())); - QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged())); - - evaluate(model, "items.removeGroups(0, items.count, \"items\")"); - QCOMPARE(itemsSpy.count(), 0); - QCOMPARE(persistedItemsSpy.count(), 0); - - evaluate(model, "items.setGroups(0, items.count, \"persistedItems\")"); - QCOMPARE(itemsSpy.count(), 0); - QCOMPARE(persistedItemsSpy.count(), 0); - - evaluate(model, "items.addGroups(0, items.count, \"persistedItems\")"); - QCOMPARE(itemsSpy.count(), 0); - QCOMPARE(persistedItemsSpy.count(), 0); - - evaluate(model, "items.remove(0, items.count)"); - QCOMPARE(itemsSpy.count(), 0); - QCOMPARE(persistedItemsSpy.count(), 0); - - evaluate(model, "items.insert([ \"color\": \"blue\" ])"); - QCOMPARE(itemsSpy.count(), 0); - QCOMPARE(persistedItemsSpy.count(), 0); - - QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: get: index out of range"); - QVERIFY(evaluate(model, "items.get(0) === undefined")); - - component.completeCreate(); -} - -template -T *tst_qquickvisualdatamodel::findItem(QQuickItem *parent, const QString &objectName, int index) -{ - const QMetaObject &mo = T::staticMetaObject; - //qDebug() << parent->childItems().count() << "children"; - for (int i = 0; i < parent->childItems().count(); ++i) { - QQuickItem *item = qobject_cast(parent->childItems().at(i)); - if (!item) - continue; - //qDebug() << "try" << item; - if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { - if (index != -1) { - QDeclarativeExpression e(qmlContext(item), item, "index"); - if (e.evaluate().toInt() == index) - return static_cast(item); - } else { - return static_cast(item); - } - } - item = findItem(item, objectName, index); - if (item) - return static_cast(item); - } - - return 0; -} - -QTEST_MAIN(tst_qquickvisualdatamodel) - -#include "tst_qquickvisualdatamodel.moc" diff --git a/tests/auto/declarative/shared/testhttpserver.cpp b/tests/auto/declarative/shared/testhttpserver.cpp deleted file mode 100644 index 206094924c..0000000000 --- a/tests/auto/declarative/shared/testhttpserver.cpp +++ /dev/null @@ -1,324 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "testhttpserver.h" -#include -#include -#include -#include - -/*! -\internal -\class TestHTTPServer -\brief provides a very, very basic HTTP server for testing. - -Inside the test case, an instance of TestHTTPServer should be created, with the -appropriate port to listen on. The server will listen on the localhost interface. - -Directories to serve can then be added to server, which will be added as "roots". -Each root can be added as a Normal, Delay or Disconnect root. Requests for files -within a Normal root are returned immediately. Request for files within a Delay -root are delayed for 500ms, and then served. Requests for files within a Disconnect -directory cause the server to disconnect immediately. A request for a file that isn't -found in any root will return a 404 error. - -If you have the following directory structure: - -\code -disconnect/disconnectTest.qml -files/main.qml -files/Button.qml -files/content/WebView.qml -slowFiles/slowMain.qml -\endcode -it can be added like this: -\code -TestHTTPServer server(14445); -server.serveDirectory("disconnect", TestHTTPServer::Disconnect); -server.serveDirectory("files"); -server.serveDirectory("slowFiles", TestHTTPServer::Delay); -\endcode - -The following request urls will then result in the appropriate action: -\table -\header \o URL \o Action -\row \o http://localhost:14445/disconnectTest.qml \o Disconnection -\row \o http://localhost:14445/main.qml \o main.qml returned immediately -\row \o http://localhost:14445/Button.qml \o Button.qml returned immediately -\row \o http://localhost:14445/content/WebView.qml \o content/WebView.qml returned immediately -\row \o http://localhost:14445/slowMain.qml \o slowMain.qml returned after 500ms -\endtable -*/ -TestHTTPServer::TestHTTPServer(quint16 port) -: m_hasFailed(false) -{ - QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); - - server.listen(QHostAddress::LocalHost, port); -} - -bool TestHTTPServer::isValid() const -{ - return server.isListening(); -} - -bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) -{ - dirs.append(qMakePair(dir, mode)); - return true; -} - -/* - Add an alias, so that if filename is requested and does not exist, - alias may be returned. -*/ -void TestHTTPServer::addAlias(const QString &filename, const QString &alias) -{ - aliases.insert(filename, alias); -} - -void TestHTTPServer::addRedirect(const QString &filename, const QString &redirectName) -{ - redirects.insert(filename, redirectName); -} - -bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &body) -{ - m_hasFailed = false; - - QFile expectFile(expect.toLocalFile()); - if (!expectFile.open(QIODevice::ReadOnly)) return false; - - QFile replyFile(reply.toLocalFile()); - if (!replyFile.open(QIODevice::ReadOnly)) return false; - - bodyData = QByteArray(); - if (body.isValid()) { - QFile bodyFile(body.toLocalFile()); - if (!bodyFile.open(QIODevice::ReadOnly)) return false; - bodyData = bodyFile.readAll(); - } - - waitData = expectFile.readAll(); - /* - while (waitData.endsWith('\n')) - waitData = waitData.left(waitData.count() - 1); - */ - - replyData = replyFile.readAll(); - - if (!replyData.endsWith('\n')) - replyData.append("\n"); - replyData.append("Content-length: " + QByteArray::number(bodyData.length())); - replyData .append("\n\n"); - - for (int ii = 0; ii < replyData.count(); ++ii) { - if (replyData.at(ii) == '\n' && (!ii || replyData.at(ii - 1) != '\r')) { - replyData.insert(ii, '\r'); - ++ii; - } - } - replyData.append(bodyData); - - return true; -} - -bool TestHTTPServer::hasFailed() const -{ - return m_hasFailed; -} - -void TestHTTPServer::newConnection() -{ - QTcpSocket *socket = server.nextPendingConnection(); - if (!socket) return; - - if (!dirs.isEmpty()) - dataCache.insert(socket, QByteArray()); - - QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); - QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); -} - -void TestHTTPServer::disconnected() -{ - QTcpSocket *socket = qobject_cast(sender()); - if (!socket) return; - - dataCache.remove(socket); - for (int ii = 0; ii < toSend.count(); ++ii) { - if (toSend.at(ii).first == socket) { - toSend.removeAt(ii); - --ii; - } - } - socket->disconnect(); - socket->deleteLater(); -} - -void TestHTTPServer::readyRead() -{ - QTcpSocket *socket = qobject_cast(sender()); - if (!socket || socket->state() == QTcpSocket::ClosingState) return; - - QByteArray ba = socket->readAll(); - - if (!dirs.isEmpty()) { - serveGET(socket, ba); - return; - } - - if (m_hasFailed || waitData.isEmpty()) { - qWarning() << "TestHTTPServer: Unexpected data" << ba; - return; - } - - for (int ii = 0; ii < ba.count(); ++ii) { - const char c = ba.at(ii); - if (c == '\r' && waitData.isEmpty()) - continue; - else if (!waitData.isEmpty() && c == waitData.at(0)) - waitData = waitData.mid(1); - else if (c == '\r') - continue; - else { - QByteArray data = ba.mid(ii); - qWarning() << "TestHTTPServer: Unexpected data" << data << "\nExpected: " << waitData; - m_hasFailed = true; - socket->disconnectFromHost(); - return; - } - } - - if (waitData.isEmpty()) { - socket->write(replyData); - socket->disconnectFromHost(); - } -} - -bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) -{ - if (redirects.contains(fileName)) { - QByteArray response = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + redirects[fileName].toUtf8() + "\r\n\r\n"; - socket->write(response); - return true; - } - - for (int ii = 0; ii < dirs.count(); ++ii) { - QString dir = dirs.at(ii).first; - Mode mode = dirs.at(ii).second; - - QString dirFile = dir + QLatin1String("/") + QLatin1String(fileName); - - if (!QFile::exists(dirFile)) { - if (aliases.contains(fileName)) - dirFile = dir + QLatin1String("/") + aliases.value(fileName); - } - - QFile file(dirFile); - if (file.open(QIODevice::ReadOnly)) { - - if (mode == Disconnect) - return true; - - QByteArray data = file.readAll(); - - QByteArray response = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; - response += QByteArray::number(data.count()); - response += "\r\n\r\n"; - response += data; - - if (mode == Delay) { - toSend.append(qMakePair(socket, response)); - QTimer::singleShot(500, this, SLOT(sendOne())); - return false; - } else { - socket->write(response); - return true; - } - } - } - - - QByteArray response = "HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"; - socket->write(response); - - return true; -} - -void TestHTTPServer::sendOne() -{ - if (!toSend.isEmpty()) { - toSend.first().first->write(toSend.first().second); - toSend.first().first->close(); - toSend.removeFirst(); - } -} - -void TestHTTPServer::serveGET(QTcpSocket *socket, const QByteArray &data) -{ - if (!dataCache.contains(socket)) - return; - - QByteArray total = dataCache[socket] + data; - dataCache[socket] = total; - - if (total.contains("\n\r\n")) { - - bool close = true; - - if (total.startsWith("GET /")) { - - int space = total.indexOf(' ', 4); - if (space != -1) { - - QByteArray req = total.mid(5, space - 5); - close = reply(socket, req); - - } - } - dataCache.remove(socket); - - if (close) - socket->disconnectFromHost(); - } -} - diff --git a/tests/auto/declarative/shared/testhttpserver.h b/tests/auto/declarative/shared/testhttpserver.h deleted file mode 100644 index 3e8f70fea4..0000000000 --- a/tests/auto/declarative/shared/testhttpserver.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TESTHTTPSERVER_H -#define TESTHTTPSERVER_H - -#include -#include -#include -#include - -class TestHTTPServer : public QObject -{ - Q_OBJECT -public: - TestHTTPServer(quint16 port); - - bool isValid() const; - - enum Mode { Normal, Delay, Disconnect }; - bool serveDirectory(const QString &, Mode = Normal); - - bool wait(const QUrl &expect, const QUrl &reply, const QUrl &body); - bool hasFailed() const; - - void addAlias(const QString &filename, const QString &aliasName); - void addRedirect(const QString &filename, const QString &redirectName); - -private slots: - void newConnection(); - void disconnected(); - void readyRead(); - void sendOne(); - -private: - void serveGET(QTcpSocket *, const QByteArray &); - bool reply(QTcpSocket *, const QByteArray &); - - QList > dirs; - QHash dataCache; - QList > toSend; - - QByteArray waitData; - QByteArray replyData; - QByteArray bodyData; - bool m_hasFailed; - - QHash aliases; - QHash redirects; - - QTcpServer server; -}; - -#endif // TESTHTTPSERVER_H - diff --git a/tests/auto/declarative/shared/util.h b/tests/auto/declarative/shared/util.h deleted file mode 100644 index eac2c4ec12..0000000000 --- a/tests/auto/declarative/shared/util.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVETESTUTILS_H -#define QDECLARATIVETESTUTILS_H - -#include -#include - -namespace QDeclarativeTestUtils -{ - /* - Returns the path to some testdata file. - - We first check relative to the binary, and then look in the source tree. - - Note we are looking for a _directory_ which exists, but the _file_ itself need not exist, - to support the case of finding a path to a testdata file which doesn't exist yet (i.e. - a file we are about to create). - */ - QString testdata(QString const& name, const char *sourceFile) - { - // Try to find it relative to the binary. - QFileInfo relative = QDir(QCoreApplication::applicationDirPath()).filePath(QLatin1String("data/") + name); - if (relative.dir().exists()) { - return relative.absoluteFilePath(); - } - - // Else try to find it in the source tree - QFileInfo from_source = QFileInfo(sourceFile).absoluteDir().filePath(QLatin1String("data/") + name); - if (from_source.dir().exists()) { - return from_source.absoluteFilePath(); - } - - qWarning("requested testdata %s could not be found (looked at: %s, %s)", - qPrintable(name), - qPrintable(relative.filePath()), - qPrintable(from_source.filePath()) - ); - - return QString(); - } -} - -#define TESTDATA(name) QDeclarativeTestUtils::testdata(name, __FILE__) - -#endif // QDECLARATIVETESTUTILS_H diff --git a/tests/auto/declarative/v4/tst_v4.cpp b/tests/auto/declarative/v4/tst_v4.cpp index 69fa4bbf0c..791610d541 100644 --- a/tests/auto/declarative/v4/tst_v4.cpp +++ b/tests/auto/declarative/v4/tst_v4.cpp @@ -48,7 +48,7 @@ #include -#include "../shared/util.h" +#include "../../shared/util.h" #include "testtypes.h" inline QUrl TEST_FILE(const QString &filename) diff --git a/tests/auto/particles/qquickage/qquickage.pro b/tests/auto/particles/qquickage/qquickage.pro index 980d390953..e03e3d47d1 100644 --- a/tests/auto/particles/qquickage/qquickage.pro +++ b/tests/auto/particles/qquickage/qquickage.pro @@ -9,5 +9,5 @@ DEPLOYMENT += testDataFiles CONFIG += insignificant_test -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro index 2a4ee5237a..235f0d81b0 100644 --- a/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro +++ b/tests/auto/particles/qquickangleddirection/qquickangleddirection.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro index 160f63f3bc..09fe1aa06a 100644 --- a/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro +++ b/tests/auto/particles/qquickcumulativedirection/qquickcumulativedirection.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro index e1293312b1..6d3ecaa6f4 100644 --- a/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro +++ b/tests/auto/particles/qquickcustomaffector/qquickcustomaffector.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro index 3476a66ca2..e9bcc1e373 100644 --- a/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro +++ b/tests/auto/particles/qquickcustomparticle/qquickcustomparticle.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro index 9f5147be33..803a366429 100644 --- a/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro +++ b/tests/auto/particles/qquickellipseextruder/qquickellipseextruder.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickfriction/qquickfriction.pro b/tests/auto/particles/qquickfriction/qquickfriction.pro index d6726724ff..889b2d9505 100644 --- a/tests/auto/particles/qquickfriction/qquickfriction.pro +++ b/tests/auto/particles/qquickfriction/qquickfriction.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickgravity/qquickgravity.pro b/tests/auto/particles/qquickgravity/qquickgravity.pro index bc503d932a..3bdd8c1efa 100644 --- a/tests/auto/particles/qquickgravity/qquickgravity.pro +++ b/tests/auto/particles/qquickgravity/qquickgravity.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro index 14d28fd43d..fa43b28407 100644 --- a/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro +++ b/tests/auto/particles/qquickimageparticle/qquickimageparticle.pro @@ -7,4 +7,4 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro index 8e8eadd463..9d78c2b49d 100644 --- a/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro +++ b/tests/auto/particles/qquickitemparticle/qquickitemparticle.pro @@ -9,5 +9,5 @@ DEPLOYMENT += testDataFiles CONFIG += insignificant_test #temporary -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro index 255c9a4104..fae5203961 100644 --- a/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro +++ b/tests/auto/particles/qquicklineextruder/qquicklineextruder.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro index b53d3610fa..d82adf8b4a 100644 --- a/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro +++ b/tests/auto/particles/qquickmaskextruder/qquickmaskextruder.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro index b100ffaf75..27547c16b1 100644 --- a/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro +++ b/tests/auto/particles/qquickparticlegroup/qquickparticlegroup.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro index 65472e23f9..6fd13ec01e 100644 --- a/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro +++ b/tests/auto/particles/qquickparticlesystem/qquickparticlesystem.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro index 13b512791a..a9d390aab8 100644 --- a/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro +++ b/tests/auto/particles/qquickpointattractor/qquickpointattractor.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro index 6adab3d75d..04fe1617de 100644 --- a/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro +++ b/tests/auto/particles/qquickpointdirection/qquickpointdirection.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro index fee29efcf3..e45c43a587 100644 --- a/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro +++ b/tests/auto/particles/qquickrectangleextruder/qquickrectangleextruder.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro index 0de6007283..0a887d1fb3 100644 --- a/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro +++ b/tests/auto/particles/qquicktargetdirection/qquicktargetdirection.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro index 7b8075d625..9139dd39fb 100644 --- a/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro +++ b/tests/auto/particles/qquicktrailemitter/qquicktrailemitter.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickturbulence/qquickturbulence.pro b/tests/auto/particles/qquickturbulence/qquickturbulence.pro index 405e8a6f2a..16d85445f5 100644 --- a/tests/auto/particles/qquickturbulence/qquickturbulence.pro +++ b/tests/auto/particles/qquickturbulence/qquickturbulence.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/qquickwander/qquickwander.pro b/tests/auto/particles/qquickwander/qquickwander.pro index cf6f08e2dc..a9c48ece78 100644 --- a/tests/auto/particles/qquickwander/qquickwander.pro +++ b/tests/auto/particles/qquickwander/qquickwander.pro @@ -7,5 +7,5 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/particles/shared/particlestestsshared.h b/tests/auto/particles/shared/particlestestsshared.h index ab6b5f16af..5989efe937 100644 --- a/tests/auto/particles/shared/particlestestsshared.h +++ b/tests/auto/particles/shared/particlestestsshared.h @@ -41,7 +41,7 @@ #ifndef PARTICLES_TESTS_SHARED #define PARTICLES_TESTS_SHARED -#include +#include #include #include const qreal EPSILON = 0.0001; diff --git a/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro b/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro index c5ec23e17e..21c846b4eb 100644 --- a/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro +++ b/tests/auto/qtquick1/qdeclarativeanimatedimage/qdeclarativeanimatedimage.pro @@ -1,7 +1,7 @@ CONFIG += testcase TARGET = tst_qdeclarativeanimatedimage -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativeanimatedimage.cpp ../../declarative/shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativeanimatedimage.cpp ../../shared/testhttpserver.cpp macx:CONFIG -= app_bundle DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp b/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp index 275b8d0fb4..3d81d669f4 100644 --- a/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp +++ b/tests/auto/qtquick1/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp @@ -48,7 +48,7 @@ #include #include -#include "../../declarative/shared/testhttpserver.h" +#include "../../shared/testhttpserver.h" class tst_qdeclarativeanimatedimage : public QObject { diff --git a/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro b/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro index 83319faf8a..a8c8b18a37 100644 --- a/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro +++ b/tests/auto/qtquick1/qdeclarativeborderimage/qdeclarativeborderimage.pro @@ -2,8 +2,8 @@ CONFIG += testcase TARGET = tst_qdeclarativeborderimage macx:CONFIG -= app_bundle -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativeborderimage.cpp ../../declarative/shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativeborderimage.cpp ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp b/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp index 4b82fe0a4e..4346c75850 100644 --- a/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp +++ b/tests/auto/qtquick1/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp @@ -54,7 +54,7 @@ #include #include -#include "../../declarative/shared/testhttpserver.h" +#include "../../shared/testhttpserver.h" #define SERVER_PORT 14446 #define SERVER_ADDR "http://127.0.0.1:14446" diff --git a/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro index fc48544fa0..fbe72b072c 100644 --- a/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro +++ b/tests/auto/qtquick1/qdeclarativefontloader/qdeclarativefontloader.pro @@ -2,8 +2,8 @@ CONFIG += testcase TARGET = tst_qdeclarativefontloader macx:CONFIG -= app_bundle -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativefontloader.cpp ../../declarative/shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativefontloader.cpp ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index 3bcbe1b67c..addd6516f5 100644 --- a/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/qtquick1/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -44,7 +44,7 @@ #include #include #include -#include "../../declarative/shared/testhttpserver.h" +#include "../../shared/testhttpserver.h" #define SERVER_PORT 14448 diff --git a/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro b/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro index 5c9b9db5c8..28570ab093 100644 --- a/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro +++ b/tests/auto/qtquick1/qdeclarativeimage/qdeclarativeimage.pro @@ -2,8 +2,8 @@ CONFIG += testcase TARGET = tst_qdeclarativeimage macx:CONFIG -= app_bundle -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativeimage.cpp ../../declarative/shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativeimage.cpp ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp index e93c373bf1..107ba89c77 100644 --- a/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp +++ b/tests/auto/qtquick1/qdeclarativeimage/tst_qdeclarativeimage.cpp @@ -54,7 +54,7 @@ #include #include -#include "../../declarative/shared/testhttpserver.h" +#include "../../shared/testhttpserver.h" #define SERVER_PORT 14451 #define SERVER_ADDR "http://127.0.0.1:14451" diff --git a/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro b/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro index 7f3cfb20b1..0e4df8d3da 100644 --- a/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro +++ b/tests/auto/qtquick1/qdeclarativeloader/qdeclarativeloader.pro @@ -2,10 +2,10 @@ CONFIG += testcase TARGET = tst_qdeclarativeloader macx:CONFIG -= app_bundle -INCLUDEPATH += ../../declarative/shared/ -HEADERS += ../../declarative/shared/testhttpserver.h +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h SOURCES += tst_qdeclarativeloader.cpp \ - ../../declarative/shared/testhttpserver.cpp + ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro b/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro index f7e6a5b292..6f426c50c5 100644 --- a/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro +++ b/tests/auto/qtquick1/qdeclarativemousearea/qdeclarativemousearea.pro @@ -2,8 +2,8 @@ CONFIG += testcase TARGET = tst_qdeclarativemousearea macx:CONFIG -= app_bundle -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += tst_qdeclarativemousearea.cpp ../../declarative/shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativemousearea.cpp ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro index 0989aab14f..1957bdd9fd 100644 --- a/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro +++ b/tests/auto/qtquick1/qdeclarativetext/qdeclarativetext.pro @@ -4,9 +4,9 @@ macx:CONFIG -= app_bundle SOURCES += tst_qdeclarativetext.cpp -INCLUDEPATH += ../../declarative/shared/ -HEADERS += ../../declarative/shared/testhttpserver.h -SOURCES += ../../declarative/shared/testhttpserver.cpp +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h +SOURCES += ../../shared/testhttpserver.cpp DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro index 74c4215579..5c86e111e8 100644 --- a/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro +++ b/tests/auto/qtquick1/qdeclarativetextedit/qdeclarativetextedit.pro @@ -2,8 +2,8 @@ CONFIG += testcase TARGET = tst_qdeclarativetextedit macx:CONFIG -= app_bundle -SOURCES += tst_qdeclarativetextedit.cpp ../../declarative/shared/testhttpserver.cpp -HEADERS += ../../declarative/shared/testhttpserver.h +SOURCES += tst_qdeclarativetextedit.cpp ../../shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 621c1753b2..54b8567161 100644 --- a/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/qtquick1/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -40,7 +40,7 @@ ****************************************************************************/ #include #include -#include "../../declarative/shared/testhttpserver.h" +#include "../../shared/testhttpserver.h" #include #include #include diff --git a/tests/auto/qtquick2/examples/data/dummytest.qml b/tests/auto/qtquick2/examples/data/dummytest.qml new file mode 100644 index 0000000000..b20e907f27 --- /dev/null +++ b/tests/auto/qtquick2/examples/data/dummytest.qml @@ -0,0 +1,6 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { msec: 0 } + Frame { msec: 10 } +} diff --git a/tests/auto/qtquick2/examples/data/webbrowser/webbrowser.qml b/tests/auto/qtquick2/examples/data/webbrowser/webbrowser.qml new file mode 100644 index 0000000000..d31787b939 --- /dev/null +++ b/tests/auto/qtquick2/examples/data/webbrowser/webbrowser.qml @@ -0,0 +1,6 @@ +import Qt.VisualTest 4.6 + +VisualTest { + Frame { msec: 0 } + Frame { msec: 2000 } +} diff --git a/tests/auto/qtquick2/examples/examples.pro b/tests/auto/qtquick2/examples/examples.pro new file mode 100644 index 0000000000..ca169242e1 --- /dev/null +++ b/tests/auto/qtquick2/examples/examples.pro @@ -0,0 +1,10 @@ +CONFIG += testcase +TARGET = tst_examples +macx:CONFIG -= app_bundle + +SOURCES += tst_examples.cpp +DEFINES += SRCDIR=\\\"$$PWD\\\" + +CONFIG += parallel_test +#temporary +QT += core-private gui-private declarative-private quick-private qtquick1-private widgets-private v8-private testlib diff --git a/tests/auto/qtquick2/examples/tst_examples.cpp b/tests/auto/qtquick2/examples/tst_examples.cpp new file mode 100644 index 0000000000..050ae49cfc --- /dev/null +++ b/tests/auto/qtquick2/examples/tst_examples.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class tst_examples : public QObject +{ + Q_OBJECT +public: + tst_examples(); + +private slots: + void sgexamples_data(); + void sgexamples(); + + void namingConvention(); +private: + QStringList excludedDirs; + QStringList excludedFiles; + + void namingConvention(const QDir &); + QStringList findQmlFiles(const QDir &); + + QDeclarativeEngine engine; +}; + +tst_examples::tst_examples() +{ + // Add files to exclude here + excludedFiles << "doc/src/snippets/declarative/listmodel.qml"; //Just a ListModel, no root QQuickItem + + // Add directories you want excluded here + excludedDirs << "examples/declarative/text/fonts"; // QTBUG-21415 + + // Not run in QQuickView + excludedDirs << "examples/declarative/qtquick1"; + + // These snippets are not expected to run on their own. + excludedDirs << "doc/src/snippets/declarative/visualdatamodel_rootindex"; + excludedDirs << "doc/src/snippets/declarative/qtbinding"; + excludedDirs << "doc/src/snippets/declarative/imports"; + excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex"; + excludedDirs << "doc/src/snippets/qtquick1/qtbinding"; + excludedDirs << "doc/src/snippets/qtquick1/imports"; + +#ifdef QT_NO_WEBKIT + excludedDirs << "examples/declarative/modelviews/webview"; + excludedDirs << "examples/declarative/webbrowser"; + excludedDirs << "doc/src/snippets/declarative/webview"; + excludedDirs << "doc/src/snippets/qtquick1/webview"; +#endif + +#ifdef QT_NO_XMLPATTERNS + excludedDirs << "examples/declarative/xml/xmldata"; + excludedDirs << "examples/declarative/twitter"; + excludedDirs << "examples/declarative/flickr"; + excludedDirs << "examples/declarative/photoviewer"; +#endif +} + +/* +This tests that the examples follow the naming convention required +to have them tested by the examples() test. +*/ +void tst_examples::namingConvention(const QDir &d) +{ + for (int ii = 0; ii < excludedDirs.count(); ++ii) { + QString s = excludedDirs.at(ii); + if (d.absolutePath().endsWith(s)) + return; + } + + QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"), + QDir::Files); + + bool seenQml = !files.isEmpty(); + bool seenLowercase = false; + + foreach (const QString &file, files) { + if (file.at(0).isLower()) + seenLowercase = true; + } + + if (!seenQml) { + QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | + QDir::NoSymLinks); + foreach (const QString &dir, dirs) { + QDir sub = d; + sub.cd(dir); + namingConvention(sub); + } + } else if(!seenLowercase) { + QFAIL(qPrintable(QString( + "Directory %1 violates naming convention; expected at least one qml file " + "starting with lower case, got: %2" + ).arg(d.absolutePath()).arg(files.join(",")))); + } +} + +void tst_examples::namingConvention() +{ + QString examples = QLibraryInfo::location(QLibraryInfo::ExamplesPath); + + namingConvention(QDir(examples)); +} + +QStringList tst_examples::findQmlFiles(const QDir &d) +{ + for (int ii = 0; ii < excludedDirs.count(); ++ii) { + QString s = excludedDirs.at(ii); + if (d.absolutePath().endsWith(s)) + return QStringList(); + } + + QStringList rv; + + QStringList cppfiles = d.entryList(QStringList() << QLatin1String("*.cpp"), QDir::Files); + if (cppfiles.isEmpty()) { + QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"), + QDir::Files); + foreach (const QString &file, files) { + if (file.at(0).isLower()) { + bool superContinue = false; + for (int ii = 0; ii < excludedFiles.count(); ++ii) { + QString e = excludedFiles.at(ii); + if (d.absoluteFilePath(file).endsWith(e)) { + superContinue = true; + break; + } + } + if (superContinue) + continue; + rv << d.absoluteFilePath(file); + } + } + } + + + QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | + QDir::NoSymLinks); + foreach (const QString &dir, dirs) { + QDir sub = d; + sub.cd(dir); + rv << findQmlFiles(sub); + } + + return rv; +} + +/* +This test runs all the examples in the declarative UI source tree and ensures +that they start and exit cleanly. + +Examples are any .qml files under the examples/ directory that start +with a lower case letter. +*/ +static void silentErrorsMsgHandler(QtMsgType, const char *) +{ +} + + +void tst_examples::sgexamples_data() +{ + QTest::addColumn("file"); + + QString examples = QLatin1String(SRCDIR) + "/../../../../examples/declarative/"; + QString snippets = QLatin1String(SRCDIR) + "/../../../../doc/src/snippets/declarative"; + + QStringList files; + files << findQmlFiles(QDir(examples)); + files << findQmlFiles(QDir(snippets)); + + foreach (const QString &file, files) + QTest::newRow(qPrintable(file)) << file; +} + +void tst_examples::sgexamples() +{ + QFETCH(QString, file); + + QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler); + qInstallMsgHandler(old); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(file)); + if (component.status() == QDeclarativeComponent::Error) + qWarning() << component.errors(); + QCOMPARE(component.status(), QDeclarativeComponent::Ready); + + QScopedPointer object(component.beginCreate(engine.rootContext())); + QQuickItem *root = qobject_cast(object.data()); + if (!root) + component.completeCreate(); + QVERIFY(root); + + QQuickCanvas canvas; + root->setParentItem(canvas.rootItem()); + component.completeCreate(); + canvas.show(); + + QTest::qWaitForWindowShown(&canvas); + +} + +QTEST_MAIN(tst_examples) + +#include "tst_examples.moc" diff --git a/tests/auto/qtquick2/geometry/geometry.pro b/tests/auto/qtquick2/geometry/geometry.pro new file mode 100644 index 0000000000..04d529cfb8 --- /dev/null +++ b/tests/auto/qtquick2/geometry/geometry.pro @@ -0,0 +1,9 @@ +CONFIG += testcase +TARGET = tst_geometry +macx:CONFIG -= app_bundle + +SOURCES += tst_geometry.cpp + +CONFIG+=parallel_test + +QT += core-private gui-private declarative-private quick-private opengl testlib diff --git a/tests/auto/qtquick2/geometry/tst_geometry.cpp b/tests/auto/qtquick2/geometry/tst_geometry.cpp new file mode 100644 index 0000000000..23e37dae2f --- /dev/null +++ b/tests/auto/qtquick2/geometry/tst_geometry.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt scene graph research project. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include + +class GeometryTest : public QObject +{ + Q_OBJECT + +public: + +private Q_SLOTS: + void testPoint2D(); + void testTexturedPoint2D(); + void testCustomGeometry(); + +private: +}; + +void GeometryTest::testPoint2D() +{ + QSGGeometry geometry(QSGGeometry::defaultAttributes_Point2D(), 4, 0); + + QCOMPARE(geometry.attributeCount(), 1); + QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 2); + QCOMPARE(geometry.vertexCount(), 4); + QCOMPARE(geometry.indexCount(), 0); + QVERIFY(geometry.indexData() == 0); + + QSGGeometry::updateRectGeometry(&geometry, QRectF(1, 2, 3, 4)); + + QSGGeometry::Point2D *pts = geometry.vertexDataAsPoint2D(); + QVERIFY(pts != 0); + + QCOMPARE(pts[0].x, (float) 1); + QCOMPARE(pts[0].y, (float) 2); + QCOMPARE(pts[3].x, (float) 4); + QCOMPARE(pts[3].y, (float) 6); + + // Verify that resize gives me enough allocated data without crashing... + geometry.allocate(100, 100); + pts = geometry.vertexDataAsPoint2D(); + quint16 *is = geometry.indexDataAsUShort(); + for (int i=0; i<100; ++i) { + pts[i].x = i; + pts[i].y = i + 100; + is[i] = i; + } + QVERIFY(true); +} + + +void GeometryTest::testTexturedPoint2D() +{ + QSGGeometry geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4, 0); + + QCOMPARE(geometry.attributeCount(), 2); + QCOMPARE(geometry.sizeOfVertex(), (int) sizeof(float) * 4); + QCOMPARE(geometry.vertexCount(), 4); + QCOMPARE(geometry.indexCount(), 0); + QVERIFY(geometry.indexData() == 0); + + QSGGeometry::updateTexturedRectGeometry(&geometry, QRectF(1, 2, 3, 4), QRectF(5, 6, 7, 8)); + + QSGGeometry::TexturedPoint2D *pts = geometry.vertexDataAsTexturedPoint2D(); + QVERIFY(pts != 0); + + QCOMPARE(pts[0].x, (float) 1); + QCOMPARE(pts[0].y, (float) 2); + QCOMPARE(pts[0].tx, (float) 5); + QCOMPARE(pts[0].ty, (float) 6); + + QCOMPARE(pts[3].x, (float) 4); + QCOMPARE(pts[3].y, (float) 6); + QCOMPARE(pts[3].tx, (float) 12); + QCOMPARE(pts[3].ty, (float) 14); + + // Verify that resize gives me enough allocated data without crashing... + geometry.allocate(100, 100); + pts = geometry.vertexDataAsTexturedPoint2D(); + quint16 *is = geometry.indexDataAsUShort(); + for (int i=0; i<100; ++i) { + pts[i].x = i; + pts[i].y = i + 100; + pts[i].tx = i + 200; + pts[i].ty = i + 300; + is[i] = i; + } + QVERIFY(true); +} + +void GeometryTest::testCustomGeometry() +{ + struct V { + float x, y; + unsigned char r, g, b, a; + float v1, v2, v3, v4; + }; + + static QSGGeometry::Attribute attributes[] = { + { 0, 2, GL_FLOAT }, + { 1, 4, GL_UNSIGNED_BYTE }, + { 2, 4, GL_FLOAT }, + }; + static QSGGeometry::AttributeSet set = { 4, 6 * sizeof(float) + 4 * sizeof(unsigned char), attributes }; + + QSGGeometry geometry(set, 1000, 4000); + + // Verify that space has been allocated. + quint16 *ii = geometry.indexDataAsUShort(); + for (int i=0; i +#include + +#include +#include +#include + +#include +#include +class NodesTest : public QObject +{ + Q_OBJECT + +public: + NodesTest(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase() { + delete widget; + } + + // Root nodes + void propegate(); + void propegateWithMultipleRoots(); + void simulatedEffect_data(); + void simulatedEffect(); + + // Opacity nodes + void basicOpacityNode(); + void opacityPropegation(); + + // QSGNodeUpdater + void isBlockedCheck(); + +private: + QGLWidget *widget; + + QSGNodeUpdater updater; +}; + +void NodesTest::initTestCase() +{ + widget = new QGLWidget(); + widget->resize(100, 30); + widget->show(); +} + +class DummyRenderer : public QSGRenderer +{ +public: + DummyRenderer(QSGRootNode *root) + : QSGRenderer(QSGContext::createDefaultContext()) + , changedNode(0) + , changedFlags(0) + , renderCount(0) + { + setRootNode(root); + } + + void render() { + ++renderCount; + renderingOrder = ++globalRendereringOrder; + } + + void nodeChanged(QSGNode *node, QSGNode::DirtyFlags flags) { + changedNode = node; + changedFlags = flags; + QSGRenderer::nodeChanged(node, flags); + } + + QSGNode *changedNode; + QSGNode::DirtyFlags changedFlags; + + int renderCount; + int renderingOrder; + static int globalRendereringOrder; +}; + +int DummyRenderer::globalRendereringOrder; + +NodesTest::NodesTest() +{ +} + + +void NodesTest::propegate() +{ + QSGRootNode root; + QSGNode child; child.setFlag(QSGNode::OwnedByParent, false); + root.appendChildNode(&child); + + DummyRenderer renderer(&root); + + child.markDirty(QSGNode::DirtyGeometry); + + QCOMPARE(&child, renderer.changedNode); + QCOMPARE((int) renderer.changedFlags, (int) QSGNode::DirtyGeometry); +} + + +void NodesTest::propegateWithMultipleRoots() +{ + QSGRootNode root1; + QSGNode child2; child2.setFlag(QSGNode::OwnedByParent, false); + QSGRootNode root3; root3.setFlag(QSGNode::OwnedByParent, false); + QSGNode child4; child4.setFlag(QSGNode::OwnedByParent, false); + + root1.appendChildNode(&child2); + child2.appendChildNode(&root3); + root3.appendChildNode(&child4); + + DummyRenderer ren1(&root1); + DummyRenderer ren2(&root3); + + child4.markDirty(QSGNode::DirtyGeometry); + + QCOMPARE(ren1.changedNode, &child4); + QCOMPARE(ren2.changedNode, &child4); + + QCOMPARE((int) ren1.changedFlags, (int) QSGNode::DirtyGeometry); + QCOMPARE((int) ren2.changedFlags, (int) QSGNode::DirtyGeometry); +} + + + +class SimulatedEffectRenderer : public DummyRenderer +{ +public: + SimulatedEffectRenderer(QSGRootNode *root, QSGBasicGeometryNode *c) + : DummyRenderer(root) + { + child = c; + } + + void render() { + matrix = child->matrix() ? *child->matrix() : QMatrix4x4(); + DummyRenderer::render(); + } + + QSGBasicGeometryNode *child; + QMatrix4x4 matrix; +}; + + +class PseudoEffectNode : public QSGNode { +public: + PseudoEffectNode(QSGRenderer *r) + : renderer(r) + { + setFlag(UsePreprocess); + } + + void preprocess() { + + if (renderer->rootNode()->parent()) { + // Mark the root dirty to build a clean state from the root and down + renderer->rootNode()->markDirty(QSGNode::DirtyForceUpdate); + } + + renderer->renderScene(); + + if (renderer->rootNode()->parent()) { + // Mark the parent of the root dirty to force the root and down to be updated. + renderer->rootNode()->parent()->markDirty(QSGNode::DirtyForceUpdate); + } + } + + QSGRenderer *renderer; +}; + +void NodesTest::simulatedEffect_data() +{ + QTest::addColumn("connected"); + + QTest::newRow("connected") << true; + QTest::newRow("disconnected") << false; +} + +void NodesTest::simulatedEffect() +{ + QFETCH(bool, connected); + + QSGRootNode root; + QSGRootNode source; + QSGTransformNode xform; + QSGSimpleRectNode geometry; + geometry.setRect(QRectF(0, 0, 1, 1)); + geometry.setColor(Qt::red); + + root.setFlag(QSGNode::OwnedByParent, false); + source.setFlag(QSGNode::OwnedByParent, false); + xform.setFlag(QSGNode::OwnedByParent, false); + geometry.setFlag(QSGNode::OwnedByParent, false); + + SimulatedEffectRenderer rootRenderer(&root, &geometry); + SimulatedEffectRenderer sourceRenderer(&source, &geometry); + + PseudoEffectNode effect(&sourceRenderer); + + /* + root Source is redirected into effect using the SimulatedEffectRenderer + / \ + xform effect + | + source + | + geometry + */ + + root.appendChildNode(&xform); + root.appendChildNode(&effect); + if (connected) + xform.appendChildNode(&source); + source.appendChildNode(&geometry); + QMatrix4x4 m; m.translate(1, 2, 3); + xform.setMatrix(m); + + // Clear all dirty states... + updater.updateStates(&root); + + rootRenderer.renderScene(); + + // compare that we got one render call to each + QCOMPARE(rootRenderer.renderCount, 1); + QCOMPARE(sourceRenderer.renderCount, 1); + QVERIFY(sourceRenderer.renderingOrder < rootRenderer.renderingOrder); + if (connected) // geometry is not rendered in this case, so skip it... + QCOMPARE(rootRenderer.matrix, xform.matrix()); + QCOMPARE(sourceRenderer.matrix, QMatrix4x4()); +} + +void NodesTest::basicOpacityNode() +{ + QSGOpacityNode n; + QCOMPARE(n.opacity(), 1.); + + n.setOpacity(0.5); + QCOMPARE(n.opacity(), 0.5); + + n.setOpacity(-1); + QCOMPARE(n.opacity(), 0.); + + n.setOpacity(2); + QCOMPARE(n.opacity(), 1.); +} + +void NodesTest::opacityPropegation() +{ + QSGRootNode root; + QSGOpacityNode *a = new QSGOpacityNode; + QSGOpacityNode *b = new QSGOpacityNode; + QSGOpacityNode *c = new QSGOpacityNode; + + QSGSimpleRectNode *geometry = new QSGSimpleRectNode; + geometry->setRect(0, 0, 100, 100); + + root.appendChildNode(a); + a->appendChildNode(b); + b->appendChildNode(c); + c->appendChildNode(geometry); + + a->setOpacity(0.9); + b->setOpacity(0.8); + c->setOpacity(0.7); + + updater.updateStates(&root); + + QCOMPARE(a->combinedOpacity(), 0.9); + QCOMPARE(b->combinedOpacity(), 0.9 * 0.8); + QCOMPARE(c->combinedOpacity(), 0.9 * 0.8 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.8 * 0.7); + + b->setOpacity(0.1); + updater.updateStates(&root); + + QCOMPARE(a->combinedOpacity(), 0.9); + QCOMPARE(b->combinedOpacity(), 0.9 * 0.1); + QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); + + b->setOpacity(0); + updater.updateStates(&root); + + QVERIFY(b->isSubtreeBlocked()); + + // Verify that geometry did not get updated as it is in a blocked + // subtree + QCOMPARE(c->combinedOpacity(), 0.9 * 0.1 * 0.7); + QCOMPARE(geometry->inheritedOpacity(), 0.9 * 0.1 * 0.7); +} + +void NodesTest::isBlockedCheck() +{ + QSGRootNode root; + QSGOpacityNode *opacity = new QSGOpacityNode(); + QSGNode *node = new QSGNode(); + + root.appendChildNode(opacity); + opacity->appendChildNode(node); + + QSGNodeUpdater updater; + + opacity->setOpacity(0); + QVERIFY(updater.isNodeBlocked(node, &root)); + + opacity->setOpacity(1); + QVERIFY(!updater.isNodeBlocked(node, &root)); +} + +QTEST_MAIN(NodesTest); + +#include "tst_nodestest.moc" diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/Double.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/Double.qml new file mode 100644 index 0000000000..99ffca1d62 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/Double.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: container + property bool on: false + border.color: "#ffffff" + color: "green" + width: 50 + height: 50 + NumberAnimation on x { + objectName: "animation" + running: container.on; from: 0; to: 600; loops: Animation.Infinite; duration: 2000 + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/attached.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/attached.qml new file mode 100644 index 0000000000..9dcfcd8752 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/attached.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 + +Rectangle { + width: 180; height: 200; + + Component { + id: delegate + Rectangle { + id: wrapper + width: 180; height: 200 + color: "blue" + + states: State { + name: "otherState" + PropertyChanges { target: wrapper; color: "green" } + } + + transitions: Transition { + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + ScriptAction { script: console.log(wrapper.ListView.delayRemove ? "on" : "off") } + } + + Component.onCompleted: { + console.log(ListView.delayRemove ? "on" : "off"); + wrapper.state = "otherState" + } + } + } + + ListView { + model: 1 + delegate: delegate + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty1.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty1.qml new file mode 100644 index 0000000000..9634c2c169 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty1.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { target: myRect; to: "red"; property: "border.colr"; duration: 1000 } + } + Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty2.qml new file mode 100644 index 0000000000..c121172a99 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badproperty2.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { target: myRect; to: "red"; property: "border"; duration: 1000 } + } + Component.onCompleted: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badtype1.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype1.qml new file mode 100644 index 0000000000..43e1ec8572 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype1.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + width: 50; height: 50 + x: 100; y: 100 + PropertyAnimation on x { from: "blue"; to: "green"; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badtype2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype2.qml new file mode 100644 index 0000000000..5341cb3d1c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype2.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { from: "blue"; to: "green"; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badtype3.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype3.qml new file mode 100644 index 0000000000..182efa0840 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype3.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + Rectangle { + color: "red" + ColorAnimation on color { from: 10; to: 15; } + width: 50; height: 50 + x: 100; y: 100 + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/badtype4.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype4.qml new file mode 100644 index 0000000000..f091e2430f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/badtype4.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; color: "blue" } + } + transitions: Transition { + //comment out each in turn to make sure each only animates the relevant property + ColorAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + NumberAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/disabledTransition.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/disabledTransition.qml new file mode 100644 index 0000000000..0fbafead8b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/disabledTransition.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + enabled: false + NumberAnimation { targets: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/dontAutoStart.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/dontAutoStart.qml new file mode 100644 index 0000000000..c0c0c65e3f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/dontAutoStart.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + Behavior on x { + NumberAnimation { id: myAnim; objectName: "MyAnim"; target: redRect; property: "y"; to: 300; loops: Animation.Infinite} + } + + } + +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart.qml new file mode 100644 index 0000000000..3eee0cfd35 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + SequentialAnimation on x { + running: false + NumberAnimation { objectName: "MyAnim"; running: true } + } + + } + +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart2.qml new file mode 100644 index 0000000000..e7b4164e4e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/dontStart2.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + + transitions: Transition { + SequentialAnimation { + NumberAnimation { id: myAnim; objectName: "MyAnim"; running: true } + } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/dotproperty.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/dotproperty.qml new file mode 100644 index 0000000000..e0e46dcef5 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/dotproperty.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; border.color: "blue" } + } + transitions: Transition { + ColorAnimation { properties: "border.color"; duration: 1000 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/doubleRegistrationBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/doubleRegistrationBug.qml new file mode 100644 index 0000000000..9ef3da20c0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/doubleRegistrationBug.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + Double { id: dub; on: parent.width < 800 } + Component.onCompleted: dub.on = false +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype1.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype1.qml new file mode 100644 index 0000000000..76129dd15e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype1.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; border.width: 10 } + } + transitions: Transition { + PropertyAnimation { properties: "x,border.width"; duration: 1000 } //x is real, border.width is int + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype2.qml new file mode 100644 index 0000000000..1a7166e3f3 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/mixedtype2.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 240 + height: 320 + Rectangle { + id: myRect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + MouseArea { + anchors.fill: parent + onClicked: if (wrapper.state == "state1") wrapper.state = ""; else wrapper.state = "state1"; + } + } + states: State { + name: "state1" + PropertyChanges { target: myRect; x: 200; color: "blue" } + } + transitions: Transition { + PropertyAnimation { properties: "x,color"; duration: 1000 } //x is real, color is color + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/nonTransitionBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/nonTransitionBug.qml new file mode 100644 index 0000000000..909c533e7b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/nonTransitionBug.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 200 + height: 200 + + Rectangle { + id: mover + objectName: "mover" + } + + states: [ + State { + name: "free" + }, + State { + name: "left" + PropertyChanges { + restoreEntryValues: false + target: mover + x: 0 + } + } + ] + + transitions: Transition { + PropertyAnimation { properties: "x"; duration: 50 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation.qml new file mode 100644 index 0000000000..d2006a1c6a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + path: Path { + startX: 50; startY: 50 + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation2.qml new file mode 100644 index 0000000000..951c5b2e57 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimation2.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + endRotation: 0 + orientationEntryInterval: .1 + orientationExitInterval: .1 + orientation: PathAnimation.RightFirst + path: Path { + startX: 50; startY: 50 + PathLine { x: 300; y: 300 } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimationNoStart.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimationNoStart.qml new file mode 100644 index 0000000000..be3501fabb --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathAnimationNoStart.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: redRect + color: "red" + width: 100; height: 100 + x: 50; y: 50 + } + + PathAnimation { + target: redRect + duration: 100; + path: Path { + //no startX/Y defined (should automatically start from redRects pos) + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolator.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolator.qml new file mode 100644 index 0000000000..0104412d7c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolator.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +PathInterpolator { + path: Path { + startX: 50; startY: 50 + PathCubic { + x: 300; y: 300 + + control1X: 300; control1Y: 50 + control2X: 50; control2Y: 300 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolatorBack.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolatorBack.qml new file mode 100644 index 0000000000..41366ef798 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathInterpolatorBack.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +PathInterpolator { + path: Path { + startX: 50; startY: 50 + PathLine { x: 50; y: 100 } + PathLine { x: 100; y: 100 } + PathLine { x: 100; y: 50 } + PathLine { x: 200; y: 50 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pathTransition.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pathTransition.qml new file mode 100644 index 0000000000..55ffc33f95 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pathTransition.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Rectangle { + width: 800 + height: 800 + + Rectangle { + id: redRect; objectName: "redRect" + color: "red" + width: 50; height: 50 + x: 500; y: 50 + } + + states: State { + name: "moved" + PropertyChanges { + target: redRect + x: 100; y: 700 + } + } + + transitions: Transition { + to: "moved"; reversible: true + PathAnimation { + id: pathAnim + target: redRect + duration: 300 + path: Path { + PathCurve { x: 100; y: 100 } + PathCurve { x: 200; y: 350 } + PathCurve { x: 600; y: 500 } + PathCurve {} + } + } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = parent.state == "moved" ? "" : "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBindingBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBindingBug.qml new file mode 100644 index 0000000000..359cda166f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBindingBug.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property bool animating: false + property int value: 0 + + NumberAnimation on value { + objectName: "animation" + paused: !rect.animating + to: 100 + duration: 50 + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBug.qml new file mode 100644 index 0000000000..fa2c4be4ba --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/pauseBug.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +SequentialAnimation { + id: animation + running: true + ScriptAction { script: animation.paused = true } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/properties.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/properties.qml new file mode 100644 index 0000000000..f0f730967c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/properties.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { to: 200 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/properties2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/properties2.qml new file mode 100644 index 0000000000..6b7f026e0b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/properties2.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { targets: theRect; properties: "x"; to: 200; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/properties3.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/properties3.qml new file mode 100644 index 0000000000..5eb65496d4 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/properties3.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { target: theRect; property: "x"; to: 300; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/properties4.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/properties4.qml new file mode 100644 index 0000000000..dfe8ad17e7 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/properties4.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { target: theRect; property: "y"; to: 200; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/properties5.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/properties5.qml new file mode 100644 index 0000000000..075fc9bc5a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/properties5.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { targets: theRect; properties: "y"; to: 200; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition.qml new file mode 100644 index 0000000000..968c5f6285 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition2.qml new file mode 100644 index 0000000000..f06165604a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition2.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { target: theRect; property: "y"; to: 200 } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition3.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition3.qml new file mode 100644 index 0000000000..7d3b3b9c6d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition3.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; properties: "y" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition4.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition4.qml new file mode 100644 index 0000000000..1c31a79634 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition4.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { target: theRect; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition5.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition5.qml new file mode 100644 index 0000000000..a2ff746900 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition5.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theRect; property: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition6.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition6.qml new file mode 100644 index 0000000000..d3db01efb0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition6.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + NumberAnimation { targets: theItem; properties: "x" } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition7.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition7.qml new file mode 100644 index 0000000000..98898de8ef --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/propertiesTransition7.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: theRect + objectName: "TheRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + } + + states: State { + name: "moved" + PropertyChanges { + target: theRect + x: 200 + } + } + transitions: Transition { + SpringAnimation { targets: theRect; properties: "x"; velocity: 10000 } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "moved" + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/registrationBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/registrationBug.qml new file mode 100644 index 0000000000..633da4e17f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/registrationBug.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property bool animating: true + property int value: 0 + + NumberAnimation { + target: rect + property: "value" + running: rect.animating + to: 100 + duration: 50 + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/rotation.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/rotation.qml new file mode 100644 index 0000000000..4dc42a1bd2 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/rotation.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Rectangle { + width: 600; height: 200 + + Row { + spacing: 5 + Rectangle { + id: rr + objectName: "rr" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr2 + objectName: "rr2" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr3 + objectName: "rr3" + color: "red" + width: 100; height: 100 + } + Rectangle { + id: rr4 + objectName: "rr4" + color: "red" + width: 100; height: 100 + } + } + + states: State { + name: "state1" + PropertyChanges { target: rr; rotation: 370 } + PropertyChanges { target: rr2; rotation: 370 } + PropertyChanges { target: rr3; rotation: 370 } + PropertyChanges { target: rr4; rotation: 370 } + } + + transitions: Transition { + RotationAnimation { target: rr; direction: RotationAnimation.Numerical; duration: 1000 } + RotationAnimation { target: rr2; direction: RotationAnimation.Clockwise; duration: 1000 } + RotationAnimation { target: rr3; direction: RotationAnimation.Counterclockwise; duration: 1000 } + RotationAnimation { target: rr4; direction: RotationAnimation.Shortest; duration: 1000 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/runningTrueBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/runningTrueBug.qml new file mode 100644 index 0000000000..bec6fab368 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/runningTrueBug.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +Rectangle { + color: "skyblue" + width: 500 + height: 200 + Rectangle { + objectName: "cloud" + color: "white" + y: 50 + width: 100 + height: 100 + + SequentialAnimation on x { + loops: Animation.Infinite + running: true + NumberAnimation { + id: firstAnimation + from: 0 + to: 500 + duration: 5000 + } + NumberAnimation { + id: secondAnimation + from: -100 + to: 0 + duration: 1000 + } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/transitionAssignmentBug.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/transitionAssignmentBug.qml new file mode 100644 index 0000000000..508693e0fc --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/transitionAssignmentBug.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + property bool nullObject + Component.onCompleted: nullObject = transitions.length > 0 && transitions[0] === null + + property list myTransitions: [Transition {}, Transition {}] + transitions: myTransitions +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource.qml new file mode 100644 index 0000000000..7a636b4003 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { id: anim; objectName: "MyAnim"; to: 200 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource2.qml b/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource2.qml new file mode 100644 index 0000000000..9788761ee8 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/data/valuesource2.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + color: "red" + width: 50; height: 50 + x: 100; y: 100 + NumberAnimation on x { id: anim; objectName: "MyAnim"; running: false; to: 200 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativeanimations/qdeclarativeanimations.pro b/tests/auto/qtquick2/qdeclarativeanimations/qdeclarativeanimations.pro new file mode 100644 index 0000000000..fd35266f66 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/qdeclarativeanimations.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdeclarativeanimations +SOURCES += tst_qdeclarativeanimations.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qdeclarativeanimations/tst_qdeclarativeanimations.cpp b/tests/auto/qtquick2/qdeclarativeanimations/tst_qdeclarativeanimations.cpp new file mode 100644 index 0000000000..ca329263e9 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeanimations/tst_qdeclarativeanimations.cpp @@ -0,0 +1,1106 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../../shared/util.h" + +class tst_qdeclarativeanimations : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativeanimations() {} + +private slots: + void initTestCase() { QDeclarativeEngine engine; } // ensure types are registered + + void simpleProperty(); + void simpleNumber(); + void simpleColor(); + void simpleRotation(); + void simplePath(); + void pathInterpolator(); + void pathInterpolatorBackwardJump(); + void pathWithNoStart(); + void alwaysRunToEnd(); + void complete(); + void resume(); + void dotProperty(); + void badTypes(); + void badProperties(); + void mixedTypes(); + void properties(); + void propertiesTransition(); + void pathTransition(); + void disabledTransition(); + void invalidDuration(); + void attached(); + void propertyValueSourceDefaultStart(); + void dontStart(); + void easingProperties(); + void rotation(); + void runningTrueBug(); + void nonTransitionBug(); + void registrationBug(); + void doubleRegistrationBug(); + void alwaysRunToEndRestartBug(); + void transitionAssignmentBug(); + void pauseBindingBug(); + void pauseBug(); +}; + +#define QTIMED_COMPARE(lhs, rhs) do { \ + for (int ii = 0; ii < 5; ++ii) { \ + if (lhs == rhs) \ + break; \ + QTest::qWait(50); \ + } \ + QCOMPARE(lhs, rhs); \ +} while (false) + +void tst_qdeclarativeanimations::simpleProperty() +{ + QQuickRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to().toReal() == 200.0); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.x(), 200.0); + + rect.setPos(QPointF(0,0)); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(),100.0); +} + +void tst_qdeclarativeanimations::simpleNumber() +{ + QQuickRectangle rect; + QDeclarativeNumberAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to() == 200); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.x(), qreal(200)); + + rect.setX(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(), qreal(100)); +} + +void tst_qdeclarativeanimations::simpleColor() +{ + QQuickRectangle rect; + QDeclarativeColorAnimation animation; + animation.setTarget(&rect); + animation.setProperty("color"); + animation.setTo(QColor("red")); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "color"); + QVERIFY(animation.to() == QColor("red")); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.color(), QColor("red")); + + rect.setColor(QColor("blue")); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); + + rect.setColor(QColor("green")); + animation.setFrom(QColor("blue")); + QVERIFY(animation.from() == QColor("blue")); + animation.restart(); + QCOMPARE(rect.color(), QColor("blue")); + QVERIFY(animation.isRunning()); + animation.setCurrentTime(125); + QCOMPARE(rect.color(), QColor::fromRgbF(0.498039, 0, 0.498039, 1)); +} + +void tst_qdeclarativeanimations::simpleRotation() +{ + QQuickRectangle rect; + QDeclarativeRotationAnimation animation; + animation.setTarget(&rect); + animation.setProperty("rotation"); + animation.setTo(270); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "rotation"); + QVERIFY(animation.to() == 270); + QVERIFY(animation.direction() == QDeclarativeRotationAnimation::Numerical); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTIMED_COMPARE(rect.rotation(), qreal(270)); + + rect.setRotation(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.rotation(), qreal(135)); +} + +void tst_qdeclarativeanimations::simplePath() +{ + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild(); + QVERIFY(pathAnim); + + pathAnim->start(); + pathAnim->pause(); + + pathAnim->setCurrentTime(30); + QCOMPARE(redRect->x(), qreal(167)); + QCOMPARE(redRect->y(), qreal(104)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + //verify animation runs to end + pathAnim->start(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + QTRY_COMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + pathAnim->setOrientation(QQuickPathAnimation::RightFirst); + QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); + pathAnim->start(); + QTRY_VERIFY(redRect->rotation() != 0); + pathAnim->stop(); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimation2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild(); + QVERIFY(pathAnim); + + QCOMPARE(pathAnim->orientation(), QQuickPathAnimation::RightFirst); + + pathAnim->start(); + pathAnim->pause(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + QCOMPARE(redRect->rotation(), qreal(-360)); + + pathAnim->setCurrentTime(50); + QCOMPARE(redRect->x(), qreal(175)); + QCOMPARE(redRect->y(), qreal(175)); + QCOMPARE(redRect->rotation(), qreal(-315)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + QCOMPARE(redRect->rotation(), qreal(0)); + } +} + +void tst_qdeclarativeanimations::pathInterpolator() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolator.qml"))); + QDeclarativePathInterpolator *interpolator = qobject_cast(c.create()); + QVERIFY(interpolator); + + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(0)); + + interpolator->setProgress(.5); + QCOMPARE(interpolator->progress(), qreal(.5)); + QCOMPARE(interpolator->x(), qreal(175)); + QCOMPARE(interpolator->y(), qreal(175)); + QCOMPARE(interpolator->angle(), qreal(270)); + + interpolator->setProgress(1); + QCOMPARE(interpolator->progress(), qreal(1)); + QCOMPARE(interpolator->x(), qreal(300)); + QCOMPARE(interpolator->y(), qreal(300)); + QCOMPARE(interpolator->angle(), qreal(0)); +} + +void tst_qdeclarativeanimations::pathInterpolatorBackwardJump() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathInterpolatorBack.qml"))); + QDeclarativePathInterpolator *interpolator = qobject_cast(c.create()); + QVERIFY(interpolator); + + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(270)); + + interpolator->setProgress(.5); + QCOMPARE(interpolator->progress(), qreal(.5)); + QCOMPARE(interpolator->x(), qreal(100)); + QCOMPARE(interpolator->y(), qreal(75)); + QCOMPARE(interpolator->angle(), qreal(90)); + + interpolator->setProgress(1); + QCOMPARE(interpolator->progress(), qreal(1)); + QCOMPARE(interpolator->x(), qreal(200)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(0)); + + //make sure we don't get caught in infinite loop here + interpolator->setProgress(0); + QCOMPARE(interpolator->progress(), qreal(0)); + QCOMPARE(interpolator->x(), qreal(50)); + QCOMPARE(interpolator->y(), qreal(50)); + QCOMPARE(interpolator->angle(), qreal(270)); +} + +void tst_qdeclarativeanimations::pathWithNoStart() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathAnimationNoStart.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *redRect = rect->findChild(); + QVERIFY(redRect); + QQuickPathAnimation *pathAnim = rect->findChild(); + QVERIFY(pathAnim); + + pathAnim->start(); + pathAnim->pause(); + QCOMPARE(redRect->x(), qreal(50)); + QCOMPARE(redRect->y(), qreal(50)); + + pathAnim->setCurrentTime(50); + QCOMPARE(redRect->x(), qreal(175)); + QCOMPARE(redRect->y(), qreal(175)); + + pathAnim->setCurrentTime(100); + QCOMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); + + redRect->setX(100); + redRect->setY(100); + pathAnim->start(); + QCOMPARE(redRect->x(), qreal(100)); + QCOMPARE(redRect->y(), qreal(100)); + QTRY_COMPARE(redRect->x(), qreal(300)); + QCOMPARE(redRect->y(), qreal(300)); +} + +void tst_qdeclarativeanimations::alwaysRunToEnd() +{ + QQuickRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setLoops(-1); + animation.setAlwaysRunToEnd(true); + QVERIFY(animation.loops() == -1); + QVERIFY(animation.alwaysRunToEnd() == true); + animation.start(); + QTest::qWait(1500); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(500); + QTIMED_COMPARE(rect.x(), qreal(200)); +} + +void tst_qdeclarativeanimations::complete() +{ + QQuickRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setFrom(1); + animation.setTo(200); + animation.setDuration(500); + QVERIFY(animation.from() == 1); + animation.start(); + QTest::qWait(50); + animation.stop(); + QVERIFY(rect.x() != qreal(200)); + animation.start(); + QTest::qWait(50); + QVERIFY(animation.isRunning()); + animation.complete(); + QCOMPARE(rect.x(), qreal(200)); +} + +void tst_qdeclarativeanimations::resume() +{ + QQuickRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setFrom(10); + animation.setTo(200); + animation.setDuration(1000); + QVERIFY(animation.from() == 10); + + animation.start(); + QTest::qWait(400); + animation.pause(); + qreal x = rect.x(); + QVERIFY(x != qreal(200) && x != qreal(10)); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + + animation.resume(); + QVERIFY(animation.isRunning()); + QVERIFY(!animation.isPaused()); + QTest::qWait(400); + animation.stop(); + QVERIFY(rect.x() > x); +} + +void tst_qdeclarativeanimations::dotProperty() +{ + QQuickRectangle rect; + QDeclarativeNumberAnimation animation; + animation.setTarget(&rect); + animation.setProperty("border.width"); + animation.setTo(10); + animation.start(); + QTest::qWait(animation.duration()+50); + QTIMED_COMPARE(rect.border()->width(), 10.0); + + rect.border()->setWidth(0); + animation.start(); + animation.pause(); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.border()->width(), 5.0); +} + +void tst_qdeclarativeanimations::badTypes() +{ + //don't crash + { + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("badtype1.qml"))); + + qApp->processEvents(); + + delete view; + } + + //make sure we get a compiler error + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype2.qml"))); + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + c.create(); + + QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected")); + } + + //make sure we get a compiler error + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype3.qml"))); + QTest::ignoreMessage(QtWarningMsg, "QDeclarativeComponent: Component is not ready"); + c.create(); + + QVERIFY(c.errors().count() == 1); + QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected")); + } + + //don't crash + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("badtype4.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(1000 + 50); + QQuickRectangle *myRect = rect->findChild("MyRect"); + QVERIFY(myRect); + QCOMPARE(myRect->x(),qreal(200)); + } +} + +void tst_qdeclarativeanimations::badProperties() +{ + //make sure we get a runtime error + { + QDeclarativeEngine engine; + + QDeclarativeComponent c1(&engine, QUrl::fromLocalFile(TESTDATA("badproperty1.qml"))); + QByteArray message = QUrl::fromLocalFile(TESTDATA("badproperty1.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\""; + QTest::ignoreMessage(QtWarningMsg, message); + QQuickRectangle *rect = qobject_cast(c1.create()); + QVERIFY(rect); + + QDeclarativeComponent c2(&engine, QUrl::fromLocalFile(TESTDATA("badproperty2.qml"))); + message = QUrl::fromLocalFile(TESTDATA("badproperty2.qml")).toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\""; + QTest::ignoreMessage(QtWarningMsg, message); + rect = qobject_cast(c2.create()); + QVERIFY(rect); + + //### should we warn here are well? + //rect->setState("state1"); + } +} + +//test animating mixed types with property animation in a transition +//for example, int + real; color + real; etc +void tst_qdeclarativeanimations::mixedTypes() +{ + //assumes border.width stays a real -- not real robust + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype1.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(500); + QQuickRectangle *myRect = rect->findChild("MyRect"); + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); + QVERIFY(myRect->border()->width() > 1 && myRect->border()->width() < 10); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("mixedtype2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(500); + QQuickRectangle *myRect = rect->findChild("MyRect"); + QVERIFY(myRect); + + //rather inexact -- is there a better way? + QVERIFY(myRect->x() > 100 && myRect->x() < 200); + QVERIFY(myRect->color() != QColor("red") && myRect->color() != QColor("blue")); + } +} + +void tst_qdeclarativeanimations::properties() +{ + const int waitDuration = 300; + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties3.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(300)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties4.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->y(),qreal(200)); + QTIMED_COMPARE(myRect->x(),qreal(100)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("properties5.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(100)); + QTIMED_COMPARE(myRect->y(),qreal(200)); + } +} + +void tst_qdeclarativeanimations::propertiesTransition() +{ + const int waitDuration = 300; + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + QCOMPARE(myRect->y(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->y(),qreal(200)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition3.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + QCOMPARE(myRect->y(),qreal(100)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition4.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition5.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + + /*{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition6.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(100)); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(100)); + }*/ + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("propertiesTransition7.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + QTest::qWait(waitDuration); + QTIMED_COMPARE(myRect->x(),qreal(200)); + } + +} + +void tst_qdeclarativeanimations::pathTransition() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathTransition.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("redRect"); + QVERIFY(myRect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started + QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(100)) && qFuzzyCompare(myRect->y(), qreal(700))); + QTest::qWait(100); + + QQuickItemPrivate::get(rect)->setState(""); + QTRY_VERIFY(myRect->x() < 500 && myRect->x() > 100 && myRect->y() > 50 && myRect->y() < 700 ); //animation started + QTRY_VERIFY(qFuzzyCompare(myRect->x(), qreal(500)) && qFuzzyCompare(myRect->y(), qreal(50))); +} + +void tst_qdeclarativeanimations::disabledTransition() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabledTransition.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *myRect = rect->findChild("TheRect"); + QVERIFY(myRect); + + QDeclarativeTransition *trans = rect->findChild(); + QVERIFY(trans); + + QCOMPARE(trans->enabled(), false); + + QQuickItemPrivate::get(rect)->setState("moved"); + QCOMPARE(myRect->x(),qreal(200)); + + trans->setEnabled(true); + + QQuickItemPrivate::get(rect)->setState(""); + QCOMPARE(myRect->x(),qreal(200)); + QTest::qWait(300); + QTIMED_COMPARE(myRect->x(),qreal(100)); +} + +void tst_qdeclarativeanimations::invalidDuration() +{ + QDeclarativePropertyAnimation *animation = new QDeclarativePropertyAnimation; + QTest::ignoreMessage(QtWarningMsg, ": QML PropertyAnimation: Cannot set a duration of < 0"); + animation->setDuration(-1); + QCOMPARE(animation->duration(), 250); + + QDeclarativePauseAnimation *pauseAnimation = new QDeclarativePauseAnimation; + QTest::ignoreMessage(QtWarningMsg, ": QML PauseAnimation: Cannot set a duration of < 0"); + pauseAnimation->setDuration(-1); + QCOMPARE(pauseAnimation->duration(), 250); +} + +void tst_qdeclarativeanimations::attached() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("attached.qml"))); + QTest::ignoreMessage(QtDebugMsg, "off"); + QTest::ignoreMessage(QtDebugMsg, "on"); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); +} + +void tst_qdeclarativeanimations::propertyValueSourceDefaultStart() +{ + { + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource.qml"))); + + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim); + QVERIFY(myAnim->isRunning()); + } + + { + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valuesource2.qml"))); + + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim); + QVERIFY(myAnim->isRunning() == false); + } + + { + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontAutoStart.qml"))); + + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim && myAnim->qtAnimation()); + QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); + } +} + + +void tst_qdeclarativeanimations::dontStart() +{ + { + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml"))); + + QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim && myAnim->qtAnimation()); + QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); + } + + { + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart2.qml"))); + + QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim && myAnim->qtAnimation()); + QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); + } +} + +void tst_qdeclarativeanimations::easingProperties() +{ + { + QDeclarativeEngine engine; + QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }"; + QDeclarativeComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad); + } + + { + QDeclarativeEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }"; + QDeclarativeComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce); + QCOMPARE(animObject->easing().amplitude(), 5.0); + } + + { + QDeclarativeEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}"; + QDeclarativeComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic); + QCOMPARE(animObject->easing().amplitude(), 5.0); + QCOMPARE(animObject->easing().period(), 3.0); + } + + { + QDeclarativeEngine engine; + QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }"; + QDeclarativeComponent animationComponent(&engine); + animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativePropertyAnimation *animObject = qobject_cast(animationComponent.create()); + + QVERIFY(animObject != 0); + QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack); + QCOMPARE(animObject->easing().overshoot(), 2.0); + } +} + +void tst_qdeclarativeanimations::rotation() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("rotation.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *rr = rect->findChild("rr"); + QQuickRectangle *rr2 = rect->findChild("rr2"); + QQuickRectangle *rr3 = rect->findChild("rr3"); + QQuickRectangle *rr4 = rect->findChild("rr4"); + + QQuickItemPrivate::get(rect)->setState("state1"); + QTest::qWait(800); + qreal r1 = rr->rotation(); + qreal r2 = rr2->rotation(); + qreal r3 = rr3->rotation(); + qreal r4 = rr4->rotation(); + + QVERIFY(r1 > qreal(0) && r1 < qreal(370)); + QVERIFY(r2 > qreal(0) && r2 < qreal(370)); + QVERIFY(r3 < qreal(0) && r3 > qreal(-350)); + QVERIFY(r4 > qreal(0) && r4 < qreal(10)); + QCOMPARE(r1,r2); + QVERIFY(r4 < r2); + + QTest::qWait(800); + QTIMED_COMPARE(rr->rotation() + rr2->rotation() + rr3->rotation() + rr4->rotation(), qreal(370*4)); +} + +void tst_qdeclarativeanimations::runningTrueBug() +{ + //ensure we start correctly when "running: true" is explicitly set + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrueBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *cloud = rect->findChild("cloud"); + QVERIFY(cloud); + QTest::qWait(1000); + QVERIFY(cloud->x() > qreal(0)); +} + +//QTBUG-12805 +void tst_qdeclarativeanimations::nonTransitionBug() +{ + //tests that the animation values from the previous transition are properly cleared + //in the case where an animation in the transition doesn't match anything (but previously did) + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonTransitionBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QQuickRectangle *mover = rect->findChild("mover"); + + mover->setX(100); + QCOMPARE(mover->x(), qreal(100)); + + rectPrivate->setState("left"); + QTRY_COMPARE(mover->x(), qreal(0)); + + mover->setX(100); + QCOMPARE(mover->x(), qreal(100)); + + //make sure we don't try to animate back to 0 + rectPrivate->setState("free"); + QTest::qWait(300); + QCOMPARE(mover->x(), qreal(100)); +} + +//QTBUG-14042 +void tst_qdeclarativeanimations::registrationBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("registrationBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QTRY_COMPARE(rect->property("value"), QVariant(int(100))); +} + +void tst_qdeclarativeanimations::doubleRegistrationBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("doubleRegistrationBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QDeclarativeAbstractAnimation *anim = rect->findChild("animation"); + QVERIFY(anim != 0); + QTRY_COMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Stopped); +} + +//QTBUG-16736 +void tst_qdeclarativeanimations::alwaysRunToEndRestartBug() +{ + QQuickRectangle rect; + QDeclarativePropertyAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(1000); + animation.setLoops(-1); + animation.setAlwaysRunToEnd(true); + QVERIFY(animation.loops() == -1); + QVERIFY(animation.alwaysRunToEnd() == true); + animation.start(); + animation.stop(); + animation.start(); + animation.stop(); + QTest::qWait(500); + QVERIFY(rect.x() != qreal(200)); + QTest::qWait(800); + QTIMED_COMPARE(rect.x(), qreal(200)); + QCOMPARE(static_cast(&animation)->qtAnimation()->state(), QAbstractAnimation::Stopped); +} + +//QTBUG-20227 +void tst_qdeclarativeanimations::transitionAssignmentBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("transitionAssignmentBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->property("nullObject").toBool(), false); +} + +//QTBUG-19080 +void tst_qdeclarativeanimations::pauseBindingBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBindingBug.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QDeclarativeAbstractAnimation *anim = rect->findChild("animation"); + QVERIFY(anim->qtAnimation()->state() == QAbstractAnimation::Paused); + + delete rect; +} + +//QTBUG-13598 +void tst_qdeclarativeanimations::pauseBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pauseBug.qml"))); + QDeclarativeAbstractAnimation *anim = qobject_cast(c.create()); + QVERIFY(anim != 0); + QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimation::Paused); + QCOMPARE(anim->isPaused(), true); + QCOMPARE(anim->isRunning(), true); + + delete anim; +} + +QTEST_MAIN(tst_qdeclarativeanimations) + +#include "tst_qdeclarativeanimations.moc" diff --git a/tests/auto/qtquick2/qdeclarativeapplication/qdeclarativeapplication.pro b/tests/auto/qtquick2/qdeclarativeapplication/qdeclarativeapplication.pro new file mode 100644 index 0000000000..b86f431d31 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeapplication/qdeclarativeapplication.pro @@ -0,0 +1,7 @@ +CONFIG += testcase +TARGET = tst_qdeclarativeapplication +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativeapplication.cpp +QT += core-private gui-private declarative-private quick-private testlib + diff --git a/tests/auto/qtquick2/qdeclarativeapplication/tst_qdeclarativeapplication.cpp b/tests/auto/qtquick2/qdeclarativeapplication/tst_qdeclarativeapplication.cpp new file mode 100644 index 0000000000..be822d8f7f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativeapplication/tst_qdeclarativeapplication.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +class tst_qdeclarativeapplication : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativeapplication(); + +private slots: + void active(); + void layoutDirection(); + void inputPanel(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativeapplication::tst_qdeclarativeapplication() +{ +} + +void tst_qdeclarativeapplication::active() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Item { property bool active: Qt.application.active }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + QQuickView view; + item->setParentItem(view.rootObject()); + + // not active + QVERIFY(!item->property("active").toBool()); + QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); + + // active + view.show(); + view.requestActivateWindow(); + QTest::qWait(50); + QEXPECT_FAIL("", "QTBUG-21573", Abort); + QTRY_COMPARE(view.status(), QQuickView::Ready); + QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); + +#if 0 + // QGuiApplication has no equivalent of setActiveWindow(0). QTBUG-21573 + // Is this different to clearing the active state of the window or can it be removed? + // On Mac, setActiveWindow(0) on mac does not deactivate the current application, + // must switch to a different app or hide the current app to trigger this + // on mac, setActiveWindow(0) on mac does not deactivate the current application + // (you have to switch to a different app or hide the current app to trigger this) + + // not active again + QGuiApplication::setActiveWindow(0); + QVERIFY(!item->property("active").toBool()); + QCOMPARE(item->property("active").toBool(), QGuiApplication::activeWindow() != 0); +#endif + +} + +void tst_qdeclarativeapplication::layoutDirection() +{ + + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Item { property bool layoutDirection: Qt.application.layoutDirection }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + QQuickView view; + item->setParentItem(view.rootObject()); + + // not mirrored + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); + + // mirrored + QGuiApplication::setLayoutDirection(Qt::RightToLeft); + QEXPECT_FAIL("", "QTBUG-21573", Abort); + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::RightToLeft); + + // not mirrored again + QGuiApplication::setLayoutDirection(Qt::LeftToRight); + QCOMPARE(Qt::LayoutDirection(item->property("layoutDirection").toInt()), Qt::LeftToRight); +} + +void tst_qdeclarativeapplication::inputPanel() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Item { property variant inputPanel: Qt.application.inputPanel }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + QQuickView view; + item->setParentItem(view.rootObject()); + + // check that the inputPanel property maches with application's input panel + QCOMPARE(qvariant_cast(item->property("inputPanel")), qApp->inputPanel()); +} + +QTEST_MAIN(tst_qdeclarativeapplication) + +#include "tst_qdeclarativeapplication.moc" diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/binding.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/binding.qml new file mode 100644 index 0000000000..5aceefa743 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/binding.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + property real basex : 0 + property real movedx: 200 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + x: basex + Behavior on x { NumberAnimation { duration: 800; } } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: movedx + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/color.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/color.qml new file mode 100644 index 0000000000..a318578a9b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/color.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; + color: "green" + Behavior on color { ColorAnimation { duration: 500; } } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "red" + when: clicker.pressed + PropertyChanges { + target: rect + color: "red" + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/cpptrigger.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/cpptrigger.qml new file mode 100644 index 0000000000..f033ec5aeb --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/cpptrigger.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { NumberAnimation { duration: 500; } } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/delayedRegistration.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/delayedRegistration.qml new file mode 100644 index 0000000000..ed35a308f7 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/delayedRegistration.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: container + + width: 400; height: 400; + property Item myItem + + function doCreate() { + myItem = myComponent.createObject(container) + myItem.x = 100 + } + + Component { + id: myComponent + Rectangle { + width: 100 + height: 100 + color: "green" + Behavior on x { NumberAnimation { duration: 500 } } + } + } + + Component.onCompleted: doCreate() +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/disabled.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/disabled.qml new file mode 100644 index 0000000000..20860d8dde --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/disabled.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { + objectName: "MyBehavior"; + enabled: false + NumberAnimation { duration: 200; } + } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/dontStart.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/dontStart.qml new file mode 100644 index 0000000000..38e1ea9d9e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/dontStart.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: wrapper + width: 600 + height: 400 + + Rectangle { + id: redRect + width: 100; height: 100 + color: Qt.rgba(1,0,0) + Behavior on x { + NumberAnimation {id: myAnim; objectName: "MyAnim"; running: true } + } + + } + +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/empty.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/empty.qml new file mode 100644 index 0000000000..d8f115390a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/empty.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x {} + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/explicit.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/explicit.qml new file mode 100644 index 0000000000..20875c30e3 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/explicit.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { + objectName: "MyBehavior"; + NumberAnimation { target: rect; property: "x"; duration: 500; } + } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty.qml new file mode 100644 index 0000000000..a05ab7d54b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on pos { PropertyAnimation { duration: 500; } } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + pos: Qt.point(200,0); + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty2.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty2.qml new file mode 100644 index 0000000000..2f3de5131c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupProperty2.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on border.width { NumberAnimation { duration: 500; } } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + border.width: 4; + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/groupedPropertyCrash.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupedPropertyCrash.qml new file mode 100644 index 0000000000..6835902bc5 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/groupedPropertyCrash.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + Text { + Behavior on anchors.verticalCenterOffset { NumberAnimation { duration: 300; } } + text: "Hello World" + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/loop.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/loop.qml new file mode 100644 index 0000000000..3e8d88734d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/loop.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { NumberAnimation { duration: 200; } } + onXChanged: x = 100; + } + states: State { + name: "moved" + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/nonSelecting2.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/nonSelecting2.qml new file mode 100644 index 0000000000..6357094cfe --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/nonSelecting2.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { + objectName: "MyBehavior"; + NumberAnimation { targets: rect; properties: "y"; duration: 200; } + } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/parent.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/parent.qml new file mode 100644 index 0000000000..f8c2731d86 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/parent.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on parent { + SequentialAnimation { + PauseAnimation { duration: 500 } + PropertyAction {} + } + } + } + Item { + id: newParent + objectName: "NewParent" + x: 100 + } + states: State { + name: "reparented" + PropertyChanges { + target: rect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/qtbug12295.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/qtbug12295.qml new file mode 100644 index 0000000000..c6bef581a4 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/qtbug12295.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + color: "blue" + + Rectangle { + id: myRect + objectName: "myRect" + width: 100 + height: 100 + Behavior on x { + NumberAnimation { duration: 500 } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/reassignedAnimation.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/reassignedAnimation.qml new file mode 100644 index 0000000000..5731cb3efd --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/reassignedAnimation.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { + id: myBehavior + objectName: "MyBehavior" + NumberAnimation {id: na1; duration: 200 } + } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } + + NumberAnimation {id: na2; duration: 1000 } + Component.onCompleted: { + myBehavior.animation = na2; + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/runningTrue.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/runningTrue.qml new file mode 100644 index 0000000000..4fd1136f3a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/runningTrue.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width:200; height:200 + + property real myValue: 0 + + Rectangle { + anchors.centerIn: parent + width: 100 + height: 100 + color: "green" + smooth: true + rotation: myValue + Behavior on rotation { + RotationAnimation { id: rotAnim; objectName: "rotAnim"; direction: RotationAnimation.Shortest } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/scripttrigger.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/scripttrigger.qml new file mode 100644 index 0000000000..ff71f2b1b0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/scripttrigger.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + + onColorChanged: { + rect.x = 200 + } + + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { NumberAnimation { duration: 800; } } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/simple.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/simple.qml new file mode 100644 index 0000000000..c64a6e1928 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/simple.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + Rectangle { + id: rect + objectName: "MyRect" + width: 100; height: 100; color: "green" + Behavior on x { + objectName: "MyBehavior"; + NumberAnimation {id: na; duration: 500; } + } + } + MouseArea { + id: clicker + anchors.fill: parent + } + states: State { + name: "moved" + when: clicker.pressed + PropertyChanges { + target: rect + x: 200 + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/startOnCompleted.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/startOnCompleted.qml new file mode 100644 index 0000000000..fdc3779a5c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/startOnCompleted.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + id: innerRect + width: 100; height: 100 + color: "green" + Behavior on x { NumberAnimation {} } + } + + Component.onCompleted: innerRect.x = 100 +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/startup.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/startup.qml new file mode 100644 index 0000000000..9fa74ca39e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/startup.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + Rectangle { + objectName: "innerRect" + height: 100; width: 100; color: "green" + property real targetX: 100 + + x: targetX + Behavior on x { + NumberAnimation {} + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/startup2.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/startup2.qml new file mode 100644 index 0000000000..0654ef3644 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/startup2.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Rectangle { + width: 800; + height: 480; + + Text { id:theText; text: "hello world" } + + Rectangle { + objectName: "innerRect" + color: "red" + x: theText.width + Behavior on x { NumberAnimation {} } + width: 100; height: 100 + } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/data/valueType.qml b/tests/auto/qtquick2/qdeclarativebehaviors/data/valueType.qml new file mode 100644 index 0000000000..7bc8297dc7 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/data/valueType.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + + color.r: 1 + color.g: 0 + color.b: 1 + + Behavior on color.r { NumberAnimation { duration: 500; } } + + function changeR() { color.r = 0 } +} diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/qdeclarativebehaviors.pro b/tests/auto/qtquick2/qdeclarativebehaviors/qdeclarativebehaviors.pro new file mode 100644 index 0000000000..3ac9446a4c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/qdeclarativebehaviors.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdeclarativebehaviors +SOURCES += tst_qdeclarativebehaviors.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp b/tests/auto/qtquick2/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp new file mode 100644 index 0000000000..526a23f262 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativebehaviors/tst_qdeclarativebehaviors.cpp @@ -0,0 +1,474 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qdeclarativebehaviors : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativebehaviors() {} + +private slots: + void init() { qApp->processEvents(); } //work around animation timer bug (QTBUG-22865) + void simpleBehavior(); + void scriptTriggered(); + void cppTriggered(); + void loop(); + void colorBehavior(); + void parentBehavior(); + void replaceBinding(); + //void transitionOverrides(); + void group(); + void valueType(); + void emptyBehavior(); + void explicitSelection(); + void nonSelectingBehavior(); + void reassignedAnimation(); + void disabled(); + void dontStart(); + void startup(); + void groupedPropertyCrash(); + void runningTrue(); + void sameValue(); + void delayedRegistration(); + void startOnCompleted(); +}; + +void tst_qdeclarativebehaviors::simpleBehavior() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("simple.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + QTRY_VERIFY(qobject_cast(rect->findChild("MyBehavior"))->animation()); + + QQuickItemPrivate::get(rect)->setState("moved"); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); + //i.e. the behavior has been triggered + + delete rect; +} + +void tst_qdeclarativebehaviors::scriptTriggered() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("scripttrigger.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + rect->setColor(QColor("red")); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); + //i.e. the behavior has been triggered + + delete rect; +} + +void tst_qdeclarativebehaviors::cppTriggered() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("cpptrigger.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QTRY_VERIFY(innerRect); + + innerRect->setProperty("x", 200); + QTRY_VERIFY(innerRect->x() > 0); + QTRY_VERIFY(innerRect->x() < 200); //i.e. the behavior has been triggered + + delete rect; +} + +void tst_qdeclarativebehaviors::loop() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("loop.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + //don't crash + QQuickItemPrivate::get(rect)->setState("moved"); + + delete rect; +} + +void tst_qdeclarativebehaviors::colorBehavior() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("color.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("red"); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->color() != QColor("red")); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->color() != QColor("green")); + //i.e. the behavior has been triggered + + delete rect; +} + +void tst_qdeclarativebehaviors::parentBehavior() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("parent.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("reparented"); + QTRY_VERIFY(rect->findChild("MyRect")->parentItem() != rect->findChild("NewParent")); + QTRY_VERIFY(rect->findChild("MyRect")->parentItem() == rect->findChild("NewParent")); + + delete rect; +} + +void tst_qdeclarativebehaviors::replaceBinding() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("binding.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QTRY_VERIFY(innerRect); + QTRY_VERIFY(innerRect->x() > 0); + QTRY_VERIFY(innerRect->x() < 200); + //i.e. the behavior has been triggered + QTRY_COMPARE(innerRect->x(), (qreal)200); + rect->setProperty("basex", 10); + QTRY_COMPARE(innerRect->x(), (qreal)200); + rect->setProperty("movedx", 210); + QTRY_COMPARE(innerRect->x(), (qreal)210); + + QQuickItemPrivate::get(rect)->setState(""); + QTRY_VERIFY(innerRect->x() > 10); + QTRY_VERIFY(innerRect->x() < 210); //i.e. the behavior has been triggered + QTRY_COMPARE(innerRect->x(), (qreal)10); + rect->setProperty("movedx", 200); + QTRY_COMPARE(innerRect->x(), (qreal)10); + rect->setProperty("basex", 20); + QTRY_COMPARE(innerRect->x(), (qreal)20); + + delete rect; +} + +void tst_qdeclarativebehaviors::group() +{ + /* XXX TODO Create a test element for this case. + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + qDebug() << c.errorString(); + QTRY_VERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + //QTest::qWait(200); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); + //i.e. the behavior has been triggered + + delete rect; + } + */ + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupProperty2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QTRY_VERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->border()->width() > 0); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->border()->width() < 4); + //i.e. the behavior has been triggered + + delete rect; + } +} + +void tst_qdeclarativebehaviors::valueType() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("valueType.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + //QTBUG-20827 + QCOMPARE(rect->color(), QColor::fromRgb(255,0,255)); + + delete rect; +} + +void tst_qdeclarativebehaviors::emptyBehavior() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("empty.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + qreal x = qobject_cast(rect->findChild("MyRect"))->x(); + QCOMPARE(x, qreal(200)); //should change immediately + + delete rect; +} + +void tst_qdeclarativebehaviors::explicitSelection() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("explicit.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() > 0); + QTRY_VERIFY(qobject_cast(rect->findChild("MyRect"))->x() < 200); + //i.e. the behavior has been triggered + + delete rect; +} + +void tst_qdeclarativebehaviors::nonSelectingBehavior() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("nonSelecting2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickItemPrivate::get(rect)->setState("moved"); + qreal x = qobject_cast(rect->findChild("MyRect"))->x(); + QCOMPARE(x, qreal(200)); //should change immediately + + delete rect; +} + +void tst_qdeclarativebehaviors::reassignedAnimation() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml"))); + QString warning = QUrl::fromLocalFile(TESTDATA("reassignedAnimation.qml")).toString() + ":9:9: QML Behavior: Cannot change the animation assigned to a Behavior."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + QCOMPARE(qobject_cast( + rect->findChild("MyBehavior")->animation())->duration(), 200); + + delete rect; +} + +void tst_qdeclarativebehaviors::disabled() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("disabled.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + QCOMPARE(rect->findChild("MyBehavior")->enabled(), false); + + QQuickItemPrivate::get(rect)->setState("moved"); + qreal x = qobject_cast(rect->findChild("MyRect"))->x(); + QCOMPARE(x, qreal(200)); //should change immediately + + delete rect; +} + +void tst_qdeclarativebehaviors::dontStart() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("dontStart.qml"))); + + QString warning = c.url().toString() + ":13:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes."; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *myAnim = rect->findChild("MyAnim"); + QVERIFY(myAnim && myAnim->qtAnimation()); + QVERIFY(myAnim->qtAnimation()->state() == QAbstractAnimation::Stopped); + + delete rect; +} + +void tst_qdeclarativebehaviors::startup() +{ + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *innerRect = rect->findChild("innerRect"); + QVERIFY(innerRect); + + QCOMPARE(innerRect->x(), qreal(100)); //should be set immediately + + delete rect; + } + + { + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startup2.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *innerRect = rect->findChild("innerRect"); + QVERIFY(innerRect); + + QQuickText *text = rect->findChild(); + QVERIFY(text); + + QCOMPARE(innerRect->x(), text->width()); //should be set immediately + + delete rect; + } +} + +//QTBUG-10799 +void tst_qdeclarativebehaviors::groupedPropertyCrash() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("groupedPropertyCrash.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); //don't crash + + delete rect; +} + +//QTBUG-5491 +void tst_qdeclarativebehaviors::runningTrue() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("runningTrue.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QDeclarativeAbstractAnimation *animation = rect->findChild("rotAnim"); + QVERIFY(animation); + + QSignalSpy runningSpy(animation, SIGNAL(runningChanged(bool))); + rect->setProperty("myValue", 180); + QTRY_VERIFY(runningSpy.count() > 0); + + delete rect; +} + +//QTBUG-12295 +void tst_qdeclarativebehaviors::sameValue() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("qtbug12295.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *target = rect->findChild("myRect"); + QVERIFY(target); + + target->setX(100); + QCOMPARE(target->x(), qreal(100)); + + target->setProperty("x", 0); + QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); + QTRY_VERIFY(target->x() == qreal(0)); //make sure Behavior has finished. + + target->setX(100); + QCOMPARE(target->x(), qreal(100)); + + //this is the main point of the test -- the behavior needs to be triggered again + //even though we set 0 twice in a row. + target->setProperty("x", 0); + QTRY_VERIFY(target->x() != qreal(0) && target->x() != qreal(100)); + + delete rect; +} + +//QTBUG-18362 +void tst_qdeclarativebehaviors::delayedRegistration() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("delayedRegistration.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickItem *innerRect = rect->property("myItem").value(); + QVERIFY(innerRect != 0); + + QCOMPARE(innerRect->property("x").toInt(), int(0)); + + QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); +} + +//QTBUG-22555 +void tst_qdeclarativebehaviors::startOnCompleted() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("startOnCompleted.qml"))); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickItem *innerRect = rect->findChild(); + QVERIFY(innerRect != 0); + + QCOMPARE(innerRect->property("x").toInt(), int(0)); + + QTRY_COMPARE(innerRect->property("x").toInt(), int(100)); + + delete rect; +} + +QTEST_MAIN(tst_qdeclarativebehaviors) + +#include "tst_qdeclarativebehaviors.moc" diff --git a/tests/auto/qtquick2/qdeclarativefontloader/data/daniel.ttf b/tests/auto/qtquick2/qdeclarativefontloader/data/daniel.ttf new file mode 100644 index 0000000000..aae50d5035 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativefontloader/data/daniel.ttf differ diff --git a/tests/auto/qtquick2/qdeclarativefontloader/data/dummy.ttf b/tests/auto/qtquick2/qdeclarativefontloader/data/dummy.ttf new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/qtquick2/qdeclarativefontloader/data/qtbug-20268.qml b/tests/auto/qtquick2/qdeclarativefontloader/data/qtbug-20268.qml new file mode 100644 index 0000000000..0eafdfa17b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativefontloader/data/qtbug-20268.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + id: test + property variant fontloader: fontloaderelement + height: 100; width: 100 + property bool usename: false + property int statenum: 1 + property alias name: fontloaderelement.name + property alias source: fontloaderelement.source + property alias status: fontloaderelement.status + + FontLoader { + id: fontloaderelement + } + + states: [ + State { name: "start"; when: !usename + PropertyChanges { target: fontloaderelement; source: "tarzeau_ocr_a.ttf" } + }, + State { name: "changefont"; when: usename + PropertyChanges { target: fontloaderelement; name: "Tahoma" } + } + ] + + Text { id: textelement; text: fontloaderelement.name; color: "black" } +} diff --git a/tests/auto/qtquick2/qdeclarativefontloader/data/tarzeau_ocr_a.ttf b/tests/auto/qtquick2/qdeclarativefontloader/data/tarzeau_ocr_a.ttf new file mode 100644 index 0000000000..cf93f9651f Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativefontloader/data/tarzeau_ocr_a.ttf differ diff --git a/tests/auto/qtquick2/qdeclarativefontloader/qdeclarativefontloader.pro b/tests/auto/qtquick2/qdeclarativefontloader/qdeclarativefontloader.pro new file mode 100644 index 0000000000..de9461f7ac --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativefontloader/qdeclarativefontloader.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qdeclarativefontloader +macx:CONFIG -= app_bundle + +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qdeclarativefontloader.cpp ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/qtquick2/qdeclarativefontloader/tst_qdeclarativefontloader.cpp new file mode 100644 index 0000000000..86789068ad --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include "../../shared/testhttpserver.h" +#include +#include + +#define SERVER_PORT 14448 + +class tst_qdeclarativefontloader : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativefontloader(); + +private slots: + void init(); + void noFont(); + void namedFont(); + void localFont(); + void failLocalFont(); + void webFont(); + void redirWebFont(); + void failWebFont(); + void changeFont(); + void changeFontSourceViaState(); + +private: + QDeclarativeEngine engine; + TestHTTPServer server; +}; + +tst_qdeclarativefontloader::tst_qdeclarativefontloader() : + server(SERVER_PORT) +{ + server.serveDirectory(TESTDATA("")); +} + +void tst_qdeclarativefontloader::init() +{ + QVERIFY(server.isValid()); +} + +void tst_qdeclarativefontloader::noFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QCOMPARE(fontObject->name(), QString("")); + QCOMPARE(fontObject->source(), QUrl("")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Null); + + delete fontObject; +} + +void tst_qdeclarativefontloader::namedFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { name: \"Helvetica\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QCOMPARE(fontObject->source(), QUrl("")); + QCOMPARE(fontObject->name(), QString("Helvetica")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::localFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + TESTDATA("tarzeau_ocr_a.ttf") + "\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::failLocalFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\" }"; + QTest::ignoreMessage(QtWarningMsg, QString("file::2:1: QML FontLoader: Cannot load font: \"" + QUrl::fromLocalFile(TESTDATA("dummy.ttf")).toString() + "\"").toUtf8().constData()); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error); +} + +void tst_qdeclarativefontloader::webFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/tarzeau_ocr_a.ttf\" }"; + QDeclarativeComponent component(&engine); + + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::redirWebFont() +{ + server.addRedirect("olddir/oldname.ttf","../tarzeau_ocr_a.ttf"); + + QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/olddir/oldname.ttf\" }"; + QDeclarativeComponent component(&engine); + + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); +} + +void tst_qdeclarativefontloader::failWebFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { source: \"http://localhost:14448/nonexist.ttf\" }"; + QTest::ignoreMessage(QtWarningMsg, "file::2:1: QML FontLoader: Cannot load font: \"http://localhost:14448/nonexist.ttf\""); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("")); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Error); +} + +void tst_qdeclarativefontloader::changeFont() +{ + QString componentStr = "import QtQuick 2.0\nFontLoader { source: font }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeFontLoader *fontObject = qobject_cast(component.create()); + + QVERIFY(fontObject != 0); + + QSignalSpy nameSpy(fontObject, SIGNAL(nameChanged())); + QSignalSpy statusSpy(fontObject, SIGNAL(statusChanged())); + + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QCOMPARE(nameSpy.count(), 0); + QCOMPARE(statusSpy.count(), 0); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + + ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf"); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Loading); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QCOMPARE(nameSpy.count(), 1); + QCOMPARE(statusSpy.count(), 2); + QTRY_COMPARE(fontObject->name(), QString("Daniel")); + + ctxt->setContextProperty("font", QUrl::fromLocalFile(TESTDATA("tarzeau_ocr_a.ttf"))); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QCOMPARE(nameSpy.count(), 2); + QCOMPARE(statusSpy.count(), 2); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + + ctxt->setContextProperty("font", "http://localhost:14448/daniel.ttf"); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QCOMPARE(nameSpy.count(), 3); + QCOMPARE(statusSpy.count(), 2); + QTRY_COMPARE(fontObject->name(), QString("Daniel")); +} + +void tst_qdeclarativefontloader::changeFontSourceViaState() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-20268.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QDeclarativeFontLoader *fontObject = qobject_cast(qvariant_cast(canvas.rootObject()->property("fontloader"))); + QVERIFY(fontObject != 0); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QVERIFY(fontObject->source() != QUrl("")); + QTRY_COMPARE(fontObject->name(), QString("OCRA")); + + canvas.rootObject()->setProperty("usename", true); + + // This warning should probably not be printed once QTBUG-20268 is fixed + QString warning = QString(QUrl::fromLocalFile(TESTDATA("qtbug-20268.qml")).toString()) + + QLatin1String(":13:5: QML FontLoader: Cannot load font: \"\""); + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + + QEXPECT_FAIL("", "QTBUG-20268", Abort); + QTRY_VERIFY(fontObject->status() == QDeclarativeFontLoader::Ready); + QCOMPARE(canvas.rootObject()->property("name").toString(), QString("Tahoma")); +} + +QTEST_MAIN(tst_qdeclarativefontloader) + +#include "tst_qdeclarativefontloader.moc" diff --git a/tests/auto/qtquick2/qdeclarativepath/data/arc.qml b/tests/auto/qtquick2/qdeclarativepath/data/arc.qml new file mode 100644 index 0000000000..000221c784 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepath/data/arc.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Path { + startX: 0; startY: 0 + + PathArc { + x: 100; y: 100 + radiusX: 100; radiusY: 100 + direction: PathArc.Clockwise + } +} diff --git a/tests/auto/qtquick2/qdeclarativepath/data/curve.qml b/tests/auto/qtquick2/qdeclarativepath/data/curve.qml new file mode 100644 index 0000000000..c571186496 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepath/data/curve.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Path { + startX: 0; startY: 0 + + PathCurve { x: 100; y: 50 } + PathCurve { x: 50; y: 100 } + PathCurve { x: 100; y: 150 } +} diff --git a/tests/auto/qtquick2/qdeclarativepath/data/svg.qml b/tests/auto/qtquick2/qdeclarativepath/data/svg.qml new file mode 100644 index 0000000000..cec0f75061 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepath/data/svg.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Path { + PathSvg { path: "M200,300 Q400,50 600,300 T1000,300" } +} diff --git a/tests/auto/qtquick2/qdeclarativepath/qdeclarativepath.pro b/tests/auto/qtquick2/qdeclarativepath/qdeclarativepath.pro new file mode 100644 index 0000000000..9f4204efa3 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepath/qdeclarativepath.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qdeclarativepath +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativepath.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qdeclarativepath/tst_qdeclarativepath.cpp b/tests/auto/qtquick2/qdeclarativepath/tst_qdeclarativepath.cpp new file mode 100644 index 0000000000..bf4f70b292 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepath/tst_qdeclarativepath.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "../../shared/util.h" + +class tst_QDeclarativePath : public QObject +{ + Q_OBJECT +public: + tst_QDeclarativePath() {} + +private slots: + void arc(); + void catmullromCurve(); + void svg(); +}; + +void tst_QDeclarativePath::arc() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("arc.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->startX(), 0.); + QCOMPARE(obj->startY(), 0.); + + QDeclarativeListReference list(obj, "pathElements"); + QCOMPARE(list.count(), 1); + + QDeclarativePathArc* arc = qobject_cast(list.at(0)); + QVERIFY(arc != 0); + QCOMPARE(arc->x(), 100.); + QCOMPARE(arc->y(), 100.); + QCOMPARE(arc->radiusX(), 100.); + QCOMPARE(arc->radiusY(), 100.); + QCOMPARE(arc->useLargeArc(), false); + QCOMPARE(arc->direction(), QDeclarativePathArc::Clockwise); + + QPainterPath path = obj->path(); + QVERIFY(path != QPainterPath()); + + QPointF pos = obj->pointAt(0); + QCOMPARE(pos, QPointF(0,0)); + pos = obj->pointAt(.25); + QCOMPARE(pos.toPoint(), QPoint(39,8)); //fuzzy compare + pos = obj->pointAt(.75); + QCOMPARE(pos.toPoint(), QPoint(92,61)); //fuzzy compare + pos = obj->pointAt(1); + QCOMPARE(pos, QPointF(100,100)); +} + +void tst_QDeclarativePath::catmullromCurve() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("curve.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->startX(), 0.); + QCOMPARE(obj->startY(), 0.); + + QDeclarativeListReference list(obj, "pathElements"); + QCOMPARE(list.count(), 3); + + QDeclarativePathCatmullRomCurve* arc = qobject_cast(list.at(0)); +// QVERIFY(arc != 0); +// QCOMPARE(arc->x(), 100.); +// QCOMPARE(arc->y(), 100.); +// QCOMPARE(arc->radiusX(), 100.); +// QCOMPARE(arc->radiusY(), 100.); +// QCOMPARE(arc->useLargeArc(), false); +// QCOMPARE(arc->direction(), QDeclarativePathArc::Clockwise); + + QPainterPath path = obj->path(); + QVERIFY(path != QPainterPath()); + + QPointF pos = obj->pointAt(0); + QCOMPARE(pos, QPointF(0,0)); + pos = obj->pointAt(.25); + QCOMPARE(pos.toPoint(), QPoint(63,26)); //fuzzy compare + pos = obj->pointAt(.75); + QCOMPARE(pos.toPoint(), QPoint(51,105)); //fuzzy compare + pos = obj->pointAt(1); + QCOMPARE(pos, QPointF(100,150)); +} + +void tst_QDeclarativePath::svg() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("svg.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->startX(), 0.); + QCOMPARE(obj->startY(), 0.); + + QDeclarativeListReference list(obj, "pathElements"); + QCOMPARE(list.count(), 1); + + QDeclarativePathSvg* svg = qobject_cast(list.at(0)); + QVERIFY(svg != 0); + QCOMPARE(svg->path(), QLatin1String("M200,300 Q400,50 600,300 T1000,300")); + + QPainterPath path = obj->path(); + QVERIFY(path != QPainterPath()); + + QPointF pos = obj->pointAt(0); + QCOMPARE(pos, QPointF(200,300)); + pos = obj->pointAt(.25); + QCOMPARE(pos.toPoint(), QPoint(400,175)); //fuzzy compare + pos = obj->pointAt(.75); + QCOMPARE(pos.toPoint(), QPoint(800,425)); //fuzzy compare + pos = obj->pointAt(1); + QCOMPARE(pos, QPointF(1000,300)); +} + + +QTEST_MAIN(tst_QDeclarativePath) + +#include "tst_qdeclarativepath.moc" diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists1.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists1.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists1.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists2.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists2.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/exists2.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists1.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists1.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists1.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists2.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists2.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists2.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists3.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists3.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists3.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists4.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists4.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists4.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists5.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists5.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists5.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists6.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists6.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists6.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists7.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists7.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists7.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists8.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists8.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/http/exists8.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/data/massive.png b/tests/auto/qtquick2/qdeclarativepixmapcache/data/massive.png new file mode 100644 index 0000000000..bc6cc9e6ca Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativepixmapcache/data/massive.png differ diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/qdeclarativepixmapcache.pro b/tests/auto/qtquick2/qdeclarativepixmapcache/qdeclarativepixmapcache.pro new file mode 100644 index 0000000000..391c28c10a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepixmapcache/qdeclarativepixmapcache.pro @@ -0,0 +1,20 @@ +CONFIG += testcase +TARGET = tst_qdeclarativepixmapcache +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativepixmapcache.cpp + +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h +SOURCES += ../../shared/testhttpserver.cpp + +importFiles.files = data +importFiles.path = . +DEPLOYMENT += importFiles + +# QMAKE_CXXFLAGS = -fprofile-arcs -ftest-coverage +# LIBS += -lgcov + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp b/tests/auto/qtquick2/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp new file mode 100644 index 0000000000..2e326263c0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativepixmapcache/tst_qdeclarativepixmapcache.cpp @@ -0,0 +1,458 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include "testhttpserver.h" + +#ifndef QT_NO_CONCURRENT +#include +#include +#endif + +inline QUrl TEST_FILE(const QString &filename) +{ + return QUrl::fromLocalFile(TESTDATA(filename)); +} + +class tst_qdeclarativepixmapcache : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativepixmapcache() : + server(14452) + { + server.serveDirectory(TESTDATA("http")); + } + +private slots: + void single(); + void single_data(); + void parallel(); + void parallel_data(); + void massive(); + void cancelcrash(); + void shrinkcache(); +#ifndef QT_NO_CONCURRENT + void networkCrash(); +#endif + void lockingCrash(); + void dataLeak(); +private: + QDeclarativeEngine engine; + TestHTTPServer server; +}; + +static int slotters=0; + +class Slotter : public QObject +{ + Q_OBJECT +public: + Slotter() + { + gotslot = false; + slotters++; + } + bool gotslot; + +public slots: + void got() + { + gotslot = true; + --slotters; + if (slotters==0) + QTestEventLoop::instance().exitLoop(); + } +}; + +#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML +static const bool localfile_optimized = true; +#else +static const bool localfile_optimized = false; +#endif + +void tst_qdeclarativepixmapcache::single_data() +{ + // Note, since QDeclarativePixmapCache is shared, tests affect each other! + // so use different files fore all test functions. + + QTest::addColumn("target"); + QTest::addColumn("incache"); + QTest::addColumn("exists"); + QTest::addColumn("neterror"); + + // File URLs are optimized + QTest::newRow("local") << TEST_FILE("exists.png") << localfile_optimized << true << false; + QTest::newRow("local") << TEST_FILE("notexists.png") << localfile_optimized << false << false; + QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/exists.png") << false << true << false; + QTest::newRow("remote") << QUrl("http://127.0.0.1:14452/notexists.png") << false << false << true; +} + +void tst_qdeclarativepixmapcache::single() +{ + QFETCH(QUrl, target); + QFETCH(bool, incache); + QFETCH(bool, exists); + QFETCH(bool, neterror); + + QString expectedError; + if (neterror) { + expectedError = "Error downloading " + target.toString() + " - server replied: Not found"; + } else if (!exists) { + expectedError = "Cannot open: " + target.toString(); + } + + QDeclarativePixmap pixmap; + QVERIFY(pixmap.width() <= 0); // Check Qt assumption + + pixmap.load(&engine, target); + + if (incache) { + QCOMPARE(pixmap.error(), expectedError); + if (exists) { + QVERIFY(pixmap.status() == QDeclarativePixmap::Ready); + QVERIFY(pixmap.width() > 0); + } else { + QVERIFY(pixmap.status() == QDeclarativePixmap::Error); + QVERIFY(pixmap.width() <= 0); + } + } else { + QVERIFY(pixmap.width() <= 0); + + Slotter getter; + pixmap.connectFinished(&getter, SLOT(got())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(getter.gotslot); + if (exists) { + QVERIFY(pixmap.status() == QDeclarativePixmap::Ready); + QVERIFY(pixmap.width() > 0); + } else { + QVERIFY(pixmap.status() == QDeclarativePixmap::Error); + QVERIFY(pixmap.width() <= 0); + } + QCOMPARE(pixmap.error(), expectedError); + } +} + +void tst_qdeclarativepixmapcache::parallel_data() +{ + // Note, since QDeclarativePixmapCache is shared, tests affect each other! + // so use different files fore all test functions. + + QTest::addColumn("target1"); + QTest::addColumn("target2"); + QTest::addColumn("incache"); + QTest::addColumn("cancel"); // which one to cancel + + QTest::newRow("local") + << TEST_FILE("exists1.png") + << TEST_FILE("exists2.png") + << (localfile_optimized ? 2 : 0) + << -1; + + QTest::newRow("remote") + << QUrl("http://127.0.0.1:14452/exists2.png") + << QUrl("http://127.0.0.1:14452/exists3.png") + << 0 + << -1; + + QTest::newRow("remoteagain") + << QUrl("http://127.0.0.1:14452/exists2.png") + << QUrl("http://127.0.0.1:14452/exists3.png") + << 2 + << -1; + + QTest::newRow("remotecopy") + << QUrl("http://127.0.0.1:14452/exists4.png") + << QUrl("http://127.0.0.1:14452/exists4.png") + << 0 + << -1; + + QTest::newRow("remotecopycancel") + << QUrl("http://127.0.0.1:14452/exists5.png") + << QUrl("http://127.0.0.1:14452/exists5.png") + << 0 + << 0; +} + +void tst_qdeclarativepixmapcache::parallel() +{ + QFETCH(QUrl, target1); + QFETCH(QUrl, target2); + QFETCH(int, incache); + QFETCH(int, cancel); + + QList targets; + targets << target1 << target2; + + QList pixmaps; + QList pending; + QList getters; + + for (int i=0; iload(&engine, target); + + QVERIFY(pixmap->status() != QDeclarativePixmap::Error); + pixmaps.append(pixmap); + if (pixmap->isReady()) { + QVERIFY(pixmap->width() > 0); + getters.append(0); + pending.append(false); + } else { + QVERIFY(pixmap->width() <= 0); + getters.append(new Slotter); + pixmap->connectFinished(getters[i], SLOT(got())); + pending.append(true); + } + } + + QCOMPARE(incache+slotters, targets.count()); + + if (cancel >= 0) { + pixmaps.at(cancel)->clear(getters[cancel]); + slotters--; + } + + if (slotters) { + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + } + + for (int i=0; igotslot); + } else { + if (pending[i]) + QVERIFY(getters[i]->gotslot); + + QVERIFY(pixmap->isReady()); + QVERIFY(pixmap->width() > 0); + delete getters[i]; + } + } + + qDeleteAll(pixmaps); +} + +void tst_qdeclarativepixmapcache::massive() +{ + QDeclarativeEngine engine; + QUrl url = TEST_FILE("massive.png"); + + // Confirm that massive images remain in the cache while they are + // in use by the application. + { + qint64 cachekey = 0; + QDeclarativePixmap p(&engine, url); + QVERIFY(p.isReady()); + QVERIFY(p.image().size() == QSize(10000, 1000)); + cachekey = p.image().cacheKey(); + + QDeclarativePixmap p2(&engine, url); + QVERIFY(p2.isReady()); + QVERIFY(p2.image().size() == QSize(10000, 1000)); + + QVERIFY(p2.image().cacheKey() == cachekey); + } + + // Confirm that massive images are removed from the cache when + // they become unused + { + qint64 cachekey = 0; + { + QDeclarativePixmap p(&engine, url); + QVERIFY(p.isReady()); + QVERIFY(p.image().size() == QSize(10000, 1000)); + cachekey = p.image().cacheKey(); + } + + QDeclarativePixmap p2(&engine, url); + QVERIFY(p2.isReady()); + QVERIFY(p2.image().size() == QSize(10000, 1000)); + + QVERIFY(p2.image().cacheKey() != cachekey); + } +} + +// QTBUG-12729 +void tst_qdeclarativepixmapcache::cancelcrash() +{ + QUrl url("http://127.0.0.1:14452/cancelcrash_notexist.png"); + for (int ii = 0; ii < 1000; ++ii) { + QDeclarativePixmap pix(&engine, url); + } +} + +class MyPixmapProvider : public QDeclarativeImageProvider +{ +public: + MyPixmapProvider() + : QDeclarativeImageProvider(Pixmap) {} + + virtual QPixmap requestPixmap(const QString &d, QSize *, const QSize &) { + Q_UNUSED(d) + QPixmap pix(800, 600); + pix.fill(Qt::red); + return pix; + } +}; + +// QTBUG-13345 +void tst_qdeclarativepixmapcache::shrinkcache() +{ + QDeclarativeEngine engine; + engine.addImageProvider(QLatin1String("mypixmaps"), new MyPixmapProvider); + + for (int ii = 0; ii < 4000; ++ii) { + QUrl url("image://mypixmaps/" + QString::number(ii)); + QDeclarativePixmap p(&engine, url); + } +} + +#ifndef QT_NO_CONCURRENT + +void createNetworkServer() +{ + QEventLoop eventLoop; + TestHTTPServer server(14453); + server.serveDirectory(TESTDATA("http")); + QTimer::singleShot(100, &eventLoop, SLOT(quit())); + eventLoop.exec(); +} + +#ifndef QT_NO_CONCURRENT +// QT-3957 +void tst_qdeclarativepixmapcache::networkCrash() +{ + QFuture future = QtConcurrent::run(createNetworkServer); + QDeclarativeEngine engine; + for (int ii = 0; ii < 100 ; ++ii) { + QDeclarativePixmap* pixmap = new QDeclarativePixmap; + pixmap->load(&engine, QUrl(QString("http://127.0.0.1:14453/exists.png"))); + QTest::qSleep(1); + pixmap->clear(); + delete pixmap; + } + future.cancel(); +} +#endif + +#endif + +// QTBUG-22125 +void tst_qdeclarativepixmapcache::lockingCrash() +{ + TestHTTPServer server(14453); + server.serveDirectory(TESTDATA("http"), TestHTTPServer::Delay); + + { + QDeclarativePixmap* p = new QDeclarativePixmap; + { + QDeclarativeEngine e; + p->load(&e, QUrl(QString("http://127.0.0.1:14453/exists6.png"))); + } + p->clear(); + QVERIFY(p->isNull()); + delete p; + } +} + +#include +class DataLeakView : public QQuickView +{ + Q_OBJECT + +public: + explicit DataLeakView() : QQuickView() + { + setSource(TEST_FILE("dataLeak.qml")); + } + + void showFor2Seconds() + { + showFullScreen(); + QTimer::singleShot(2000, this, SIGNAL(ready())); + } + +signals: + void ready(); +}; + +// QTBUG-22742 +Q_GLOBAL_STATIC(QDeclarativePixmap, dataLeakPixmap) +void tst_qdeclarativepixmapcache::dataLeak() +{ + // Should not leak cached QDeclarativePixmapData. + // Unfortunately, since the QDeclarativePixmapStore + // is a global static, and it releases the cache + // entries on dtor (application exit), we must use + // valgrind to determine whether it leaks or not. + QDeclarativePixmap *p1 = new QDeclarativePixmap; + QDeclarativePixmap *p2 = new QDeclarativePixmap; + { + QScopedPointer test(new DataLeakView); + test->showFor2Seconds(); + dataLeakPixmap()->load(test->engine(), TEST_FILE("exists.png")); + p1->load(test->engine(), TEST_FILE("exists.png")); + p2->load(test->engine(), TEST_FILE("exists2.png")); + QTest::qWait(2005); // 2 seconds + a few more millis. + } + + // When the (global static) dataLeakPixmap is deleted, it + // shouldn't attempt to dereference a QDeclarativePixmapData + // which has been deleted by the QDeclarativePixmapStore + // destructor. +} + +QTEST_MAIN(tst_qdeclarativepixmapcache) + +#include "tst_qdeclarativepixmapcache.moc" diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation1.qml b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation1.qml new file mode 100644 index 0000000000..3631f971f0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation1.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 + +SmoothedAnimation {} diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation2.qml b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation2.qml new file mode 100644 index 0000000000..b07120234a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation2.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +SmoothedAnimation { + to: 10; duration: 300; reversingMode: SmoothedAnimation.Immediate +} diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation3.qml b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation3.qml new file mode 100644 index 0000000000..8d5dc4a92b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimation3.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +SmoothedAnimation { + to: 10; velocity: 250; reversingMode: SmoothedAnimation.Sync + maximumEasingTime: 150 +} diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml new file mode 100644 index 0000000000..81d36bf015 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationBehavior.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400; color: "blue" + + Rectangle { + id: rect1 + color: "red" + width: 60; height: 60; + x: 100; y: 100; + SmoothedAnimation on x { to: 200; velocity: 500 } + SmoothedAnimation on y { to: 200; velocity: 500 } + } + + Rectangle { + objectName: "theRect" + color: "green" + width: 60; height: 60; + x: rect1.x; y: rect1.y; + // id are needed for SmoothedAnimation in order to avoid deferred creation + Behavior on x { SmoothedAnimation { id: anim1; objectName: "easeX"; velocity: 400 } } + Behavior on y { SmoothedAnimation { id: anim2; objectName: "easeY"; velocity: 400 } } + } + } diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml new file mode 100644 index 0000000000..e136df84f6 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/data/smoothedanimationValueSource.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Rectangle { + width: 300; height: 300; + Rectangle { + objectName: "theRect" + color: "red" + width: 60; height: 60; + x: 100; y: 100; + SmoothedAnimation on x { objectName: "easeX"; to: 200; velocity: 500 } + SmoothedAnimation on y { objectName: "easeY"; to: 200; duration: 250; velocity: 500 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro b/tests/auto/qtquick2/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro new file mode 100644 index 0000000000..1e8a7d5ba6 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/qdeclarativesmoothedanimation.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qdeclarativesmoothedanimation +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativesmoothedanimation.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp b/tests/auto/qtquick2/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp new file mode 100644 index 0000000000..632bcda091 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesmoothedanimation/tst_qdeclarativesmoothedanimation.cpp @@ -0,0 +1,211 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qdeclarativesmoothedanimation : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativesmoothedanimation(); + +private slots: + void defaultValues(); + void values(); + void disabled(); + void simpleAnimation(); + void valueSource(); + void behavior(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativesmoothedanimation::tst_qdeclarativesmoothedanimation() +{ +} + +void tst_qdeclarativesmoothedanimation::defaultValues() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation1.qml"))); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 0.); + QCOMPARE(obj->velocity(), 200.); + QCOMPARE(obj->duration(), -1); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Eased); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::values() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation2.qml"))); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 10.); + QCOMPARE(obj->velocity(), 200.); + QCOMPARE(obj->duration(), 300); + QCOMPARE(obj->maximumEasingTime(), -1); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Immediate); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::disabled() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimation3.qml"))); + QDeclarativeSmoothedAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 10.); + QCOMPARE(obj->velocity(), 250.); + QCOMPARE(obj->maximumEasingTime(), 150); + QCOMPARE(obj->reversingMode(), QDeclarativeSmoothedAnimation::Sync); + + delete obj; +} + +void tst_qdeclarativesmoothedanimation::simpleAnimation() +{ + QQuickRectangle rect; + QDeclarativeSmoothedAnimation animation; + animation.setTarget(&rect); + animation.setProperty("x"); + animation.setTo(200); + animation.setDuration(250); + QVERIFY(animation.target() == &rect); + QVERIFY(animation.property() == "x"); + QVERIFY(animation.to() == 200); + animation.start(); + QVERIFY(animation.isRunning()); + QTest::qWait(animation.duration()); + QTRY_COMPARE(rect.x(), qreal(200)); + + rect.setX(0); + animation.start(); + animation.pause(); + QVERIFY(animation.isRunning()); + QVERIFY(animation.isPaused()); + animation.setCurrentTime(125); + QVERIFY(animation.currentTime() == 125); + QCOMPARE(rect.x(), qreal(100)); +} + +void tst_qdeclarativesmoothedanimation::valueSource() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationValueSource.qml"))); + + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + QVERIFY(easeX->isRunning()); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("easeY"); + QVERIFY(easeY); + QVERIFY(easeY->isRunning()); + + // XXX get the proper duration + QTest::qWait(100); + + QTRY_VERIFY(!easeX->isRunning()); + QTRY_VERIFY(!easeY->isRunning()); + + QTRY_COMPARE(theRect->x(), qreal(200)); + QTRY_COMPARE(theRect->y(), qreal(200)); + + delete rect; +} + +void tst_qdeclarativesmoothedanimation::behavior() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("smoothedanimationBehavior.qml"))); + + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect); + + QQuickRectangle *theRect = rect->findChild("theRect"); + QVERIFY(theRect); + + QDeclarativeSmoothedAnimation *easeX = rect->findChild("easeX"); + QVERIFY(easeX); + + QDeclarativeSmoothedAnimation *easeY = rect->findChild("easeY"); + QVERIFY(easeY); + + // XXX get the proper duration + QTest::qWait(400); + + QTRY_VERIFY(!easeX->isRunning()); + QTRY_VERIFY(!easeY->isRunning()); + + QTRY_COMPARE(theRect->x(), qreal(200)); + QTRY_COMPARE(theRect->y(), qreal(200)); + + delete rect; +} + +QTEST_MAIN(tst_qdeclarativesmoothedanimation) + +#include "tst_qdeclarativesmoothedanimation.moc" diff --git a/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation1.qml b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation1.qml new file mode 100644 index 0000000000..9f52aa56c1 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation1.qml @@ -0,0 +1,4 @@ +import QtQuick 2.0 + +SpringAnimation { +} diff --git a/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation2.qml b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation2.qml new file mode 100644 index 0000000000..172cc57ca8 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation2.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +SpringAnimation { + to: 1.44; velocity: 0.9 + spring: 1.0; damping: 0.5 + epsilon: 0.25; modulus: 360.0 + mass: 2.0; + running: true; +} diff --git a/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation3.qml b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation3.qml new file mode 100644 index 0000000000..f4dc121eb8 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativespringanimation/data/springanimation3.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +SpringAnimation { + to: 1.44; velocity: 0.9 + spring: 1.0; damping: 0.5 + epsilon: 0.25; modulus: 360.0 + mass: 2.0; running: false +} diff --git a/tests/auto/qtquick2/qdeclarativespringanimation/qdeclarativespringanimation.pro b/tests/auto/qtquick2/qdeclarativespringanimation/qdeclarativespringanimation.pro new file mode 100644 index 0000000000..3ac2551380 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativespringanimation/qdeclarativespringanimation.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qdeclarativespringanimation +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativespringanimation.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp b/tests/auto/qtquick2/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp new file mode 100644 index 0000000000..f7acc2a3e0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativespringanimation/tst_qdeclarativespringanimation.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qdeclarativespringanimation : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativespringanimation(); + +private slots: + void defaultValues(); + void values(); + void disabled(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativespringanimation::tst_qdeclarativespringanimation() +{ +} + +void tst_qdeclarativespringanimation::defaultValues() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation1.qml"))); + QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 0.); + QCOMPARE(obj->velocity(), 0.); + QCOMPARE(obj->spring(), 0.); + QCOMPARE(obj->damping(), 0.); + QCOMPARE(obj->epsilon(), 0.01); + QCOMPARE(obj->modulus(), 0.); + QCOMPARE(obj->mass(), 1.); + QCOMPARE(obj->isRunning(), false); + + delete obj; +} + +void tst_qdeclarativespringanimation::values() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation2.qml"))); + QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 1.44); + QCOMPARE(obj->velocity(), 0.9); + QCOMPARE(obj->spring(), 1.0); + QCOMPARE(obj->damping(), 0.5); + QCOMPARE(obj->epsilon(), 0.25); + QCOMPARE(obj->modulus(), 360.0); + QCOMPARE(obj->mass(), 2.0); + QCOMPARE(obj->isRunning(), true); + + QTRY_COMPARE(obj->isRunning(), false); + + delete obj; +} + +void tst_qdeclarativespringanimation::disabled() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("springanimation3.qml"))); + QDeclarativeSpringAnimation *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + + QCOMPARE(obj->to(), 1.44); + QCOMPARE(obj->velocity(), 0.9); + QCOMPARE(obj->spring(), 1.0); + QCOMPARE(obj->damping(), 0.5); + QCOMPARE(obj->epsilon(), 0.25); + QCOMPARE(obj->modulus(), 360.0); + QCOMPARE(obj->mass(), 2.0); + QCOMPARE(obj->isRunning(), false); + + delete obj; +} + +QTEST_MAIN(tst_qdeclarativespringanimation) + +#include "tst_qdeclarativespringanimation.moc" diff --git a/tests/auto/qtquick2/qdeclarativestates/data/ExtendedRectangle.qml b/tests/auto/qtquick2/qdeclarativestates/data/ExtendedRectangle.qml new file mode 100644 index 0000000000..1ea346b841 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/ExtendedRectangle.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 +Rectangle { + id: extendedRect + objectName: "extendedRect" + property color extendedColor: "orange" + + width: 100; height: 100 + color: "red" + states: State { + name: "green" + PropertyChanges { + target: rect + onDidSomething: { + extendedRect.color = "green" + extendedColor = "green" + } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/Implementation/MyType.qml b/tests/auto/qtquick2/qdeclarativestates/data/Implementation/MyType.qml new file mode 100644 index 0000000000..01eb32cd4d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/Implementation/MyType.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Item { + Column { + anchors.centerIn: parent + Image { id: image1; objectName: "image1" } + Image { id: image2; objectName: "image2" } + Image { id: image3; objectName: "image3" } + } + + states: State { + name: "SetImageState" + PropertyChanges { + target: image1 + source: "images/qt-logo.png" + } + PropertyChanges { + target: image2 + source: "images/" + "qt-logo.png" + } + PropertyChanges { + target: image3 + source: "images/" + (true ? "qt-logo.png" : "") + } + } + + MouseArea { + anchors.fill: parent + onClicked: parent.state = "SetImageState" + } + +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/Implementation/images/qt-logo.png b/tests/auto/qtquick2/qdeclarativestates/data/Implementation/images/qt-logo.png new file mode 100644 index 0000000000..14ddf2a028 Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativestates/data/Implementation/images/qt-logo.png differ diff --git a/tests/auto/qtquick2/qdeclarativestates/data/QTBUG-14830.qml b/tests/auto/qtquick2/qdeclarativestates/data/QTBUG-14830.qml new file mode 100644 index 0000000000..5ba7c3ad6f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/QTBUG-14830.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 1024 + height: 768 + + Item { + id: area + objectName: "area" + property int numx: 6 + property int cellwidth: 1024/numx + + onWidthChanged: { + width = width>1024?1024:width; + } + + state: 'minimal' + states: [ + State { + name: 'minimal' + PropertyChanges { + target: area + width: cellwidth + } + } + ] + + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges1.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges1.qml new file mode 100644 index 0000000000..378f5390f9 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges1.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + width: 50; height: 50 + color: "green"; + anchors.left: parent.left + anchors.leftMargin: 5 + } + states: State { + name: "right" + AnchorChanges { + id: ancCh + target: myRect; + anchors.left: undefined + anchors.right: container.right + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges2.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges2.qml new file mode 100644 index 0000000000..dc7f8ef0d1 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges2.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + width: 50; height: 50 + color: "green"; + anchors.left: parent.left + anchors.leftMargin: 5 + } + states: State { + name: "right" + AnchorChanges { + target: myRect; + anchors.left: undefined + anchors.right: parent.right + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges3.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges3.qml new file mode 100644 index 0000000000..af49575854 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges3.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + id: container + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + color: "green"; + anchors.left: parent.left + anchors.right: rightGuideline.left + anchors.top: topGuideline.top + anchors.bottom: container.bottom + } + Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } + Item { id: rightGuideline; x: 150 } + Item { id: topGuideline; y: 10 } + Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } + states: State { + name: "reanchored" + AnchorChanges { + target: myRect; + anchors.left: leftGuideline.left + anchors.right: container.right + anchors.top: container.top + anchors.bottom: bottomGuideline.bottom + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges4.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges4.qml new file mode 100644 index 0000000000..28b55818bd --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges4.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + color: "green"; + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } + Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } + states: State { + name: "reanchored" + AnchorChanges { + target: myRect; + anchors.horizontalCenter: bottomGuideline.horizontalCenter + anchors.verticalCenter: leftGuideline.verticalCenter + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges5.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges5.qml new file mode 100644 index 0000000000..b1ca968fb9 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChanges5.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + id: myRect + objectName: "MyRect" + color: "green"; + anchors.horizontalCenter: parent.horizontalCenter + anchors.baseline: parent.baseline + } + Item { objectName: "LeftGuideline"; id: leftGuideline; x: 10 } + Item { objectName: "BottomGuideline"; id: bottomGuideline; y: 150 } + states: State { + name: "reanchored" + AnchorChanges { + target: myRect; + anchors.horizontalCenter: bottomGuideline.horizontalCenter + anchors.baseline: leftGuideline.baseline + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorChangesCrash.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorChangesCrash.qml new file mode 100644 index 0000000000..9af0e4645a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorChangesCrash.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: container + width: 400 + height: 400 + + states: State { + name: "reanchored" + AnchorChanges { + anchors.top: container.top + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug.qml new file mode 100644 index 0000000000..60c537b1ed --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 +Rectangle { + id: container + color: "red" + height: 200 + width: 200 + Column { + id: column + objectName: "column" + anchors.left: container.right + anchors.bottom: container.bottom + + Rectangle { + id: rectangle + color: "blue" + height: 100 + width: 200 + } + Rectangle { + color: "blue" + height: 100 + width: 200 + } + } + states: State { + name: "reanchored" + AnchorChanges { + target: column + anchors.left: undefined + anchors.right: container.right + } + PropertyChanges { + target: rectangle + visible: false + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug2.qml b/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug2.qml new file mode 100644 index 0000000000..574ef473ce --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/anchorRewindBug2.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width:200; height:300 + + Rectangle { + id: rectangle + objectName: "mover" + color: "green" + width:50; height:50 + } + + states: [ + State { + name: "anchored" + AnchorChanges { + target: rectangle + anchors.left: root.left + anchors.right: root.right + anchors.bottom: root.bottom + } + } + ] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/attachedPropertyChanges.qml b/tests/auto/qtquick2/qdeclarativestates/data/attachedPropertyChanges.qml new file mode 100644 index 0000000000..413af2ee42 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/attachedPropertyChanges.qml @@ -0,0 +1,20 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +Item { + id: item + width: 100; height: 100 + MyRectangle.foo: 0 + + states: State { + name: "foo1" + PropertyChanges { + target: item + MyRectangle.foo: 1 + width: 50 + } + } + + Component.onCompleted: item.state = "foo1" +} + diff --git a/tests/auto/qtquick2/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml b/tests/auto/qtquick2/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml new file mode 100644 index 0000000000..6cbf524ec2 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/autoStateAtStartupRestoreBug.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + id: root + property int input: 1 + property int test: 9 + + states: [ + State { + name: "portrait" + when: root.input == 1 + PropertyChanges { + target: root + test: 3 + } + } + ] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/avoidFastForward.qml b/tests/auto/qtquick2/qdeclarativestates/data/avoidFastForward.qml new file mode 100644 index 0000000000..519befc31e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/avoidFastForward.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 200 + height: 200 + + property int updateCount: 0 + onColorChanged: updateCount++ + + property color aColor: "green" + + states: State { + name: "a" + PropertyChanges { target: rect; color: aColor } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicBinding.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding.qml new file mode 100644 index 0000000000..59b67d0863 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + property color sourceColor: "blue" + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: sourceColor } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicBinding2.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding2.qml new file mode 100644 index 0000000000..55f88120aa --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding2.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + property color sourceColor: "red" + width: 100; height: 100 + color: sourceColor + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicBinding3.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding3.qml new file mode 100644 index 0000000000..361ab0b091 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding3.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + property color sourceColor: "red" + property color sourceColor2: "blue" + width: 100; height: 100 + color: sourceColor + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: sourceColor2 } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicBinding4.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding4.qml new file mode 100644 index 0000000000..b29f0fcf22 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicBinding4.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + property color sourceColor: "blue" + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: myRectangle; color: sourceColor } + }, + State { + name: "green" + PropertyChanges { target: myRectangle; color: "green" } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicChanges.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges.qml new file mode 100644 index 0000000000..3e2b73acde --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicChanges2.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges2.qml new file mode 100644 index 0000000000..5ff46cc60c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges2.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + }, + State { + name: "green" + PropertyChanges { target: myRectangle; color: "green" } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicChanges3.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges3.qml new file mode 100644 index 0000000000..e46e98f75e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges3.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + }, + State { + name: "bordered" + PropertyChanges { target: myRectangle; border.width: 2 } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicChanges4.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges4.qml new file mode 100644 index 0000000000..7da1e0fb2e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicChanges4.qml @@ -0,0 +1,19 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyRectangle { + id: rect + width: 100; height: 100 + color: "red" + + states: State { + name: "aBlueDay" + PropertyChanges { + target: rect + onPropertyWithNotifyChanged: { rect.color = "blue"; } + } + } + + Component.onCompleted: rect.state = "aBlueDay" +} + diff --git a/tests/auto/qtquick2/qdeclarativestates/data/basicExtension.qml b/tests/auto/qtquick2/qdeclarativestates/data/basicExtension.qml new file mode 100644 index 0000000000..00f5fee287 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/basicExtension.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + }, + State { + name: "bordered" + extend: "blue" + PropertyChanges { target: myRectangle; border.width: 2 } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/deleting.qml b/tests/auto/qtquick2/qdeclarativestates/data/deleting.qml new file mode 100644 index 0000000000..b8e8d33c17 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/deleting.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue"; objectName: "pc1" } + PropertyChanges { target: myRectangle; radius: 5; objectName: "pc2" } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/deletingState.qml b/tests/auto/qtquick2/qdeclarativestates/data/deletingState.qml new file mode 100644 index 0000000000..68a9c2a24d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/deletingState.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + StateGroup { + id: stateGroup + states: State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/editProperties.qml b/tests/auto/qtquick2/qdeclarativestates/data/editProperties.qml new file mode 100644 index 0000000000..9bff3657ba --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/editProperties.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + property color sourceColor: "blue" + width: 400; height: 400 + color: "red" + + Rectangle { + id: rect2 + objectName: "rect2" + width: parent.width + 2 + height: 200 + color: "yellow" + } + + states: [ + State { + name: "blue" + PropertyChanges { + target: rect2 + width:50 + height: 40 + } + }, + State { + name: "green" + PropertyChanges { + target: rect2 + width: myRectangle.width / 2 + height: myRectangle.width / 4 + } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/explicit.qml b/tests/auto/qtquick2/qdeclarativestates/data/explicit.qml new file mode 100644 index 0000000000..d09893a1db --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/explicit.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + property color sourceColor: "blue" + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { + objectName: "changes" + target: myRectangle; explicit: true + color: sourceColor + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/extendsBug.qml b/tests/auto/qtquick2/qdeclarativestates/data/extendsBug.qml new file mode 100644 index 0000000000..573341520d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/extendsBug.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + + Rectangle { + id: rect + objectName: "greenRect" + width: 100 + height: 100 + color: "green" + } + + states:[ + State { + name: "a" + PropertyChanges { target: rect; x: 100 } + }, + State { + name: "b" + extend:"a" + PropertyChanges { target: rect; y: 100 } + } + ] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/fakeExtension.qml b/tests/auto/qtquick2/qdeclarativestates/data/fakeExtension.qml new file mode 100644 index 0000000000..6a5c7003f6 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/fakeExtension.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: [ + State { + name: "blue" + PropertyChanges { target: myRectangle; color: "blue" } + }, + State { + name: "green" + extend: "blue" + PropertyChanges { target: myRectangle; color: "green" } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/illegalObj.qml b/tests/auto/qtquick2/qdeclarativestates/data/illegalObj.qml new file mode 100644 index 0000000000..a2bbd5d32b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/illegalObj.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + id: myItem + + states : State { + PropertyChanges { + target: myItem + children: Item { id: newItem } + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/illegalTempState.qml b/tests/auto/qtquick2/qdeclarativestates/data/illegalTempState.qml new file mode 100644 index 0000000000..9cb39c0728 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/illegalTempState.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: card + width: 100; height: 100 + + states: [ + State { + name: "placed" + PropertyChanges { target: card; state: "idle" } + }, + State { + name: "idle" + } + ] + + MouseArea { + anchors.fill: parent + onClicked: card.state = "placed" + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/image.png b/tests/auto/qtquick2/qdeclarativestates/data/image.png new file mode 100644 index 0000000000..ed1833c95b Binary files /dev/null and b/tests/auto/qtquick2/qdeclarativestates/data/image.png differ diff --git a/tests/auto/qtquick2/qdeclarativestates/data/legalTempState.qml b/tests/auto/qtquick2/qdeclarativestates/data/legalTempState.qml new file mode 100644 index 0000000000..a93860f5cc --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/legalTempState.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + id: card + width: 100; height: 100 + + states: [ + State { + name: "placed" + onCompleted: card.state = "idle" + StateChangeScript { script: console.log("entering placed") } + }, + State { + name: "idle" + StateChangeScript { script: console.log("entering idle") } + } + ] + + MouseArea { + anchors.fill: parent + onClicked: card.state = "placed" + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/nonExistantProp.qml b/tests/auto/qtquick2/qdeclarativestates/data/nonExistantProp.qml new file mode 100644 index 0000000000..ce502699bb --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/nonExistantProp.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: myRectangle; colr: "blue" } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange1.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange1.qml new file mode 100644 index 0000000000..663ad1a264 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange1.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + Item { + x: 10; y: 10 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5 + width: 100; height: 100 + color: "red" + } + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + x: -100; y: -50 + Item { + id: newParent + objectName: "NewParent" + x: 248; y: 360 + } + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange2.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange2.qml new file mode 100644 index 0000000000..ae290e961e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange2.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +Rectangle { + id: newParent + width: 400; height: 400 + Item { + scale: .5 + rotation: 15 + x: 10; y: 10 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5 + width: 100; height: 100 + color: "red" + } + } + MouseArea { + id: clickable + anchors.fill: parent + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange3.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange3.qml new file mode 100644 index 0000000000..46665cb4c8 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange3.qml @@ -0,0 +1,42 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + Item { + scale: .5 + rotation: 15 + transformOrigin: "Center" + x: 10; y: 10 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5 + width: 100; height: 100 + transformOrigin: "BottomLeft" + color: "red" + } + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + x: 200; y: 200 + rotation: 52; + scale: 2 + Item { + id: newParent + x: 100; y: 100 + } + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange4.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange4.qml new file mode 100644 index 0000000000..22de72f8c9 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange4.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5; y: 5 + width: 100; height: 100 + color: "red" + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + id: newParent + transform: Scale { xScale: .5; yScale: .7} + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange5.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange5.qml new file mode 100644 index 0000000000..c353d2637f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange5.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5; y: 5 + width: 100; height: 100 + color: "red" + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + id: newParent + transform: Rotation { angle: 30; axis { x: 0; y: 1; z: 0 } } + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/parentChange6.qml b/tests/auto/qtquick2/qdeclarativestates/data/parentChange6.qml new file mode 100644 index 0000000000..b373dbba20 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/parentChange6.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + Rectangle { + id: myRect + objectName: "MyRect" + x: 5; y: 5 + width: 100; height: 100 + color: "red" + } + MouseArea { + id: clickable + anchors.fill: parent + } + + Item { + id: newParent + rotation: 180 + } + + states: State { + name: "reparented" + when: clickable.pressed + ParentChange { + target: myRect + parent: newParent + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/propertyErrors.qml b/tests/auto/qtquick2/qdeclarativestates/data/propertyErrors.qml new file mode 100644 index 0000000000..ddd636493d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/propertyErrors.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { target: myRectangle; colr: "blue"; activeFocus: true } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/reset.qml b/tests/auto/qtquick2/qdeclarativestates/data/reset.qml new file mode 100644 index 0000000000..f0ecab0950 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/reset.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + width: 640 + height: 480 + Image { + id: image + width: 40 + source: "image.png" + } + + states: State { + name: "state1" + PropertyChanges { + target: image + width: undefined + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/restoreEntryValues.qml b/tests/auto/qtquick2/qdeclarativestates/data/restoreEntryValues.qml new file mode 100644 index 0000000000..950a522841 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/restoreEntryValues.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + PropertyChanges { + target: myRectangle + restoreEntryValues: false + color: "blue" + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/returnToBase.qml b/tests/auto/qtquick2/qdeclarativestates/data/returnToBase.qml new file mode 100644 index 0000000000..9a0ee82397 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/returnToBase.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Rectangle { + id: theRect + property bool triggerState: false + property string stateString: "" + states: [ State { + when: triggerState + PropertyChanges { + target: theRect + stateString: "inState" + } + }, + State { + name: "" + PropertyChanges { + target: theRect + stateString: "originalState" + } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/revertListBug.qml b/tests/auto/qtquick2/qdeclarativestates/data/revertListBug.qml new file mode 100644 index 0000000000..fbc4bc5ecc --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/revertListBug.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + property Item targetItem: rect1 + + function switchTargetItem() { + if (targetItem === rect1) + targetItem = rect2; + else + targetItem = rect1; + } + + states: State { + name: "reparented" + ParentChange { + target: targetItem + parent: newParent + x: 0; y: 0 + } + } + + Item { + objectName: "originalParent1" + Rectangle { + id: rect1; objectName: "rect1" + width: 50; height: 50 + color: "green" + } + } + + Item { + objectName: "originalParent2" + Rectangle { + id: rect2; objectName: "rect2" + x: 50; y: 50 + width: 50; height: 50 + color: "green" + } + } + + Item { + id: newParent; objectName: "newParent" + x: 200; y: 100 + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/script.qml b/tests/auto/qtquick2/qdeclarativestates/data/script.qml new file mode 100644 index 0000000000..218f0fae74 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/script.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 +Rectangle { + id: myRectangle + width: 100; height: 100 + color: "red" + states: State { + name: "blue" + StateChangeScript { script: myRectangle.color = "blue"; } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/signalOverride.qml b/tests/auto/qtquick2/qdeclarativestates/data/signalOverride.qml new file mode 100644 index 0000000000..9ab8037e51 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/signalOverride.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MyRectangle { + id: rect + + onDidSomething: color = "blue" + + width: 100; height: 100 + color: "red" + states: State { + name: "green" + PropertyChanges { + target: rect + onDidSomething: color = "green" + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/signalOverride2.qml b/tests/auto/qtquick2/qdeclarativestates/data/signalOverride2.qml new file mode 100644 index 0000000000..4e5e335b8b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/signalOverride2.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MyRectangle { + id: rect + onDidSomething: color = "blue" + width: 100; height: 100 + ExtendedRectangle {} +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash.qml b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash.qml new file mode 100644 index 0000000000..3e2ae1e93d --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 +import Qt.test 1.0 + +MyRectangle { + id: rect + + width: 100; height: 100 + states: State { + name: "overridden" + PropertyChanges { + target: rect + onDidSomething: rect.state = "" + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash2.qml b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash2.qml new file mode 100644 index 0000000000..3937874aa2 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash2.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: myRect + width: 400 + height: 400 + + states: [ + State { + name: "state1" + PropertyChanges { + target: myRect + onHeightChanged: console.log("Hello World") + color: "green" + } + }, + State { + name: "state2"; extend: "state1" + PropertyChanges { + target: myRect + color: "red" + } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash3.qml b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash3.qml new file mode 100644 index 0000000000..98d4c57219 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/signalOverrideCrash3.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + id: myRect + width: 400 + height: 400 + + onHeightChanged: console.log("base state") + + states: [ + State { + name: "state1" + PropertyChanges { + target: myRect + onHeightChanged: console.log("state1") + color: "green" + } + }, + State { + name: "state2"; + PropertyChanges { + target: myRect + onHeightChanged: console.log("state2") + color: "red" + } + }] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/unnamedWhen.qml b/tests/auto/qtquick2/qdeclarativestates/data/unnamedWhen.qml new file mode 100644 index 0000000000..35eacff07b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/unnamedWhen.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + id: theRect + property bool triggerState: false + property string stateString: "" + states: State { + when: triggerState + PropertyChanges { + target: theRect + stateString: "inState" + } + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/urlResolution.qml b/tests/auto/qtquick2/qdeclarativestates/data/urlResolution.qml new file mode 100644 index 0000000000..516ac034d6 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/urlResolution.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 +import "Implementation" + +Rectangle { + width: 100 + height: 200 + + MyType { + objectName: "MyType" + anchors.fill: parent + } +} diff --git a/tests/auto/qtquick2/qdeclarativestates/data/whenOrdering.qml b/tests/auto/qtquick2/qdeclarativestates/data/whenOrdering.qml new file mode 100644 index 0000000000..92025a2054 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/data/whenOrdering.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + property bool condition1: false + property bool condition2: false + + states: [ + State { name: "state1"; when: condition1 }, + State { name: "state2"; when: condition2 } + ] +} diff --git a/tests/auto/qtquick2/qdeclarativestates/qdeclarativestates.pro b/tests/auto/qtquick2/qdeclarativestates/qdeclarativestates.pro new file mode 100644 index 0000000000..f799f7066b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/qdeclarativestates.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdeclarativestates +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativestates.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qdeclarativestates/tst_qdeclarativestates.cpp b/tests/auto/qtquick2/qdeclarativestates/tst_qdeclarativestates.cpp new file mode 100644 index 0000000000..663d78d402 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestates/tst_qdeclarativestates.cpp @@ -0,0 +1,1596 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class MyAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(int foo READ foo WRITE setFoo) +public: + MyAttached(QObject *parent) : QObject(parent), m_foo(13) {} + + int foo() const { return m_foo; } + void setFoo(int f) { m_foo = f; } + +private: + int m_foo; +}; + +class MyRect : public QQuickRectangle +{ + Q_OBJECT + Q_PROPERTY(int propertyWithNotify READ propertyWithNotify WRITE setPropertyWithNotify NOTIFY oddlyNamedNotifySignal) +public: + MyRect() {} + + void doSomething() { emit didSomething(); } + + int propertyWithNotify() const { return m_prop; } + void setPropertyWithNotify(int i) { m_prop = i; emit oddlyNamedNotifySignal(); } + + static MyAttached *qmlAttachedProperties(QObject *o) { + return new MyAttached(o); + } +Q_SIGNALS: + void didSomething(); + void oddlyNamedNotifySignal(); + +private: + int m_prop; +}; + +QML_DECLARE_TYPE(MyRect) +QML_DECLARE_TYPEINFO(MyRect, QML_HAS_ATTACHED_PROPERTIES) + +class tst_qdeclarativestates : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativestates() {} + +private: + static QByteArray fullDataPath(const QString &path); + +private slots: + void initTestCase(); + + void basicChanges(); + void attachedPropertyChanges(); + void basicExtension(); + void basicBinding(); + void signalOverride(); + void signalOverrideCrash(); + void signalOverrideCrash2(); + void signalOverrideCrash3(); + void parentChange(); + void parentChangeErrors(); + void anchorChanges(); + void anchorChanges2(); + void anchorChanges3(); + void anchorChanges4(); + void anchorChanges5(); + void anchorChangesRTL(); + void anchorChangesRTL2(); + void anchorChangesRTL3(); + void anchorChangesCrash(); + void anchorRewindBug(); + void anchorRewindBug2(); + void script(); + void restoreEntryValues(); + void explicitChanges(); + void propertyErrors(); + void incorrectRestoreBug(); + void autoStateAtStartupRestoreBug(); + void deletingChange(); + void deletingState(); + void tempState(); + void illegalTempState(); + void nonExistantProperty(); + void reset(); + void illegalObjectCreation(); + void whenOrdering(); + void urlResolution(); + void unnamedWhen(); + void returnToBase(); + void extendsBug(); + void editProperties(); + void QTBUG_14830(); + void avoidFastForward(); + void revertListBug(); +}; + +void tst_qdeclarativestates::initTestCase() +{ + qmlRegisterType("Qt.test", 1, 0, "MyRectangle"); +} + +QByteArray tst_qdeclarativestates::fullDataPath(const QString &path) +{ + return QUrl::fromLocalFile(TESTDATA(path)).toString().toUtf8(); +} + +void tst_qdeclarativestates::basicChanges() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState("bordered"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),2.0); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1.0); + //### we should be checking that this is an implicit rather than explicit 1 (which currently fails) + + rectPrivate->setState("bordered"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),2.0); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1.0); + + } + + { + // Test basicChanges4.qml can magically connect to propertyWithNotify's notify + // signal using 'onPropertyWithNotifyChanged' even though the signal name is + // actually 'oddlyNamedNotifySignal' + + QDeclarativeComponent component(&engine, TESTDATA("basicChanges4.qml")); + QVERIFY(component.isReady()); + + MyRect *rect = qobject_cast(component.create()); + QVERIFY(rect != 0); + + QMetaProperty prop = rect->metaObject()->property(rect->metaObject()->indexOfProperty("propertyWithNotify")); + QVERIFY(prop.hasNotifySignal()); + QString notifySignal = QByteArray(prop.notifySignal().signature()); + QVERIFY(!notifySignal.startsWith("propertyWithNotifyChanged(")); + + QCOMPARE(rect->color(), QColor(Qt::red)); + + rect->setPropertyWithNotify(100); + QCOMPARE(rect->color(), QColor(Qt::blue)); + } +} + +void tst_qdeclarativestates::attachedPropertyChanges() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent component(&engine, TESTDATA("attachedPropertyChanges.qml")); + QVERIFY(component.isReady()); + + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item != 0); + QCOMPARE(item->width(), 50.0); + + // Ensure attached property has been changed + QObject *attObj = qmlAttachedPropertiesObject(item, false); + QVERIFY(attObj); + + MyAttached *att = qobject_cast(attObj); + QVERIFY(att); + + QCOMPARE(att->foo(), 1); +} + +void tst_qdeclarativestates::basicExtension() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicExtension.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState("bordered"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),2.0); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1.0); + + rectPrivate->setState("bordered"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->border()->width(),2.0); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->border()->width(),1.0); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("fakeExtension.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + } +} + +void tst_qdeclarativestates::basicBinding() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("green")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("red")); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor2", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor2", QColor("green")); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicBinding4.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("yellow")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + rect->setProperty("sourceColor", QColor("purple")); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("purple")); + + rectPrivate->setState("green"); + QCOMPARE(rect->color(),QColor("green")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + } +} + +void tst_qdeclarativestates::signalOverride() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride.qml")); + MyRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + rect->doSomething(); + QCOMPARE(rect->color(),QColor("blue")); + + QQuickItemPrivate::get(rect)->setState("green"); + rect->doSomething(); + QCOMPARE(rect->color(),QColor("green")); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverride2.qml")); + MyRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("white")); + rect->doSomething(); + QCOMPARE(rect->color(),QColor("blue")); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("extendedRect")); + QQuickItemPrivate::get(innerRect)->setState("green"); + rect->doSomething(); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(innerRect->color(),QColor("green")); + QCOMPARE(innerRect->property("extendedColor").value(),QColor("green")); + } +} + +void tst_qdeclarativestates::signalOverrideCrash() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash.qml")); + MyRect *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate::get(rect)->setState("overridden"); + rect->doSomething(); +} + +void tst_qdeclarativestates::signalOverrideCrash2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate::get(rect)->setState("state1"); + QQuickItemPrivate::get(rect)->setState("state2"); + QQuickItemPrivate::get(rect)->setState("state1"); + + delete rect; +} + +void tst_qdeclarativestates::signalOverrideCrash3() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("signalOverrideCrash3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate::get(rect)->setState("state1"); + QQuickItemPrivate::get(rect)->setState(""); + QQuickItemPrivate::get(rect)->setState("state2"); + QQuickItemPrivate::get(rect)->setState(""); + + delete rect; +} + +void tst_qdeclarativestates::parentChange() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange1.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickParentChange *pChange = qobject_cast(state->operationAt(0)); + QVERIFY(pChange != 0); + QQuickItem *nParent = qobject_cast(rect->findChild("NewParent")); + QVERIFY(nParent != 0); + + QCOMPARE(pChange->parent(), nParent); + + QQuickItemPrivate::get(rect)->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(0)); + QCOMPARE(innerRect->scale(), qreal(1)); + QCOMPARE(innerRect->x(), qreal(-133)); + QCOMPARE(innerRect->y(), qreal(-300)); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + rectPrivate->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(15)); + QCOMPARE(innerRect->scale(), qreal(.5)); + QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-19.9075)); + QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-8.73433)); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + rectPrivate->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(-37)); + QCOMPARE(innerRect->scale(), qreal(.25)); + QCOMPARE(QString("%1").arg(innerRect->x()), QString("%1").arg(-217.305)); + QCOMPARE(QString("%1").arg(innerRect->y()), QString("%1").arg(-164.413)); + + rectPrivate->setState(""); + QCOMPARE(innerRect->rotation(), qreal(0)); + QCOMPARE(innerRect->scale(), qreal(1)); + QCOMPARE(innerRect->x(), qreal(5)); + //do a non-qFuzzyCompare fuzzy compare + QVERIFY(innerRect->y() < qreal(0.00001) && innerRect->y() > qreal(-0.00001)); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange6.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QQuickItemPrivate::get(rect)->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(180)); + QCOMPARE(innerRect->scale(), qreal(1)); + QCOMPARE(innerRect->x(), qreal(-105)); + QCOMPARE(innerRect->y(), qreal(-105)); + } +} + +void tst_qdeclarativestates::parentChangeErrors() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange4.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange4.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under non-uniform scale"); + QQuickItemPrivate::get(rect)->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(0)); + QCOMPARE(innerRect->scale(), qreal(1)); + QCOMPARE(innerRect->x(), qreal(5)); + QCOMPARE(innerRect->y(), qreal(5)); + } + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("parentChange5.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QTest::ignoreMessage(QtWarningMsg, fullDataPath("parentChange5.qml") + ":25:9: QML ParentChange: Unable to preserve appearance under complex transform"); + QQuickItemPrivate::get(rect)->setState("reparented"); + QCOMPARE(innerRect->rotation(), qreal(0)); + QCOMPARE(innerRect->scale(), qreal(1)); + QCOMPARE(innerRect->x(), qreal(5)); + QCOMPARE(innerRect->y(), qreal(5)); + } +} + +void tst_qdeclarativestates::anchorChanges() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + rectPrivate->setState("right"); + QCOMPARE(innerRect->x(), qreal(150)); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all) + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), qreal(5)); + + delete rect; +} + +void tst_qdeclarativestates::anchorChanges2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + rectPrivate->setState("right"); + QCOMPARE(innerRect->x(), qreal(150)); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), qreal(5)); + + delete rect; +} + +void tst_qdeclarativestates::anchorChanges3() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); + QVERIFY(leftGuideline != 0); + + QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); + QVERIFY(bottomGuideline != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + rectPrivate->setState("reanchored"); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine); + + QCOMPARE(innerRect->x(), qreal(10)); + QCOMPARE(innerRect->y(), qreal(0)); + QCOMPARE(innerRect->width(), qreal(190)); + QCOMPARE(innerRect->height(), qreal(150)); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), qreal(0)); + QCOMPARE(innerRect->y(), qreal(10)); + QCOMPARE(innerRect->width(), qreal(150)); + QCOMPARE(innerRect->height(), qreal(190)); + + delete rect; +} + +void tst_qdeclarativestates::anchorChanges4() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges4.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); + QVERIFY(leftGuideline != 0); + + QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); + QVERIFY(bottomGuideline != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + QQuickItemPrivate::get(rect)->setState("reanchored"); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().item, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->horizontalCenter().anchorLine, QQuickItemPrivate::get(bottomGuideline)->horizontalCenter().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().item, QQuickItemPrivate::get(leftGuideline)->verticalCenter().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->verticalCenter().anchorLine, QQuickItemPrivate::get(leftGuideline)->verticalCenter().anchorLine); + + delete rect; +} + +void tst_qdeclarativestates::anchorChanges5() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges5.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + + QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); + QVERIFY(leftGuideline != 0); + + QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); + QVERIFY(bottomGuideline != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + QQuickItemPrivate::get(rect)->setState("reanchored"); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + //QCOMPARE(aChanges->anchors()->horizontalCenter().item, bottomGuideline->horizontalCenter().item); + //QCOMPARE(aChanges->anchors()->horizontalCenter().anchorLine, bottomGuideline->horizontalCenter().anchorLine); + //QCOMPARE(aChanges->anchors()->baseline().item, leftGuideline->baseline().item); + //QCOMPARE(aChanges->anchors()->baseline().anchorLine, leftGuideline->baseline().anchorLine); + + delete rect; +} + +void mirrorAnchors(QQuickItem *item) { + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->setLayoutMirror(true); +} + +qreal offsetRTL(QQuickItem *anchorItem, QQuickItem *item) { + return anchorItem->width()+2*anchorItem->x()-item->width(); +} + +void tst_qdeclarativestates::anchorChangesRTL() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges1.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + mirrorAnchors(innerRect); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + rectPrivate->setState("right"); + QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150)); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickAnchorLine::Invalid); //### was reset (how do we distinguish from not set at all) + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) -qreal(5)); + + delete rect; +} + +void tst_qdeclarativestates::anchorChangesRTL2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + mirrorAnchors(innerRect); + + rectPrivate->setState("right"); + QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(150)); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(5)); + + delete rect; +} + +void tst_qdeclarativestates::anchorChangesRTL3() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChanges3.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QQuickRectangle *innerRect = qobject_cast(rect->findChild("MyRect")); + QVERIFY(innerRect != 0); + mirrorAnchors(innerRect); + + QQuickItem *leftGuideline = qobject_cast(rect->findChild("LeftGuideline")); + QVERIFY(leftGuideline != 0); + + QQuickItem *bottomGuideline = qobject_cast(rect->findChild("BottomGuideline")); + QVERIFY(bottomGuideline != 0); + + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QQuickAnchorChanges *aChanges = qobject_cast(state->operationAt(0)); + QVERIFY(aChanges != 0); + + rectPrivate->setState("reanchored"); + QCOMPARE(aChanges->object(), qobject_cast(innerRect)); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().item, QQuickItemPrivate::get(leftGuideline)->left().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->left().anchorLine, QQuickItemPrivate::get(leftGuideline)->left().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().item, rectPrivate->right().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->right().anchorLine, rectPrivate->right().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().item, rectPrivate->top().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->top().anchorLine, rectPrivate->top().anchorLine); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().item, QQuickItemPrivate::get(bottomGuideline)->bottom().item); + QCOMPARE(QQuickItemPrivate::get(aChanges->object())->anchors()->bottom().anchorLine, QQuickItemPrivate::get(bottomGuideline)->bottom().anchorLine); + + QCOMPARE(innerRect->x(), offsetRTL(leftGuideline, innerRect) - qreal(10)); + QCOMPARE(innerRect->y(), qreal(0)); + // between left side of parent and leftGuideline.x: 10, which has width 0 + QCOMPARE(innerRect->width(), qreal(10)); + QCOMPARE(innerRect->height(), qreal(150)); + + rectPrivate->setState(""); + QCOMPARE(innerRect->x(), offsetRTL(rect, innerRect) - qreal(0)); + QCOMPARE(innerRect->y(), qreal(10)); + // between right side of parent and left side of rightGuideline.x: 150, which has width 0 + QCOMPARE(innerRect->width(), qreal(50)); + QCOMPARE(innerRect->height(), qreal(190)); + + delete rect; +} + +//QTBUG-9609 +void tst_qdeclarativestates::anchorChangesCrash() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorChangesCrash.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate::get(rect)->setState("reanchored"); + + delete rect; +} + +// QTBUG-12273 +void tst_qdeclarativestates::anchorRewindBug() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("anchorRewindBug.qml"))); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + + QQuickRectangle *rect = qobject_cast(view->rootObject()); + QVERIFY(rect != 0); + + QQuickItem * column = rect->findChild("column"); + + QVERIFY(column != 0); + QVERIFY(!QQuickItemPrivate::get(column)->heightValid); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QCOMPARE(column->height(), 200.0); + QQuickItemPrivate::get(rect)->setState("reanchored"); + + // column height and width should stay implicit + // and column's implicit resizing should still work + QVERIFY(!QQuickItemPrivate::get(column)->heightValid); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QTRY_COMPARE(column->height(), 100.0); + + QQuickItemPrivate::get(rect)->setState(""); + + // column height and width should stay implicit + // and column's implicit resizing should still work + QVERIFY(!QQuickItemPrivate::get(column)->heightValid); + QVERIFY(!QQuickItemPrivate::get(column)->widthValid); + QTRY_COMPARE(column->height(), 200.0); + + delete view; +} + +// QTBUG-11834 +void tst_qdeclarativestates::anchorRewindBug2() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("anchorRewindBug2.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QQuickRectangle *mover = rect->findChild("mover"); + + QVERIFY(mover != 0); + QCOMPARE(mover->y(), qreal(0.0)); + QCOMPARE(mover->width(), qreal(50.0)); + + QQuickItemPrivate::get(rect)->setState("anchored"); + QCOMPARE(mover->y(), qreal(250.0)); + QCOMPARE(mover->width(), qreal(200.0)); + + QQuickItemPrivate::get(rect)->setState(""); + QCOMPARE(mover->y(), qreal(0.0)); + QCOMPARE(mover->width(), qreal(50.0)); + + delete rect; +} + +void tst_qdeclarativestates::script() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent rectComponent(&engine, TESTDATA("script.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("blue")); // a script isn't reverted + } +} + +void tst_qdeclarativestates::restoreEntryValues() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("restoreEntryValues.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("blue")); +} + +void tst_qdeclarativestates::explicitChanges() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("explicit.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QDeclarativeListReference list(rect, "states"); + QDeclarativeState *state = qobject_cast(list.at(0)); + QVERIFY(state != 0); + + qmlExecuteDeferred(state); + QDeclarativePropertyChanges *changes = qobject_cast(rect->findChild("changes")); + QVERIFY(changes != 0); + QVERIFY(changes->isExplicit()); + + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rect->setProperty("sourceColor", QColor("green")); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + rect->setProperty("sourceColor", QColor("yellow")); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("yellow")); +} + +void tst_qdeclarativestates::propertyErrors() +{ + QDeclarativeEngine engine; + QDeclarativeComponent rectComponent(&engine, TESTDATA("propertyErrors.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QCOMPARE(rect->color(),QColor("red")); + + QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\""); + QTest::ignoreMessage(QtWarningMsg, fullDataPath("propertyErrors.qml") + ":8:9: QML PropertyChanges: Cannot assign to read-only property \"activeFocus\""); + QQuickItemPrivate::get(rect)->setState("blue"); +} + +void tst_qdeclarativestates::incorrectRestoreBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("basicChanges.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rect->color(),QColor("red")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + // make sure if we change the base state value, we then restore to it correctly + rect->setColor(QColor("green")); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("green")); +} + +void tst_qdeclarativestates::autoStateAtStartupRestoreBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent component(&engine, TESTDATA("autoStateAtStartupRestoreBug.qml")); + QObject *obj = component.create(); + + QVERIFY(obj != 0); + QCOMPARE(obj->property("test").toInt(), 3); + + obj->setProperty("input", 2); + + QCOMPARE(obj->property("test").toInt(), 9); + + delete obj; +} + +void tst_qdeclarativestates::deletingChange() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("deleting.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + QCOMPARE(rect->radius(),qreal(5)); + + rectPrivate->setState(""); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->radius(),qreal(0)); + + QDeclarativePropertyChanges *pc = rect->findChild("pc1"); + QVERIFY(pc != 0); + delete pc; + + QDeclarativeState *state = rect->findChild(); + QVERIFY(state != 0); + qmlExecuteDeferred(state); + QCOMPARE(state->operationCount(), 1); + + rectPrivate->setState("blue"); + QCOMPARE(rect->color(),QColor("red")); + QCOMPARE(rect->radius(),qreal(5)); + + delete rect; +} + +void tst_qdeclarativestates::deletingState() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("deletingState.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + + QDeclarativeStateGroup *sg = rect->findChild(); + QVERIFY(sg != 0); + QVERIFY(sg->findState("blue") != 0); + + sg->setState("blue"); + QCOMPARE(rect->color(),QColor("blue")); + + sg->setState(""); + QCOMPARE(rect->color(),QColor("red")); + + QDeclarativeState *state = rect->findChild(); + QVERIFY(state != 0); + delete state; + + QVERIFY(sg->findState("blue") == 0); + + //### should we warn that state doesn't exist + sg->setState("blue"); + QCOMPARE(rect->color(),QColor("red")); + + delete rect; +} + +void tst_qdeclarativestates::tempState() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("legalTempState.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QTest::ignoreMessage(QtDebugMsg, "entering placed"); + QTest::ignoreMessage(QtDebugMsg, "entering idle"); + rectPrivate->setState("placed"); + QCOMPARE(rectPrivate->state(), QLatin1String("idle")); +} + +void tst_qdeclarativestates::illegalTempState() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("illegalTempState.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QTest::ignoreMessage(QtWarningMsg, ": QML StateGroup: Can't apply a state change as part of a state definition."); + rectPrivate->setState("placed"); + QCOMPARE(rectPrivate->state(), QLatin1String("placed")); +} + +void tst_qdeclarativestates::nonExistantProperty() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent rectComponent(&engine, TESTDATA("nonExistantProp.qml")); + QQuickRectangle *rect = qobject_cast(rectComponent.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QTest::ignoreMessage(QtWarningMsg, fullDataPath("nonExistantProp.qml") + ":9:9: QML PropertyChanges: Cannot assign to non-existent property \"colr\""); + rectPrivate->setState("blue"); + QCOMPARE(rectPrivate->state(), QLatin1String("blue")); +} + +void tst_qdeclarativestates::reset() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("reset.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickImage *image = rect->findChild(); + QVERIFY(image != 0); + QCOMPARE(image->width(), qreal(40.)); + QCOMPARE(image->height(), qreal(20.)); + + QQuickItemPrivate::get(rect)->setState("state1"); + + QCOMPARE(image->width(), 20.0); + QCOMPARE(image->height(), qreal(20.)); + + delete rect; +} + +void tst_qdeclarativestates::illegalObjectCreation() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent component(&engine, TESTDATA("illegalObj.qml")); + QList errors = component.errors(); + QVERIFY(errors.count() == 1); + const QDeclarativeError &error = errors.at(0); + QCOMPARE(error.line(), 9); + QCOMPARE(error.column(), 23); + QCOMPARE(error.description().toUtf8().constData(), "PropertyChanges does not support creating state-specific objects."); +} + +void tst_qdeclarativestates::whenOrdering() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("whenOrdering.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QCOMPARE(rectPrivate->state(), QLatin1String("")); + rect->setProperty("condition2", true); + QCOMPARE(rectPrivate->state(), QLatin1String("state2")); + rect->setProperty("condition1", true); + QCOMPARE(rectPrivate->state(), QLatin1String("state1")); + rect->setProperty("condition2", false); + QCOMPARE(rectPrivate->state(), QLatin1String("state1")); + rect->setProperty("condition2", true); + QCOMPARE(rectPrivate->state(), QLatin1String("state1")); + rect->setProperty("condition1", false); + rect->setProperty("condition2", false); + QCOMPARE(rectPrivate->state(), QLatin1String("")); +} + +void tst_qdeclarativestates::urlResolution() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("urlResolution.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickItem *myType = rect->findChild("MyType"); + QQuickImage *image1 = rect->findChild("image1"); + QQuickImage *image2 = rect->findChild("image2"); + QQuickImage *image3 = rect->findChild("image3"); + QVERIFY(myType != 0 && image1 != 0 && image2 != 0 && image3 != 0); + + QQuickItemPrivate::get(myType)->setState("SetImageState"); + QUrl resolved = QUrl::fromLocalFile(TESTDATA("Implementation/images/qt-logo.png")); + QCOMPARE(image1->source(), resolved); + QCOMPARE(image2->source(), resolved); + QCOMPARE(image3->source(), resolved); + + delete rect; +} + +void tst_qdeclarativestates::unnamedWhen() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("unnamedWhen.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QCOMPARE(rectPrivate->state(), QLatin1String("")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); + rect->setProperty("triggerState", true); + QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState")); + rect->setProperty("triggerState", false); + QCOMPARE(rectPrivate->state(), QLatin1String("")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); +} + +void tst_qdeclarativestates::returnToBase() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("returnToBase.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QCOMPARE(rectPrivate->state(), QLatin1String("")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("")); + rect->setProperty("triggerState", true); + QCOMPARE(rectPrivate->state(), QLatin1String("anonymousState1")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("inState")); + rect->setProperty("triggerState", false); + QCOMPARE(rectPrivate->state(), QLatin1String("")); + QCOMPARE(rect->property("stateString").toString(), QLatin1String("originalState")); +} + +//QTBUG-12559 +void tst_qdeclarativestates::extendsBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("extendsBug.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QQuickRectangle *greenRect = rect->findChild("greenRect"); + + rectPrivate->setState("b"); + QCOMPARE(greenRect->x(), qreal(100)); + QCOMPARE(greenRect->y(), qreal(100)); +} + +void tst_qdeclarativestates::editProperties() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("editProperties.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QDeclarativeStateGroup *stateGroup = rectPrivate->_states(); + QVERIFY(stateGroup != 0); + qmlExecuteDeferred(stateGroup); + + QDeclarativeState *blueState = stateGroup->findState("blue"); + QVERIFY(blueState != 0); + qmlExecuteDeferred(blueState); + + QDeclarativePropertyChanges *propertyChangesBlue = qobject_cast(blueState->operationAt(0)); + QVERIFY(propertyChangesBlue != 0); + + QDeclarativeState *greenState = stateGroup->findState("green"); + QVERIFY(greenState != 0); + qmlExecuteDeferred(greenState); + + QDeclarativePropertyChanges *propertyChangesGreen = qobject_cast(greenState->operationAt(0)); + QVERIFY(propertyChangesGreen != 0); + + QQuickRectangle *childRect = rect->findChild("rect2"); + QVERIFY(childRect != 0); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->height(), qreal(200)); + + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(50)); + QCOMPARE(childRect->height(), qreal(40)); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QVERIFY(blueState->bindingInRevertList(childRect, "width")); + + + rectPrivate->setState("green"); + QCOMPARE(childRect->width(), qreal(200)); + QCOMPARE(childRect->height(), qreal(100)); + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + + + rectPrivate->setState(""); + + + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QVERIFY(propertyChangesBlue->containsValue("width")); + QVERIFY(!propertyChangesBlue->containsProperty("x")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); + QVERIFY(!propertyChangesBlue->value("x").isValid()); + + propertyChangesBlue->changeValue("width", 60); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + + propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); + QVERIFY(!propertyChangesBlue->containsValue("width")); + QVERIFY(propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + propertyChangesBlue->changeValue("width", 50); + QVERIFY(propertyChangesBlue->containsValue("width")); + QVERIFY(!propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 50); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(50)); + QCOMPARE(childRect->height(), qreal(40)); + + propertyChangesBlue->changeValue("width", 60); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 60); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QCOMPARE(childRect->width(), qreal(60)); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + + propertyChangesBlue->changeExpression("width", "myRectangle.width / 2"); + QVERIFY(!propertyChangesBlue->containsValue("width")); + QVERIFY(propertyChangesBlue->containsExpression("width")); + QCOMPARE(propertyChangesBlue->value("width").toInt(), 0); + QCOMPARE(propertyChangesBlue->actions().length(), 2); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->width(), qreal(200)); + + propertyChangesBlue->changeValue("width", 50); + QCOMPARE(childRect->width(), qreal(50)); + + rectPrivate->setState(""); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + + QCOMPARE(propertyChangesGreen->actions().length(), 2); + rectPrivate->setState("green"); + QCOMPARE(childRect->width(), qreal(200)); + QCOMPARE(childRect->height(), qreal(100)); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + QCOMPARE(propertyChangesGreen->actions().length(), 2); + + + propertyChangesGreen->removeProperty("height"); + QVERIFY(!QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "height"))); + QCOMPARE(childRect->height(), qreal(200)); + + QVERIFY(greenState->bindingInRevertList(childRect, "width")); + QVERIFY(greenState->containsPropertyInRevertList(childRect, "width")); + propertyChangesGreen->removeProperty("width"); + QVERIFY(QDeclarativePropertyPrivate::binding(QDeclarativeProperty(childRect, "width"))); + QCOMPARE(childRect->width(), qreal(402)); + QVERIFY(!greenState->bindingInRevertList(childRect, "width")); + QVERIFY(!greenState->containsPropertyInRevertList(childRect, "width")); + + propertyChangesBlue->removeProperty("width"); + QCOMPARE(childRect->width(), qreal(402)); + + rectPrivate->setState("blue"); + QCOMPARE(childRect->width(), qreal(402)); + QCOMPARE(childRect->height(), qreal(40)); +} + +void tst_qdeclarativestates::QTBUG_14830() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("QTBUG-14830.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + QQuickItem *item = rect->findChild("area"); + + QCOMPARE(item->width(), qreal(171)); +} + +void tst_qdeclarativestates::avoidFastForward() +{ + QDeclarativeEngine engine; + + //shouldn't fast forward if there isn't a transition + QDeclarativeComponent c(&engine, TESTDATA("avoidFastForward.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + rectPrivate->setState("a"); + QCOMPARE(rect->property("updateCount").toInt(), 1); +} + +//QTBUG-22583 +void tst_qdeclarativestates::revertListBug() +{ + QDeclarativeEngine engine; + + QDeclarativeComponent c(&engine, TESTDATA("revertListBug.qml")); + QQuickRectangle *rect = qobject_cast(c.create()); + QVERIFY(rect != 0); + + QQuickRectangle *rect1 = rect->findChild("rect1"); + QQuickRectangle *rect2 = rect->findChild("rect2"); + QQuickItem *origParent1 = rect->findChild("originalParent1"); + QQuickItem *origParent2 = rect->findChild("originalParent2"); + QQuickItem *newParent = rect->findChild("newParent"); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); + + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + rectPrivate->setState("reparented"); + + QCOMPARE(rect1->parentItem(), newParent); + QCOMPARE(rect2->parentItem(), origParent2); + + rectPrivate->setState(""); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); + + QMetaObject::invokeMethod(rect, "switchTargetItem"); + + rectPrivate->setState("reparented"); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), newParent); + + rectPrivate->setState(""); + + QCOMPARE(rect1->parentItem(), origParent1); + QCOMPARE(rect2->parentItem(), origParent2); //QTBUG-22583 causes rect2's parent item to be origParent1 +} + +QTEST_MAIN(tst_qdeclarativestates) + +#include "tst_qdeclarativestates.moc" diff --git a/tests/auto/qtquick2/qdeclarativestyledtext/qdeclarativestyledtext.pro b/tests/auto/qtquick2/qdeclarativestyledtext/qdeclarativestyledtext.pro new file mode 100644 index 0000000000..84532f611e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestyledtext/qdeclarativestyledtext.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qdeclarativestyledtext +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativestyledtext.cpp + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp b/tests/auto/qtquick2/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp new file mode 100644 index 0000000000..b09c33302e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativestyledtext/tst_qdeclarativestyledtext.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include + +class tst_qdeclarativestyledtext : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativestyledtext() + { + } + +private slots: + void textOutput(); + void textOutput_data(); +}; + +// For malformed input all we test is that we get the expected text out. +// +void tst_qdeclarativestyledtext::textOutput_data() +{ + QTest::addColumn("input"); + QTest::addColumn("output"); + + QTest::newRow("bold") << "bold" << "bold"; + QTest::newRow("italic") << "italic" << "italic"; + QTest::newRow("missing >") << "text") << "text") << "text<" << "text"; + QTest::newRow("missing ") << "text" << "text"; + QTest::newRow("bad nest") << "text italic" << "text italic"; + QTest::newRow("font color") << "red text" << "red text"; + QTest::newRow("font color: single quote") << "red text" << "red text"; + QTest::newRow("font size") << "text" << "text"; + QTest::newRow("font empty") << "text" << "text"; + QTest::newRow("font bad 1") << "text" << "text"; + QTest::newRow("font bad 2") << "text" << ""; + QTest::newRow("extra close") << "text" << "text"; + QTest::newRow("extra space") << "text" << "text"; + QTest::newRow("entities") << "<b>this & that</b>" << "this & that"; + QTest::newRow("newline") << "text
more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") ; + QTest::newRow("self-closing newline") << "text
more text" << QLatin1String("text") + QChar(QChar::LineSeparator) + QLatin1String("more text") ; + QTest::newRow("empty") << "" << ""; +} + +void tst_qdeclarativestyledtext::textOutput() +{ + QFETCH(QString, input); + QFETCH(QString, output); + + QTextLayout layout; + QDeclarativeStyledText::parse(input, layout); + + QCOMPARE(layout.text(), output); +} + + +QTEST_MAIN(tst_qdeclarativestyledtext) + +#include "tst_qdeclarativestyledtext.moc" diff --git a/tests/auto/qtquick2/qdeclarativesystempalette/qdeclarativesystempalette.pro b/tests/auto/qtquick2/qdeclarativesystempalette/qdeclarativesystempalette.pro new file mode 100644 index 0000000000..87c2af2190 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesystempalette/qdeclarativesystempalette.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qdeclarativesystempalette +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativesystempalette.cpp + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private widgets testlib diff --git a/tests/auto/qtquick2/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp b/tests/auto/qtquick2/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp new file mode 100644 index 0000000000..4cb09f90f5 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativesystempalette/tst_qdeclarativesystempalette.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include + +class tst_qdeclarativesystempalette : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativesystempalette(); + +private slots: + void activePalette(); + void inactivePalette(); + void disabledPalette(); + void paletteChanged(); + +private: + QDeclarativeEngine engine; +}; + +tst_qdeclarativesystempalette::tst_qdeclarativesystempalette() +{ +} + +void tst_qdeclarativesystempalette::activePalette() +{ + QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeSystemPalette *object = qobject_cast(component.create()); + + QVERIFY(object != 0); + + QPalette palette; + palette.setCurrentColorGroup(QPalette::Active); + QCOMPARE(palette.window().color(), object->window()); + QCOMPARE(palette.windowText().color(), object->windowText()); + QCOMPARE(palette.base().color(), object->base()); + QCOMPARE(palette.text().color(), object->text()); + QCOMPARE(palette.alternateBase().color(), object->alternateBase()); + QCOMPARE(palette.button().color(), object->button()); + QCOMPARE(palette.buttonText().color(), object->buttonText()); + QCOMPARE(palette.light().color(), object->light()); + QCOMPARE(palette.midlight().color(), object->midlight()); + QCOMPARE(palette.dark().color(), object->dark()); + QCOMPARE(palette.mid().color(), object->mid()); + QCOMPARE(palette.shadow().color(), object->shadow()); + QCOMPARE(palette.highlight().color(), object->highlight()); + QCOMPARE(palette.highlightedText().color(), object->highlightedText()); + + delete object; +} + +void tst_qdeclarativesystempalette::inactivePalette() +{ + QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Inactive }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeSystemPalette *object = qobject_cast(component.create()); + + QVERIFY(object != 0); + QVERIFY(object->colorGroup() == QDeclarativeSystemPalette::Inactive); + + QPalette palette; + palette.setCurrentColorGroup(QPalette::Inactive); + QCOMPARE(palette.window().color(), object->window()); + QCOMPARE(palette.windowText().color(), object->windowText()); + QCOMPARE(palette.base().color(), object->base()); + QCOMPARE(palette.text().color(), object->text()); + QCOMPARE(palette.alternateBase().color(), object->alternateBase()); + QCOMPARE(palette.button().color(), object->button()); + QCOMPARE(palette.buttonText().color(), object->buttonText()); + QCOMPARE(palette.light().color(), object->light()); + QCOMPARE(palette.midlight().color(), object->midlight()); + QCOMPARE(palette.dark().color(), object->dark()); + QCOMPARE(palette.mid().color(), object->mid()); + QCOMPARE(palette.shadow().color(), object->shadow()); + QCOMPARE(palette.highlight().color(), object->highlight()); + QCOMPARE(palette.highlightedText().color(), object->highlightedText()); + + delete object; +} + +void tst_qdeclarativesystempalette::disabledPalette() +{ + QString componentStr = "import QtQuick 2.0\nSystemPalette { colorGroup: SystemPalette.Disabled }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeSystemPalette *object = qobject_cast(component.create()); + + QVERIFY(object != 0); + QVERIFY(object->colorGroup() == QDeclarativeSystemPalette::Disabled); + + QPalette palette; + palette.setCurrentColorGroup(QPalette::Disabled); + QCOMPARE(palette.window().color(), object->window()); + QCOMPARE(palette.windowText().color(), object->windowText()); + QCOMPARE(palette.base().color(), object->base()); + QCOMPARE(palette.text().color(), object->text()); + QCOMPARE(palette.alternateBase().color(), object->alternateBase()); + QCOMPARE(palette.button().color(), object->button()); + QCOMPARE(palette.buttonText().color(), object->buttonText()); + QCOMPARE(palette.light().color(), object->light()); + QCOMPARE(palette.midlight().color(), object->midlight()); + QCOMPARE(palette.dark().color(), object->dark()); + QCOMPARE(palette.mid().color(), object->mid()); + QCOMPARE(palette.shadow().color(), object->shadow()); + QCOMPARE(palette.highlight().color(), object->highlight()); + QCOMPARE(palette.highlightedText().color(), object->highlightedText()); + + delete object; +} + +void tst_qdeclarativesystempalette::paletteChanged() +{ + QString componentStr = "import QtQuick 2.0\nSystemPalette { }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QDeclarativeSystemPalette *object = qobject_cast(component.create()); + + QVERIFY(object != 0); + + QPalette p; + p.setCurrentColorGroup(QPalette::Active); + p.setColor(QPalette::Active, QPalette::Text, QColor("red")); + p.setColor(QPalette::Active, QPalette::ButtonText, QColor("green")); + p.setColor(QPalette::Active, QPalette::WindowText, QColor("blue")); + + qApp->setPalette(p); + + object->setColorGroup(QDeclarativeSystemPalette::Active); + QTRY_COMPARE(QColor("red"), object->text()); + QTRY_COMPARE(QColor("green"), object->buttonText()); + QTRY_COMPARE(QColor("blue"), object->windowText()); + + delete object; +} + +QTEST_MAIN(tst_qdeclarativesystempalette) + +#include "tst_qdeclarativesystempalette.moc" diff --git a/tests/auto/qtquick2/qdeclarativetimer/qdeclarativetimer.pro b/tests/auto/qtquick2/qdeclarativetimer/qdeclarativetimer.pro new file mode 100644 index 0000000000..d990dc449f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativetimer/qdeclarativetimer.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qdeclarativetimer +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativetimer.cpp + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private gui testlib diff --git a/tests/auto/qtquick2/qdeclarativetimer/tst_qdeclarativetimer.cpp b/tests/auto/qtquick2/qdeclarativetimer/tst_qdeclarativetimer.cpp new file mode 100644 index 0000000000..ac32585365 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativetimer/tst_qdeclarativetimer.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +class tst_qdeclarativetimer : public QObject +{ + Q_OBJECT +public: + tst_qdeclarativetimer(); + +private slots: + void notRepeating(); + void notRepeatingStart(); + void repeat(); + void noTriggerIfNotRunning(); + void triggeredOnStart(); + void triggeredOnStartRepeat(); + void changeDuration(); + void restart(); + void parentProperty(); +}; + +class TimerHelper : public QObject +{ + Q_OBJECT +public: + TimerHelper() : QObject(), count(0) + { + } + + int count; + +public slots: + void timeout() { + ++count; + } +}; + +#define TIMEOUT_TIMEOUT 200 + +tst_qdeclarativetimer::tst_qdeclarativetimer() +{ +} + +void tst_qdeclarativetimer::notRepeating() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + QVERIFY(timer->isRunning()); + QVERIFY(!timer->isRepeating()); + QCOMPARE(timer->interval(), 100); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QVERIFY(timer->isRunning() == false); +} + +void tst_qdeclarativetimer::notRepeatingStart() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100 }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + QVERIFY(!timer->isRunning()); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 0); + + timer->start(); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 1); + QVERIFY(timer->isRunning() == false); + + delete timer; +} + +void tst_qdeclarativetimer::repeat() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; repeat: true; running: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > 0); + int oldCount = helper.count; + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > oldCount); + QVERIFY(timer->isRunning()); + + oldCount = helper.count; + timer->stop(); + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count == oldCount); + QVERIFY(timer->isRunning() == false); + + QSignalSpy spy(timer, SIGNAL(repeatChanged())); + + timer->setRepeating(false); + QVERIFY(!timer->isRepeating()); + QCOMPARE(spy.count(),1); + + timer->setRepeating(false); + QCOMPARE(spy.count(),1); + + timer->setRepeating(true); + QCOMPARE(spy.count(),2); + + delete timer; +} + +void tst_qdeclarativetimer::triggeredOnStart() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true; triggeredOnStart: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + QVERIFY(timer->triggeredOnStart()); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QTest::qWait(1); + QCOMPARE(helper.count, 1); + + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 2); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(helper.count, 2); + QVERIFY(timer->isRunning() == false); + + QSignalSpy spy(timer, SIGNAL(triggeredOnStartChanged())); + + timer->setTriggeredOnStart(false); + QVERIFY(!timer->triggeredOnStart()); + QCOMPARE(spy.count(),1); + + timer->setTriggeredOnStart(false); + QCOMPARE(spy.count(),1); + + timer->setTriggeredOnStart(true); + QCOMPARE(spy.count(),2); + + delete timer; +} + +void tst_qdeclarativetimer::triggeredOnStartRepeat() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 100; running: true; triggeredOnStart: true; repeat: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QTest::qWait(1); + QCOMPARE(helper.count, 1); + + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > 1); + int oldCount = helper.count; + QTest::qWait(TIMEOUT_TIMEOUT); + QVERIFY(helper.count > oldCount); + QVERIFY(timer->isRunning()); + + delete timer; +} + +void tst_qdeclarativetimer::noTriggerIfNotRunning() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray( + "import QtQuick 2.0\n" + "Item { property bool ok: true\n" + "Timer { id: t1; interval: 100; repeat: true; running: true; onTriggered: if (!running) ok=false }" + "Timer { interval: 10; running: true; onTriggered: t1.running=false }" + "}" + ), QUrl::fromLocalFile("")); + QObject *item = component.create(); + QVERIFY(item != 0); + QTest::qWait(TIMEOUT_TIMEOUT); + QCOMPARE(item->property("ok").toBool(), true); + + delete item; +} + +void tst_qdeclarativetimer::changeDuration() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 200; repeat: true; running: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(500); + QCOMPARE(helper.count, 2); + + timer->setInterval(500); + + QTest::qWait(600); + QCOMPARE(helper.count, 3); + QVERIFY(timer->isRunning()); + + QSignalSpy spy(timer, SIGNAL(intervalChanged())); + + timer->setInterval(200); + QCOMPARE(timer->interval(), 200); + QCOMPARE(spy.count(),1); + + timer->setInterval(200); + QCOMPARE(spy.count(),1); + + timer->setInterval(300); + QCOMPARE(spy.count(),2); + + delete timer; +} + +void tst_qdeclarativetimer::restart() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nTimer { interval: 500; repeat: true; running: true }"), QUrl::fromLocalFile("")); + QDeclarativeTimer *timer = qobject_cast(component.create()); + QVERIFY(timer != 0); + + TimerHelper helper; + connect(timer, SIGNAL(triggered()), &helper, SLOT(timeout())); + QCOMPARE(helper.count, 0); + + QTest::qWait(600); + QCOMPARE(helper.count, 1); + + QTest::qWait(300); + + timer->restart(); + + QTest::qWait(700); + + QCOMPARE(helper.count, 2); + QVERIFY(timer->isRunning()); + + delete timer; +} + +void tst_qdeclarativetimer::parentProperty() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nItem { Timer { objectName: \"timer\"; running: parent.visible } }"), QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item != 0); + QDeclarativeTimer *timer = item->findChild("timer"); + QVERIFY(timer != 0); + + QVERIFY(timer->isRunning()); + + delete timer; +} + +QTEST_MAIN(tst_qdeclarativetimer) + +#include "tst_qdeclarativetimer.moc" diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/empty.xml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/empty.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/get.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/get.qml new file mode 100644 index 0000000000..509da7174b --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/get.qml @@ -0,0 +1,61 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { name: "name"; query: "name/string()" } + XmlRole { name: "type"; query: "type/string()" } + XmlRole { name: "age"; query: "age/number()" } + XmlRole { name: "size"; query: "size/string()" } + + id: root + + property bool preTest: false + property bool postTest: false + + function runPreTest() { + if (root.get(0) != undefined) + return; + + preTest = true; + } + + function runPostTest() { + if (root.get(-1) != undefined) + return; + + var row = root.get(0); + if (row.name != "Polly" || + row.type != "Parrot" || + row.age != 12 || + row.size != "Small") + return; + + row = root.get(1); + if (row.name != "Penny" || + row.type != "Turtle" || + row.age != 4 || + row.size != "Small") + return; + + row = root.get(7); + if (row.name != "Rover" || + row.type != "Dog" || + row.age != 0 || + row.size != "Large") + return; + + row = root.get(8); + if (row.name != "Tiny" || + row.type != "Elephant" || + row.age != 15 || + row.size != "Large") + return; + + if (root.get(9) != undefined) + return; + + postTest = true; + } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.qml new file mode 100644 index 0000000000..2df3927479 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { name: "name"; query: "name/string()" } + XmlRole { name: "type"; query: "type/string()" } + XmlRole { name: "age"; query: "age/number()" } + XmlRole { name: "size"; query: "size/string()" } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.xml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.xml new file mode 100644 index 0000000000..40cd6d0432 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model.xml @@ -0,0 +1,54 @@ + + + Polly + Parrot + 12 + Small + + + Penny + Turtle + 4 + Small + + + Warren + Rabbit + 2 + Small + + + Spot + Dog + 9 + Medium + + + Whiskers + Cat + 2 + Medium + + + Joey + Kangaroo + 1 + + + Kimba + Bunny + 65 + Large + + + Rover + Dog + Large + + + Tiny + Elephant + 15 + Large + + diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model2.xml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model2.xml new file mode 100644 index 0000000000..dab2ec6dc0 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/model2.xml @@ -0,0 +1,14 @@ + + + Polly + Parrot + 12 + Small + + + Penny + Turtle + 4 + Small + + diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/propertychanges.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/propertychanges.qml new file mode 100644 index 0000000000..f8a97bffc3 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/propertychanges.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { objectName: "role"; name: "name"; query: "name/string()" } + XmlRole { name: "type"; query: "type/string()" } + XmlRole { name: "age"; query: "age/number()" } + XmlRole { name: "size"; query: "size/string()" } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.qml new file mode 100644 index 0000000000..dc609e95e3 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "recipes.xml" + query: "/recipes/recipe" + XmlRole { name: "title"; query: "@title/string()" } + XmlRole { name: "picture"; query: "picture/string()" } + XmlRole { name: "ingredients"; query: "ingredients/string()" } + XmlRole { name: "preparation"; query: "method/string()" } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.xml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.xml new file mode 100644 index 0000000000..d71de60710 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/recipes.xml @@ -0,0 +1,90 @@ + + + content/pics/pancakes.jpg + +

    +
  • 1 cup (150g) self-raising flour +
  • 1 tbs caster sugar +
  • 3/4 cup (185ml) milk +
  • 1 egg +
+ + ]]> + +
    +
  1. Sift flour and sugar together into a bowl. Add a pinch of salt. +
  2. Beat milk and egg together, then add to dry ingredients. Beat until smooth. +
  3. Pour mixture into a pan on medium heat and cook until bubbles appear on the surface. +
  4. Turn over and cook other side until golden. +
+ + ]]>
+ + + content/pics/fruit-salad.jpg + + + + + content/pics/vegetable-soup.jpg + +
    +
  • 1 onion +
  • 1 turnip +
  • 1 potato +
  • 1 carrot +
  • 1 head of celery +
  • 1 1/2 litres of water +
+ + ]]>
+ +
    +
  1. Chop vegetables. +
  2. Boil in water until vegetables soften. +
  3. Season with salt and pepper to taste. +
+ + ]]>
+
+ + content/pics/hamburger.jpg + +
    +
  • 500g minced beef +
  • Seasoning +
  • lettuce, tomato, onion, cheese +
  • 1 hamburger bun for each burger +
+ + ]]>
+ +
    +
  1. Mix the beef, together with seasoning, in a food processor. +
  2. Shape the beef into burgers. +
  3. Grill the burgers for about 5 mins on each side (until cooked through) +
  4. Serve each burger on a bun with ketchup, cheese, lettuce, tomato and onion. +
+ + ]]>
+
+ + content/pics/lemonade.jpg + +
    +
  • 1 cup Lemon Juice +
  • 1 cup Sugar +
  • 6 Cups of Water (2 cups warm water, 4 cups cold water) +
+ + ]]>
+ +
    +
  1. Pour 2 cups of warm water into a pitcher and stir in sugar until it dissolves. +
  2. Pour in lemon juice, stir again, and add 4 cups of cold water. +
  3. Chill or serve over ice cubes. +
+ + ]]>
+
+ diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleCrash.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleCrash.qml new file mode 100644 index 0000000000..6a7059bb45 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleCrash.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + id: model + XmlRole {} + Component.onCompleted: model.roles = 0 +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleErrors.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleErrors.qml new file mode 100644 index 0000000000..91664b6d4a --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleErrors.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { name: "name"; query: "/name/string()" } //starts with '/' + XmlRole { name: "type"; query: "type" } //no type + XmlRole { name: "age"; query: "age/" } //ends with '/' + XmlRole { name: "size"; query: "size/number()" } //wrong type +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleKeys.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleKeys.qml new file mode 100644 index 0000000000..9f667d86e5 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/roleKeys.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + query: "/data/item" + XmlRole { id: nameRole; name: "name"; query: "name/string()"; isKey: true } + XmlRole { name: "age"; query: "age/number()"; isKey: true } + XmlRole { name: "sport"; query: "sport/string()" } + + function disableNameKey() { + nameRole.isKey = false; + } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/testtypes.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/testtypes.qml new file mode 100644 index 0000000000..5ec1ffa35f --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/testtypes.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + query: "/data" + XmlRole { name: "stringValue"; query: "a-string/string()" } + XmlRole { name: "numberValue"; query: "a-number/number()" } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/data/unique.qml b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/unique.qml new file mode 100644 index 0000000000..322a2e4e5c --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/data/unique.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtQuick.XmlListModel 2.0 + +XmlListModel { + source: "model.xml" + query: "/Pets/Pet" + XmlRole { name: "name"; query: "name/string()" } + XmlRole { name: "name"; query: "type/string()" } +} diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro b/tests/auto/qtquick2/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro new file mode 100644 index 0000000000..10944bcb41 --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/qdeclarativexmllistmodel.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qdeclarativexmllistmodel +macx:CONFIG -= app_bundle + +SOURCES += tst_qdeclarativexmllistmodel.cpp +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private network testlib xmlpatterns diff --git a/tests/auto/qtquick2/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/qtquick2/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp new file mode 100644 index 0000000000..316ac50c5e --- /dev/null +++ b/tests/auto/qtquick2/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -0,0 +1,961 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include + +#include +#include +#include +#include "../../../../src/imports/xmllistmodel/qdeclarativexmllistmodel_p.h" + +typedef QPair QDeclarativeXmlListRange; +typedef QList QDeclarativeXmlModelData; + +Q_DECLARE_METATYPE(QList) +Q_DECLARE_METATYPE(QDeclarativeXmlModelData) +Q_DECLARE_METATYPE(QDeclarativeXmlListModel::Status) + +class tst_qdeclarativexmllistmodel : public QObject + +{ + Q_OBJECT +public: + tst_qdeclarativexmllistmodel() {} + +private slots: + void initTestCase() { + qRegisterMetaType(); + } + + void buildModel(); + void testTypes(); + void testTypes_data(); + void cdata(); + void attributes(); + void roles(); + void roleErrors(); + void uniqueRoleNames(); + void headers(); + void xml(); + void xml_data(); + void source(); + void source_data(); + void data(); + void get(); + void reload(); + void useKeys(); + void useKeys_data(); + void noKeysValueChanges(); + void keysChanged(); + void threading(); + void threading_data(); + void propertyChanges(); + + void roleCrash(); + +private: + QString errorString(QListModelInterface* model) { + QString ret; + QMetaObject::invokeMethod(model, "errorString", Q_RETURN_ARG(QString, ret)); + return ret; + } + + QString makeItemXmlAndData(const QString &data, QDeclarativeXmlModelData *modelData = 0) const + { + if (modelData) + modelData->clear(); + QString xml; + + if (!data.isEmpty()) { + QStringList items = data.split(";"); + foreach(const QString &item, items) { + if (item.isEmpty()) + continue; + QVariantList variants; + xml += QLatin1String(""); + QStringList fields = item.split(","); + foreach(const QString &field, fields) { + QStringList values = field.split("="); + if (values.count() != 2) { + qWarning() << "makeItemXmlAndData: invalid field:" << field; + continue; + } + xml += QString("<%1>%2").arg(values[0], values[1]); + if (!modelData) + continue; + bool isNum = false; + int number = values[1].toInt(&isNum); + if (isNum) + variants << number; + else + variants << values[1]; + } + xml += QLatin1String(""); + if (modelData) + modelData->append(variants); + } + } + + QString decl = ""; + return decl + QLatin1String("") + xml + QLatin1String(""); + } + + QDeclarativeEngine engine; +}; + +class CustomNetworkAccessManagerFactory : public QObject, public QDeclarativeNetworkAccessManagerFactory +{ + Q_OBJECT +public: + QVariantMap lastSentHeaders; + +protected: + QNetworkAccessManager *create(QObject *parent); +}; + +class CustomNetworkAccessManager : public QNetworkAccessManager +{ + Q_OBJECT +public: + CustomNetworkAccessManager(CustomNetworkAccessManagerFactory *factory, QObject *parent) + : QNetworkAccessManager(parent), m_factory(factory) {} + +protected: + QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0) + { + if (m_factory) { + QVariantMap map; + foreach (const QString &header, req.rawHeaderList()) + map[header] = req.rawHeader(header.toUtf8()); + m_factory->lastSentHeaders = map; + } + return QNetworkAccessManager::createRequest(op, req, outgoingData); + } + + QPointer m_factory; +}; + +QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent) +{ + return new CustomNetworkAccessManager(this, parent); +} + + +void tst_qdeclarativexmllistmodel::buildModel() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + QCOMPARE(model->data(3, Qt::UserRole).toString(), QLatin1String("Spot")); + QCOMPARE(model->data(3, Qt::UserRole+1).toString(), QLatin1String("Dog")); + QCOMPARE(model->data(3, Qt::UserRole+2).toInt(), 9); + QCOMPARE(model->data(3, Qt::UserRole+3).toString(), QLatin1String("Medium")); + + delete model; +} + +void tst_qdeclarativexmllistmodel::testTypes() +{ + QFETCH(QString, xml); + QFETCH(QString, roleName); + QFETCH(QVariant, expectedValue); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("testtypes.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + model->setProperty("xml",xml.toUtf8()); + QMetaObject::invokeMethod(model, "reload"); + QTRY_COMPARE(model->count(), 1); + + int role = -1; + foreach (int i, model->roles()) { + if (model->toString(i) == roleName) { + role = i; + break; + } + } + QVERIFY(role >= 0); + + if (expectedValue.toString() == "nan") + QVERIFY(qIsNaN(model->data(0, role).toDouble())); + else + QCOMPARE(model->data(0, role), expectedValue); + + delete model; +} + +void tst_qdeclarativexmllistmodel::testTypes_data() +{ + QTest::addColumn("xml"); + QTest::addColumn("roleName"); + QTest::addColumn("expectedValue"); + + QTest::newRow("missing string field") << "" + << "stringValue" << QVariant(""); + QTest::newRow("empty string") << "" + << "stringValue" << QVariant(""); + QTest::newRow("1-char string") << "5" + << "stringValue" << QVariant("5"); + QTest::newRow("string ok") << "abc def g" + << "stringValue" << QVariant("abc def g"); + + QTest::newRow("missing number field") << "" + << "numberValue" << QVariant(""); + double nan = qQNaN(); + QTest::newRow("empty number field") << "" + << "numberValue" << QVariant(nan); + QTest::newRow("number field with string") << "a string" + << "numberValue" << QVariant(nan); + QTest::newRow("-1") << "-1" + << "numberValue" << QVariant("-1"); + QTest::newRow("-1.5") << "-1.5" + << "numberValue" << QVariant("-1.5"); + QTest::newRow("0") << "0" + << "numberValue" << QVariant("0"); + QTest::newRow("+1") << "1" + << "numberValue" << QVariant("1"); + QTest::newRow("+1.5") << "1.5" + << "numberValue" << QVariant("1.5"); +} + +void tst_qdeclarativexmllistmodel::cdata() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 5); + + QVERIFY(model->data(2, Qt::UserRole+2).toString().startsWith(QLatin1String(""))); + + delete model; +} + +void tst_qdeclarativexmllistmodel::attributes() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("recipes.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 5); + QCOMPARE(model->data(2, Qt::UserRole).toString(), QLatin1String("Vegetable Soup")); + + delete model; +} + +void tst_qdeclarativexmllistmodel::roles() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + QList roles = model->roles(); + QCOMPARE(roles.count(), 4); + QCOMPARE(model->toString(roles.at(0)), QLatin1String("name")); + QCOMPARE(model->toString(roles.at(1)), QLatin1String("type")); + QCOMPARE(model->toString(roles.at(2)), QLatin1String("age")); + QCOMPARE(model->toString(roles.at(3)), QLatin1String("size")); + + delete model; +} + +void tst_qdeclarativexmllistmodel::roleErrors() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleErrors.qml"))); + QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":7:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData()); + QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("roleErrors.qml")).toString() + ":10:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData()); + + //### make sure we receive all expected warning messages. + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + + //### should any of these return valid values? + QCOMPARE(model->data(3, Qt::UserRole), QVariant()); + QCOMPARE(model->data(3, Qt::UserRole+1), QVariant()); + QCOMPARE(model->data(3, Qt::UserRole+2), QVariant()); + + QEXPECT_FAIL("", "QTBUG-10797", Continue); + QCOMPARE(model->data(3, Qt::UserRole+3), QVariant()); + + delete model; +} + +void tst_qdeclarativexmllistmodel::uniqueRoleNames() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("unique.qml"))); + QTest::ignoreMessage(QtWarningMsg, (QUrl::fromLocalFile(TESTDATA("unique.qml")).toString() + ":8:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData()); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + QList roles = model->roles(); + QCOMPARE(roles.count(), 1); + + delete model; +} + + +void tst_qdeclarativexmllistmodel::xml() +{ + QFETCH(QString, xml); + QFETCH(int, count); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + + QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status))); + QVERIFY(errorString(model).isEmpty()); + QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Loading); + QTRY_COMPARE(spy.count(), 1); spy.clear(); + QTest::qWait(50); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Ready); + QVERIFY(errorString(model).isEmpty()); + QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); + QCOMPARE(model->count(), 9); + + // if xml is empty (i.e. clearing) it won't have any effect if a source is set + if (xml.isEmpty()) + model->setProperty("source",QUrl()); + model->setProperty("xml",xml); + QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); // immediately goes to 1.0 if using setXml() + QTRY_COMPARE(spy.count(), 1); spy.clear(); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Loading); + QTRY_COMPARE(spy.count(), 1); spy.clear(); + if (xml.isEmpty()) + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Null); + else + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Ready); + QVERIFY(errorString(model).isEmpty()); + QCOMPARE(model->count(), count); + + delete model; +} + +void tst_qdeclarativexmllistmodel::xml_data() +{ + QTest::addColumn("xml"); + QTest::addColumn("count"); + + QTest::newRow("xml with no items") << "" << 0; + QTest::newRow("empty xml") << "" << 0; + QTest::newRow("one item") << "HobbesTiger7Large" << 1; +} + +void tst_qdeclarativexmllistmodel::headers() +{ + // ensure the QNetworkAccessManagers created for this test are immediately deleted + QDeclarativeEngine qmlEng; + + CustomNetworkAccessManagerFactory factory; + qmlEng.setNetworkAccessManagerFactory(&factory); + + QDeclarativeComponent component(&qmlEng, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Ready); + + QVariantMap expectedHeaders; + expectedHeaders["Accept"] = "application/xml,*/*"; + + QCOMPARE(factory.lastSentHeaders.count(), expectedHeaders.count()); + foreach (const QString &header, expectedHeaders.keys()) { + QVERIFY(factory.lastSentHeaders.contains(header)); + QCOMPARE(factory.lastSentHeaders[header].toString(), expectedHeaders[header].toString()); + } + + delete model; +} + +void tst_qdeclarativexmllistmodel::source() +{ + QFETCH(QUrl, source); + QFETCH(int, count); + QFETCH(QDeclarativeXmlListModel::Status, status); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QSignalSpy spy(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status))); + + QVERIFY(errorString(model).isEmpty()); + QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Loading); + QTRY_COMPARE(spy.count(), 1); spy.clear(); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Ready); + QVERIFY(errorString(model).isEmpty()); + QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); + QCOMPARE(model->count(), 9); + + model->setProperty("source",source); + if (model->property("source").toString().isEmpty()) + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Null); + QCOMPARE(model->property("progress").toDouble(), qreal(0.0)); + QTRY_COMPARE(spy.count(), 1); spy.clear(); + QCOMPARE(qvariant_cast(model->property("status")), + QDeclarativeXmlListModel::Loading); + QVERIFY(errorString(model).isEmpty()); + + QEventLoop loop; + QTimer timer; + timer.setSingleShot(true); + connect(model, SIGNAL(statusChanged(QDeclarativeXmlListModel::Status)), &loop, SLOT(quit())); + connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); + timer.start(20000); + loop.exec(); + + if (spy.count() == 0 && status != QDeclarativeXmlListModel::Ready) { + qWarning("QDeclarativeXmlListModel invalid source test timed out"); + } else { + QCOMPARE(spy.count(), 1); spy.clear(); + } + + QCOMPARE(qvariant_cast(model->property("status")), status); + QCOMPARE(model->count(), count); + + if (status == QDeclarativeXmlListModel::Ready) + QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); + + QCOMPARE(errorString(model).isEmpty(), status == QDeclarativeXmlListModel::Ready); + + delete model; +} + +void tst_qdeclarativexmllistmodel::source_data() +{ + QTest::addColumn("source"); + QTest::addColumn("count"); + QTest::addColumn("status"); + + QTest::newRow("valid") << QUrl::fromLocalFile(TESTDATA("model2.xml")) << 2 + << QDeclarativeXmlListModel::Ready; + QTest::newRow("invalid") << QUrl("http://blah.blah/blah.xml") << 0 + << QDeclarativeXmlListModel::Error; + + // empty file + QTemporaryFile *temp = new QTemporaryFile(this); + if (temp->open()) + QTest::newRow("empty file") << QUrl::fromLocalFile(temp->fileName()) << 0 + << QDeclarativeXmlListModel::Ready; + temp->close(); +} + +void tst_qdeclarativexmllistmodel::data() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + + for (int i=0; i<9; i++) { + for (int j=0; jroles().count(); j++) { + QCOMPARE(model->data(i, j), QVariant()); + } + } + QTRY_COMPARE(model->count(), 9); + + delete model; +} + +void tst_qdeclarativexmllistmodel::get() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("get.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + + QVERIFY(model != 0); + + QVERIFY(QMetaObject::invokeMethod(model, "runPreTest")); + QCOMPARE(model->property("preTest").toBool(), true); + + QTRY_COMPARE(model->count(), 9); + + QVERIFY(QMetaObject::invokeMethod(model, "runPostTest")); + QCOMPARE(model->property("postTest").toBool(), true); + + delete model; +} + +void tst_qdeclarativexmllistmodel::reload() +{ + // If no keys are used, the model should be rebuilt from scratch when + // reload() is called. + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("model.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); + QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); + QSignalSpy spyCount(model, SIGNAL(countChanged())); + //reload multiple times to test the xml query aborting + QMetaObject::invokeMethod(model, "reload"); + QMetaObject::invokeMethod(model, "reload"); + QCoreApplication::processEvents(); + QMetaObject::invokeMethod(model, "reload"); + QMetaObject::invokeMethod(model, "reload"); + QTRY_COMPARE(spyCount.count(), 1); + QTRY_COMPARE(spyInsert.count(), 1); + QTRY_COMPARE(spyRemove.count(), 1); + + QCOMPARE(spyInsert[0][0].toInt(), 0); + QCOMPARE(spyInsert[0][1].toInt(), 9); + + QCOMPARE(spyRemove[0][0].toInt(), 0); + QCOMPARE(spyRemove[0][1].toInt(), 9); + + delete model; +} + +void tst_qdeclarativexmllistmodel::useKeys() +{ + // If using incremental updates through keys, the model should only + // insert & remove some of the items, instead of throwing everything + // away and causing the view to repaint the whole view. + + QFETCH(QString, oldXml); + QFETCH(int, oldCount); + QFETCH(QString, newXml); + QFETCH(QDeclarativeXmlModelData, newData); + QFETCH(QList, insertRanges); + QFETCH(QList, removeRanges); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + + model->setProperty("xml",oldXml); + QTRY_COMPARE(model->count(), oldCount); + + QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); + QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); + QSignalSpy spyCount(model, SIGNAL(countChanged())); + + model->setProperty("xml",newXml); + + if (oldCount != newData.count()) { + QTRY_COMPARE(model->count(), newData.count()); + QCOMPARE(spyCount.count(), 1); + } else { + QTRY_VERIFY(spyInsert.count() > 0 || spyRemove.count() > 0); + QCOMPARE(spyCount.count(), 0); + } + + QList roles = model->roles(); + for (int i=0; icount(); i++) { + for (int j=0; jdata(i, roles[j]), newData[i][j]); + } + + QCOMPARE(spyInsert.count(), insertRanges.count()); + for (int i=0; i("oldXml"); + QTest::addColumn("oldCount"); + QTest::addColumn("newXml"); + QTest::addColumn("newData"); + QTest::addColumn >("insertRanges"); + QTest::addColumn >("removeRanges"); + + QDeclarativeXmlModelData modelData; + + QTest::newRow("append 1") + << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics", &modelData) + << modelData + << (QList() << qMakePair(1, 1)) + << QList(); + + QTest::newRow("append multiple") + << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData) + << modelData + << (QList() << qMakePair(1, 2)) + << QList(); + + QTest::newRow("insert in different spots") + << makeItemXmlAndData("name=B,age=35,sport=Athletics") << 1 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) + << modelData + << (QList() << qMakePair(0, 1) << qMakePair(2,2)) + << QList(); + + QTest::newRow("insert in middle") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=D,age=55,sport=Golf") << 2 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) + << modelData + << (QList() << qMakePair(1, 2)) + << QList(); + + QTest::newRow("remove first") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2 + << makeItemXmlAndData("name=B,age=35,sport=Athletics", &modelData) + << modelData + << QList() + << (QList() << qMakePair(0, 1)); + + QTest::newRow("remove last") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2 + << makeItemXmlAndData("name=A,age=25,sport=Football", &modelData) + << modelData + << QList() + << (QList() << qMakePair(1, 1)); + + QTest::newRow("remove from multiple spots") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 5 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=C,age=45,sport=Curling", &modelData) + << modelData + << QList() + << (QList() << qMakePair(1, 1) << qMakePair(3,2)); + + QTest::newRow("remove all") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3 + << makeItemXmlAndData("", &modelData) + << modelData + << QList() + << (QList() << qMakePair(0, 3)); + + QTest::newRow("replace item") + << makeItemXmlAndData("name=A,age=25,sport=Football") << 1 + << makeItemXmlAndData("name=ZZZ,age=25,sport=Football", &modelData) + << modelData + << (QList() << qMakePair(0, 1)) + << (QList() << qMakePair(0, 1)); + + QTest::newRow("add and remove simultaneously, in different spots") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf") << 4 + << makeItemXmlAndData("name=B,age=35,sport=Athletics;name=E,age=65,sport=Fencing", &modelData) + << modelData + << (QList() << qMakePair(1, 1)) + << (QList() << qMakePair(0, 1) << qMakePair(2,2)); + + QTest::newRow("insert at start, remove at end i.e. rss feed") + << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 3 + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData) + << modelData + << (QList() << qMakePair(0, 2)) + << (QList() << qMakePair(1, 2)); + + QTest::newRow("remove at start, insert at end") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3 + << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing", &modelData) + << modelData + << (QList() << qMakePair(1, 2)) + << (QList() << qMakePair(0, 2)); + + QTest::newRow("all data has changed") + << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35") << 2 + << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData) + << modelData + << (QList() << qMakePair(0, 2)) + << (QList() << qMakePair(0, 2)); +} + +void tst_qdeclarativexmllistmodel::noKeysValueChanges() +{ + // The 'key' roles are 'name' and 'age', as defined in roleKeys.qml. + // If a 'sport' value is changed, the model should not be reloaded, + // since 'sport' is not marked as a key. + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + + QString xml; + + xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics"); + model->setProperty("xml",xml); + QTRY_COMPARE(model->count(), 2); + + model->setProperty("xml",""); + + QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); + QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); + QSignalSpy spyCount(model, SIGNAL(countChanged())); + + xml = makeItemXmlAndData("name=A,age=25,sport=AussieRules;name=B,age=35,sport=Athletics"); + model->setProperty("xml",xml); + + // wait for the new xml data to be set, and verify no signals were emitted + QTRY_VERIFY(model->data(0, model->roles()[2]).toString() != QLatin1String("Football")); + QCOMPARE(model->data(0, model->roles()[2]).toString(), QLatin1String("AussieRules")); + + QVERIFY(spyInsert.count() == 0); + QVERIFY(spyRemove.count() == 0); + QVERIFY(spyCount.count() == 0); + + QCOMPARE(model->count(), 2); + + delete model; +} + +void tst_qdeclarativexmllistmodel::keysChanged() +{ + // If the key roles change, the next time the data is reloaded, it should + // delete all its data and build a clean model (i.e. same behaviour as + // if no keys are set). + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + + QString xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics"); + model->setProperty("xml",xml); + QTRY_COMPARE(model->count(), 2); + + model->setProperty("xml",""); + + QSignalSpy spyInsert(model, SIGNAL(itemsInserted(int,int))); + QSignalSpy spyRemove(model, SIGNAL(itemsRemoved(int,int))); + QSignalSpy spyCount(model, SIGNAL(countChanged())); + + QVERIFY(QMetaObject::invokeMethod(model, "disableNameKey")); + model->setProperty("xml",xml); + + QTRY_VERIFY(spyInsert.count() > 0 && spyRemove.count() > 0); + + QCOMPARE(spyInsert.count(), 1); + QCOMPARE(spyInsert[0][0].toInt(), 0); + QCOMPARE(spyInsert[0][1].toInt(), 2); + + QCOMPARE(spyRemove.count(), 1); + QCOMPARE(spyRemove[0][0].toInt(), 0); + QCOMPARE(spyRemove[0][1].toInt(), 2); + + QCOMPARE(spyCount.count(), 0); + + delete model; +} + +void tst_qdeclarativexmllistmodel::threading() +{ + QFETCH(int, xmlDataCount); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleKeys.qml"))); + + QListModelInterface *m1 = qobject_cast(component.create()); + QVERIFY(m1 != 0); + QListModelInterface *m2 = qobject_cast(component.create()); + QVERIFY(m2 != 0); + QListModelInterface *m3 = qobject_cast(component.create()); + QVERIFY(m3 != 0); + + for (int dataCount=0; dataCountsetProperty("xml",makeItemXmlAndData(data1)); + m2->setProperty("xml",makeItemXmlAndData(data2)); + m3->setProperty("xml",makeItemXmlAndData(data3)); + QCoreApplication::processEvents(); + m2->setProperty("xml",makeItemXmlAndData(data2)); + m1->setProperty("xml",makeItemXmlAndData(data1)); + m2->setProperty("xml",makeItemXmlAndData(data2)); + QCoreApplication::processEvents(); + m3->setProperty("xml",makeItemXmlAndData(data3)); + QCoreApplication::processEvents(); + m2->setProperty("xml",makeItemXmlAndData(data2)); + m1->setProperty("xml",makeItemXmlAndData(data1)); + m2->setProperty("xml",makeItemXmlAndData(data2)); + m3->setProperty("xml",makeItemXmlAndData(data3)); + QCoreApplication::processEvents(); + m2->setProperty("xml",makeItemXmlAndData(data2)); + m3->setProperty("xml",makeItemXmlAndData(data3)); + m3->setProperty("xml",makeItemXmlAndData(data3)); + QCoreApplication::processEvents(); + + QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount); + + for (int i=0; idata(i, m1->roles()[0]).toString(), QString("A" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[1]).toString(), QString("1" + QString::number(i))); + QCOMPARE(m1->data(i, m1->roles()[2]).toString(), QString("Football")); + + QCOMPARE(m2->data(i, m2->roles()[0]).toString(), QString("B" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[1]).toString(), QString("2" + QString::number(i))); + QCOMPARE(m2->data(i, m2->roles()[2]).toString(), QString("Athletics")); + + QCOMPARE(m3->data(i, m3->roles()[0]).toString(), QString("C" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[1]).toString(), QString("3" + QString::number(i))); + QCOMPARE(m3->data(i, m3->roles()[2]).toString(), QString("Curling")); + } + } + + delete m1; + delete m2; + delete m3; +} + +void tst_qdeclarativexmllistmodel::threading_data() +{ + QTest::addColumn("xmlDataCount"); + + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; + QTest::newRow("10") << 10; +} + +void tst_qdeclarativexmllistmodel::propertyChanges() +{ + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + QTRY_COMPARE(model->count(), 9); + + QObject *role = model->findChild("role"); + QVERIFY(role); + + QSignalSpy nameSpy(role, SIGNAL(nameChanged())); + QSignalSpy querySpy(role, SIGNAL(queryChanged())); + QSignalSpy isKeySpy(role, SIGNAL(isKeyChanged())); + + role->setProperty("name","size"); + role->setProperty("query","size/string()"); + role->setProperty("isKey",true); + + QCOMPARE(role->property("name").toString(), QString("size")); + QCOMPARE(role->property("query").toString(), QString("size/string()")); + QVERIFY(role->property("isKey").toBool()); + + QCOMPARE(nameSpy.count(),1); + QCOMPARE(querySpy.count(),1); + QCOMPARE(isKeySpy.count(),1); + + role->setProperty("name","size"); + role->setProperty("query","size/string()"); + role->setProperty("isKey",true); + + QCOMPARE(nameSpy.count(),1); + QCOMPARE(querySpy.count(),1); + QCOMPARE(isKeySpy.count(),1); + + QSignalSpy sourceSpy(model, SIGNAL(sourceChanged())); + QSignalSpy xmlSpy(model, SIGNAL(xmlChanged())); + QSignalSpy modelQuerySpy(model, SIGNAL(queryChanged())); + QSignalSpy namespaceDeclarationsSpy(model, SIGNAL(namespaceDeclarationsChanged())); + + model->setProperty("source",QUrl("")); + model->setProperty("xml","PollyParrot12Small"); + model->setProperty("query","/Pets"); + model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";"); + + QCOMPARE(model->property("source").toUrl(), QUrl("")); + QCOMPARE(model->property("xml").toString(), QString("PollyParrot12Small")); + QCOMPARE(model->property("query").toString(), QString("/Pets")); + QCOMPARE(model->property("namespaceDeclarations").toString(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";")); + + QTRY_VERIFY(model->count() == 1); + + QCOMPARE(sourceSpy.count(),1); + QCOMPARE(xmlSpy.count(),1); + QCOMPARE(modelQuerySpy.count(),1); + QCOMPARE(namespaceDeclarationsSpy.count(),1); + + model->setProperty("source",QUrl("")); + model->setProperty("xml","PollyParrot12Small"); + model->setProperty("query","/Pets"); + model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";"); + + QCOMPARE(sourceSpy.count(),1); + QCOMPARE(xmlSpy.count(),1); + QCOMPARE(modelQuerySpy.count(),1); + QCOMPARE(namespaceDeclarationsSpy.count(),1); + + QTRY_VERIFY(model->count() == 1); + delete model; +} + +void tst_qdeclarativexmllistmodel::roleCrash() +{ + // don't crash + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("roleCrash.qml"))); + QListModelInterface *model = qobject_cast(component.create()); + QVERIFY(model != 0); + delete model; +} + +QTEST_MAIN(tst_qdeclarativexmllistmodel) + +#include "tst_qdeclarativexmllistmodel.moc" diff --git a/tests/auto/qtquick2/qquickanchors/data/anchors.qml b/tests/auto/qtquick2/qquickanchors/data/anchors.qml new file mode 100644 index 0000000000..4be49a3468 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/anchors.qml @@ -0,0 +1,162 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 240 + height: 320 + Rectangle { id: masterRect; objectName: "masterRect"; x: 26; width: 96; height: 20; color: "red" } + Rectangle { + id: rect1; objectName: "rect1" + y: 20; width: 10; height: 10 + anchors.left: masterRect.left + } + Rectangle { + id: rect2; objectName: "rect2" + y: 20; width: 10; height: 10 + anchors.left: masterRect.right + } + Rectangle { + id: rect3; objectName: "rect3" + y: 20; width: 10; height: 10 + anchors.left: masterRect.horizontalCenter + } + Rectangle { + id: rect4; objectName: "rect4" + y: 30; width: 10; height: 10 + anchors.right: masterRect.left + } + Rectangle { + id: rect5; objectName: "rect5" + y: 30; width: 10; height: 10 + anchors.right: masterRect.right + } + Rectangle { + id: rect6; objectName: "rect6" + y: 30; width: 10; height: 10 + anchors.right: masterRect.horizontalCenter + } + Rectangle { + id: rect7; objectName: "rect7" + y: 50; width: 10; height: 10 + anchors.left: parent.left + } + Rectangle { + id: rect8; objectName: "rect8" + y: 50; width: 10; height: 10 + anchors.left: parent.right + } + Rectangle { + id: rect9; objectName: "rect9" + y: 50; width: 10; height: 10 + anchors.left: parent.horizontalCenter + } + Rectangle { + id: rect10; objectName: "rect10" + y: 60; width: 10; height: 10 + anchors.right: parent.left + } + Rectangle { + id: rect11; objectName: "rect11" + y: 60; width: 10; height: 10 + anchors.right: parent.right + } + Rectangle { + id: rect12; objectName: "rect12" + y: 60; width: 10; height: 10 + anchors.right: parent.horizontalCenter + } + Rectangle { + id: rect13; objectName: "rect13" + x: 200; width: 10; height: 10 + anchors.top: masterRect.bottom + } + Rectangle { + id: rect14; objectName: "rect14" + width: 10; height: 10; color: "steelblue" + anchors.verticalCenter: parent.verticalCenter + } + Rectangle { + id: rect15; objectName: "rect15" + y: 200; height: 10 + anchors.left: masterRect.left + anchors.right: masterRect.right + } + Rectangle { + id: rect16; objectName: "rect16" + y: 220; height: 10 + anchors.left: masterRect.left + anchors.horizontalCenter: masterRect.right + } + Rectangle { + id: rect17; objectName: "rect17" + y: 240; height: 10 + anchors.right: masterRect.right + anchors.horizontalCenter: masterRect.left + } + Rectangle { + id: rect18; objectName: "rect18" + x: 180; width: 10 + anchors.top: masterRect.bottom + anchors.bottom: rect12.top + } + Rectangle { + id: rect19; objectName: "rect19" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.horizontalCenter + } + Rectangle { + id: rect20; objectName: "rect20" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.right + } + Rectangle { + id: rect21; objectName: "rect21" + y: 70; width: 10; height: 10 + anchors.horizontalCenter: parent.left + } + Rectangle { + id: rect22; objectName: "rect22" + width: 10; height: 10 + anchors.centerIn: masterRect + } + Rectangle { + id: rect23; objectName: "rect23" + anchors.left: masterRect.left + anchors.leftMargin: 5 + anchors.right: masterRect.right + anchors.rightMargin: 5 + anchors.top: masterRect.top + anchors.topMargin: 5 + anchors.bottom: masterRect.bottom + anchors.bottomMargin: 5 + } + Rectangle { + id: rect24; objectName: "rect24" + width: 10; height: 10 + anchors.horizontalCenter: masterRect.left + anchors.horizontalCenterOffset: width/2 + } + Rectangle { + id: rect25; objectName: "rect25" + width: 10; height: 10 + anchors.verticalCenter: rect12.top + anchors.verticalCenterOffset: height/2 + } + Rectangle { + id: rect26; objectName: "rect26" + width: 10; height: 10 + anchors.baseline: masterRect.top + anchors.baselineOffset: height/2 + } + Text { + id: text1; objectName: "text1" + y: 200; + text: "Hello" + } + Text { + id: text2; objectName: "text2" + anchors.baseline: text1.baseline + anchors.left: text1.right + text: "World" + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/centerin.qml b/tests/auto/qtquick2/qquickanchors/data/centerin.qml new file mode 100644 index 0000000000..e5f64f1e47 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/centerin.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + objectName: "centered" + width: 50; height: 50; color: "blue" + anchors.centerIn: parent; + anchors.verticalCenterOffset: 30 + anchors.horizontalCenterOffset: 10 + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/centerinRotation.qml b/tests/auto/qtquick2/qquickanchors/data/centerinRotation.qml new file mode 100644 index 0000000000..933a25c100 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/centerinRotation.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + objectName: "outer" + rotation: 90 + width: 101; height: 101; color: "blue" + anchors.centerIn: parent; + + Rectangle { + objectName: "inner" + width: 50; height: 50; color: "blue" + anchors.centerIn: parent; + } + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/crash1.qml b/tests/auto/qtquick2/qquickanchors/data/crash1.qml new file mode 100644 index 0000000000..98dd6cfa41 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/crash1.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Column { + Text { + text: "foo" + anchors.fill: parent + } + Text { + text: "bar" + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/fill.qml b/tests/auto/qtquick2/qquickanchors/data/fill.qml new file mode 100644 index 0000000000..08db199d7b --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/fill.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + objectName: "filler" + width: 50; height: 50; color: "blue" + anchors.fill: parent; + anchors.leftMargin: 10; + anchors.rightMargin: 20; + anchors.topMargin: 30; + anchors.bottomMargin: 40; + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/hvCenter.qml b/tests/auto/qtquick2/qquickanchors/data/hvCenter.qml new file mode 100644 index 0000000000..6763f8eb75 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/hvCenter.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 77; height: 95 + Rectangle { + objectName: "centered" + width: 57; height: 57; color: "blue" + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/loop1.qml b/tests/auto/qtquick2/qquickanchors/data/loop1.qml new file mode 100644 index 0000000000..342b2af052 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/loop1.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Rectangle { + id: rect + width: 120; height: 200; color: "white" + Text { id: text1; anchors.right: text2.right; text: "Hello" } + Text { id: text2; anchors.right: text1.right; anchors.rightMargin: 10; text: "World" } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/loop2.qml b/tests/auto/qtquick2/qquickanchors/data/loop2.qml new file mode 100644 index 0000000000..e1875be025 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/loop2.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Rectangle { + id: container; + width: 600; + height: 600; + + Image { + id: image1 + source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/3311388091_ac2a257feb.jpg" + anchors.right: image2.left + } + + Image { + id: image2 + source: "http://labs.trolltech.com/blogs/wp-content/uploads/2009/03/oslo_groupphoto.jpg" + anchors.left: image1.right + anchors.leftMargin: 20 + } +} diff --git a/tests/auto/qtquick2/qquickanchors/data/margins.qml b/tests/auto/qtquick2/qquickanchors/data/margins.qml new file mode 100644 index 0000000000..9403f65a61 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/data/margins.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 200 + Rectangle { + objectName: "filler" + width: 50; height: 50; color: "blue" + anchors.fill: parent; + anchors.margins: 10 + anchors.leftMargin: 5 + anchors.topMargin: 6 + } +} diff --git a/tests/auto/qtquick2/qquickanchors/qquickanchors.pro b/tests/auto/qtquick2/qquickanchors/qquickanchors.pro new file mode 100644 index 0000000000..92f24cff07 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/qquickanchors.pro @@ -0,0 +1,12 @@ +TARGET = tst_qquickanchors +CONFIG += testcase +SOURCES += tst_qquickanchors.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private v8-private testlib diff --git a/tests/auto/qtquick2/qquickanchors/tst_qquickanchors.cpp b/tests/auto/qtquick2/qquickanchors/tst_qquickanchors.cpp new file mode 100644 index 0000000000..cae1421573 --- /dev/null +++ b/tests/auto/qtquick2/qquickanchors/tst_qquickanchors.cpp @@ -0,0 +1,692 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +Q_DECLARE_METATYPE(QQuickAnchors::Anchor) +Q_DECLARE_METATYPE(QQuickAnchorLine::AnchorLine) + +class tst_qquickanchors : public QObject +{ + Q_OBJECT +public: + tst_qquickanchors() {} + +private slots: + void basicAnchors(); + void basicAnchorsRTL(); + void loops(); + void illegalSets(); + void illegalSets_data(); + void reset(); + void reset_data(); + void resetConvenience(); + void nullItem(); + void nullItem_data(); + void crash1(); + void centerIn(); + void centerInRTL(); + void centerInRotation(); + void hvCenter(); + void hvCenterRTL(); + void fill(); + void fillRTL(); + void margins(); + void marginsRTL(); +}; + +/* + Find an item with the specified objectName. +*/ +template +T *findItem(QQuickItem *parent, const QString &objectName) +{ + if (!parent) + return 0; + + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->QQuickItem::children().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) + return static_cast(item); + item = findItem(item, objectName); + if (item) + return static_cast(item); + } + + return 0; +} + +void tst_qquickanchors::basicAnchors() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml"))); + + qApp->processEvents(); + + //sibling horizontal + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect1"))->x(), 26.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect2"))->x(), 122.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect3"))->x(), 74.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect4"))->x(), 16.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect5"))->x(), 112.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect6"))->x(), 64.0); + + //parent horizontal + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect7"))->x(), 0.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect8"))->x(), 240.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect9"))->x(), 120.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect10"))->x(), -10.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect11"))->x(), 230.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect12"))->x(), 110.0); + + //vertical + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect13"))->y(), 20.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect14"))->y(), 155.0); + + //stretch + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect15"))->x(), 26.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect15"))->width(), 96.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect16"))->x(), 26.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect16"))->width(), 192.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect17"))->x(), -70.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect17"))->width(), 192.0); + + //vertical stretch + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect18"))->y(), 20.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect18"))->height(), 40.0); + + //more parent horizontal + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect19"))->x(), 115.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect20"))->x(), 235.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect21"))->x(), -5.0); + + //centerIn + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect22"))->x(), 69.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect22"))->y(), 5.0); + + //margins + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->x(), 31.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->y(), 5.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->width(), 86.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect23"))->height(), 10.0); + + // offsets + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect24"))->x(), 26.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect25"))->y(), 60.0); + QCOMPARE(findItem(view->rootObject(), QLatin1String("rect26"))->y(), 5.0); + + //baseline + QQuickText *text1 = findItem(view->rootObject(), QLatin1String("text1")); + QQuickText *text2 = findItem(view->rootObject(), QLatin1String("text2")); + QCOMPARE(text1->y(), text2->y()); + + delete view; +} + +QQuickItem* childItem(QQuickItem *parentItem, const char * itemString) { + return findItem(parentItem, QLatin1String(itemString)); +} + +qreal offsetMasterRTL(QQuickItem *rootItem, const char * itemString) { + QQuickItem* masterItem = findItem(rootItem, QLatin1String("masterRect")); + return masterItem->width()+2*masterItem->x()-findItem(rootItem, QLatin1String(itemString))->width(); +} + +qreal offsetParentRTL(QQuickItem *rootItem, const char * itemString) { + return rootItem->width()+2*rootItem->x()-findItem(rootItem, QLatin1String(itemString))->width(); +} + +void mirrorAnchors(QQuickItem *item) { + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + itemPrivate->setLayoutMirror(true); +} + +void tst_qquickanchors::basicAnchorsRTL() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("anchors.qml"))); + + qApp->processEvents(); + + QQuickItem* rootItem = qobject_cast(view->rootObject()); + foreach (QObject *child, rootItem->children()) { + bool mirrored = QQuickItemPrivate::get(qobject_cast(child))->anchors()->property("mirrored").toBool(); + QCOMPARE(mirrored, false); + } + + foreach (QObject *child, rootItem->children()) + mirrorAnchors(qobject_cast(child)); + + foreach (QObject *child, rootItem->children()) { + bool mirrored = QQuickItemPrivate::get(qobject_cast(child))->anchors()->property("mirrored").toBool(); + QCOMPARE(mirrored, true); + } + + //sibling horizontal + QCOMPARE(childItem(rootItem, "rect1")->x(), offsetMasterRTL(rootItem, "rect1")-26.0); + QCOMPARE(childItem(rootItem, "rect2")->x(), offsetMasterRTL(rootItem, "rect2")-122.0); + QCOMPARE(childItem(rootItem, "rect3")->x(), offsetMasterRTL(rootItem, "rect3")-74.0); + QCOMPARE(childItem(rootItem, "rect4")->x(), offsetMasterRTL(rootItem, "rect4")-16.0); + QCOMPARE(childItem(rootItem, "rect5")->x(), offsetMasterRTL(rootItem, "rect5")-112.0); + QCOMPARE(childItem(rootItem, "rect6")->x(), offsetMasterRTL(rootItem, "rect6")-64.0); + + //parent horizontal + QCOMPARE(childItem(rootItem, "rect7")->x(), offsetParentRTL(rootItem, "rect7")-0.0); + QCOMPARE(childItem(rootItem, "rect8")->x(), offsetParentRTL(rootItem, "rect8")-240.0); + QCOMPARE(childItem(rootItem, "rect9")->x(), offsetParentRTL(rootItem, "rect9")-120.0); + QCOMPARE(childItem(rootItem, "rect10")->x(), offsetParentRTL(rootItem, "rect10")+10.0); + QCOMPARE(childItem(rootItem, "rect11")->x(), offsetParentRTL(rootItem, "rect11")-230.0); + QCOMPARE(childItem(rootItem, "rect12")->x(), offsetParentRTL(rootItem, "rect12")-110.0); + + //vertical + QCOMPARE(childItem(rootItem, "rect13")->y(), 20.0); + QCOMPARE(childItem(rootItem, "rect14")->y(), 155.0); + + //stretch + QCOMPARE(childItem(rootItem, "rect15")->x(), offsetMasterRTL(rootItem, "rect15")-26.0); + QCOMPARE(childItem(rootItem, "rect15")->width(), 96.0); + QCOMPARE(childItem(rootItem, "rect16")->x(), offsetMasterRTL(rootItem, "rect16")-26.0); + QCOMPARE(childItem(rootItem, "rect16")->width(), 192.0); + QCOMPARE(childItem(rootItem, "rect17")->x(), offsetMasterRTL(rootItem, "rect17")+70.0); + QCOMPARE(childItem(rootItem, "rect17")->width(), 192.0); + + //vertical stretch + QCOMPARE(childItem(rootItem, "rect18")->y(), 20.0); + QCOMPARE(childItem(rootItem, "rect18")->height(), 40.0); + + //more parent horizontal + QCOMPARE(childItem(rootItem, "rect19")->x(), offsetParentRTL(rootItem, "rect19")-115.0); + QCOMPARE(childItem(rootItem, "rect20")->x(), offsetParentRTL(rootItem, "rect20")-235.0); + QCOMPARE(childItem(rootItem, "rect21")->x(), offsetParentRTL(rootItem, "rect21")+5.0); + + //centerIn + QCOMPARE(childItem(rootItem, "rect22")->x(), offsetMasterRTL(rootItem, "rect22")-69.0); + QCOMPARE(childItem(rootItem, "rect22")->y(), 5.0); + + //margins + QCOMPARE(childItem(rootItem, "rect23")->x(), offsetMasterRTL(rootItem, "rect23")-31.0); + QCOMPARE(childItem(rootItem, "rect23")->y(), 5.0); + QCOMPARE(childItem(rootItem, "rect23")->width(), 86.0); + QCOMPARE(childItem(rootItem, "rect23")->height(), 10.0); + + // offsets + QCOMPARE(childItem(rootItem, "rect24")->x(), offsetMasterRTL(rootItem, "rect24")-26.0); + QCOMPARE(childItem(rootItem, "rect25")->y(), 60.0); + QCOMPARE(childItem(rootItem, "rect26")->y(), 5.0); + + //baseline + QQuickText *text1 = findItem(rootItem, QLatin1String("text1")); + QQuickText *text2 = findItem(rootItem, QLatin1String("text2")); + QCOMPARE(text1->y(), text2->y()); + + delete view; +} + +// mostly testing that we don't crash +void tst_qquickanchors::loops() +{ + { + QUrl source(QUrl::fromLocalFile(TESTDATA("loop1.qml"))); + + QString expect = source.toString() + ":6:5: QML Text: Possible anchor loop detected on horizontal anchor."; + QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); + QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); + + QQuickView *view = new QQuickView; + view->setSource(source); + qApp->processEvents(); + + delete view; + } + + { + QUrl source(QUrl::fromLocalFile(TESTDATA("loop2.qml"))); + + QString expect = source.toString() + ":8:3: QML Image: Possible anchor loop detected on horizontal anchor."; + QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); + + QQuickView *view = new QQuickView; + view->setSource(source); + qApp->processEvents(); + + delete view; + } +} + +void tst_qquickanchors::illegalSets() +{ + QFETCH(QString, qml); + QFETCH(QString, warning); + + QTest::ignoreMessage(QtWarningMsg, warning.toLatin1()); + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 1.0\n" + qml.toUtf8()), QUrl::fromLocalFile("")); + if (!component.isReady()) + qWarning() << "Test errors:" << component.errors(); + QVERIFY(component.isReady()); + QObject *o = component.create(); + delete o; +} + +void tst_qquickanchors::illegalSets_data() +{ + QTest::addColumn("qml"); + QTest::addColumn("warning"); + + QTest::newRow("H - too many anchors") + << "Rectangle { id: rect; Rectangle { anchors.left: rect.left; anchors.right: rect.right; anchors.horizontalCenter: rect.horizontalCenter } }" + << "file::2:23: QML Rectangle: Cannot specify left, right, and hcenter anchors."; + + foreach (const QString &side, QStringList() << "left" << "right") { + QTest::newRow("H - anchor to V") + << QString("Rectangle { Rectangle { anchors.%1: parent.top } }").arg(side) + << "file::2:13: QML Rectangle: Cannot anchor a horizontal edge to a vertical edge."; + + QTest::newRow("H - anchor to non parent/sibling") + << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) + << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; + + QTest::newRow("H - anchor to self") + << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) + << "file::2:1: QML Rectangle: Cannot anchor item to self."; + } + + + QTest::newRow("V - too many anchors") + << "Rectangle { id: rect; Rectangle { anchors.top: rect.top; anchors.bottom: rect.bottom; anchors.verticalCenter: rect.verticalCenter } }" + << "file::2:23: QML Rectangle: Cannot specify top, bottom, and vcenter anchors."; + + QTest::newRow("V - too many anchors with baseline") + << "Rectangle { Text { id: text1; text: \"Hello\" } Text { anchors.baseline: text1.baseline; anchors.top: text1.top; } }" + << "file::2:47: QML Text: Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors."; + + foreach (const QString &side, QStringList() << "top" << "bottom" << "baseline") { + + QTest::newRow("V - anchor to H") + << QString("Rectangle { Rectangle { anchors.%1: parent.left } }").arg(side) + << "file::2:13: QML Rectangle: Cannot anchor a vertical edge to a horizontal edge."; + + QTest::newRow("V - anchor to non parent/sibling") + << QString("Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.%1: rect.%1 } }").arg(side) + << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; + + QTest::newRow("V - anchor to self") + << QString("Rectangle { id: rect; anchors.%1: rect.%1 }").arg(side) + << "file::2:1: QML Rectangle: Cannot anchor item to self."; + } + + + QTest::newRow("centerIn - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.centerIn: rect} }" + << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; + + + QTest::newRow("fill - anchor to non parent/sibling") + << "Rectangle { Item { Rectangle { id: rect } } Rectangle { anchors.fill: rect} }" + << "file::2:45: QML Rectangle: Cannot anchor to an item that isn't a parent or sibling."; +} + +void tst_qquickanchors::reset() +{ + QFETCH(QString, side); + QFETCH(QQuickAnchorLine::AnchorLine, anchorLine); + QFETCH(QQuickAnchors::Anchor, usedAnchor); + + QQuickItem *baseItem = new QQuickItem; + + QQuickAnchorLine anchor; + anchor.item = baseItem; + anchor.anchorLine = anchorLine; + + QQuickItem *item = new QQuickItem; + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + + const QMetaObject *meta = itemPrivate->anchors()->metaObject(); + QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); + + QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor))); + QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), true); + + QVERIFY(p.reset(itemPrivate->anchors())); + QCOMPARE(itemPrivate->anchors()->usedAnchors().testFlag(usedAnchor), false); + + delete item; + delete baseItem; +} + +void tst_qquickanchors::reset_data() +{ + QTest::addColumn("side"); + QTest::addColumn("anchorLine"); + QTest::addColumn("usedAnchor"); + + QTest::newRow("left") << "left" << QQuickAnchorLine::Left << QQuickAnchors::LeftAnchor; + QTest::newRow("top") << "top" << QQuickAnchorLine::Top << QQuickAnchors::TopAnchor; + QTest::newRow("right") << "right" << QQuickAnchorLine::Right << QQuickAnchors::RightAnchor; + QTest::newRow("bottom") << "bottom" << QQuickAnchorLine::Bottom << QQuickAnchors::BottomAnchor; + + QTest::newRow("hcenter") << "horizontalCenter" << QQuickAnchorLine::HCenter << QQuickAnchors::HCenterAnchor; + QTest::newRow("vcenter") << "verticalCenter" << QQuickAnchorLine::VCenter << QQuickAnchors::VCenterAnchor; + QTest::newRow("baseline") << "baseline" << QQuickAnchorLine::Baseline << QQuickAnchors::BaselineAnchor; +} + +void tst_qquickanchors::resetConvenience() +{ + QQuickItem *baseItem = new QQuickItem; + QQuickItem *item = new QQuickItem; + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + + //fill + itemPrivate->anchors()->setFill(baseItem); + QVERIFY(itemPrivate->anchors()->fill() == baseItem); + itemPrivate->anchors()->resetFill(); + QVERIFY(itemPrivate->anchors()->fill() == 0); + + //centerIn + itemPrivate->anchors()->setCenterIn(baseItem); + QVERIFY(itemPrivate->anchors()->centerIn() == baseItem); + itemPrivate->anchors()->resetCenterIn(); + QVERIFY(itemPrivate->anchors()->centerIn() == 0); + + delete item; + delete baseItem; +} + +void tst_qquickanchors::nullItem() +{ + QFETCH(QString, side); + + QQuickAnchorLine anchor; + QQuickItem *item = new QQuickItem; + QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); + + const QMetaObject *meta = itemPrivate->anchors()->metaObject(); + QMetaProperty p = meta->property(meta->indexOfProperty(side.toUtf8().constData())); + + QTest::ignoreMessage(QtWarningMsg, ": QML Item: Cannot anchor to a null item."); + QVERIFY(p.write(itemPrivate->anchors(), qVariantFromValue(anchor))); + + delete item; +} + +void tst_qquickanchors::nullItem_data() +{ + QTest::addColumn("side"); + + QTest::newRow("left") << "left"; + QTest::newRow("top") << "top"; + QTest::newRow("right") << "right"; + QTest::newRow("bottom") << "bottom"; + + QTest::newRow("hcenter") << "horizontalCenter"; + QTest::newRow("vcenter") << "verticalCenter"; + QTest::newRow("baseline") << "baseline"; +} + +//QTBUG-5428 +void tst_qquickanchors::crash1() +{ + QUrl source(QUrl::fromLocalFile(TESTDATA("crash1.qml"))); + + QString expect = source.toString() + ":3:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column"; + + QTest::ignoreMessage(QtWarningMsg, expect.toLatin1()); + + QQuickView *view = new QQuickView(source); + qApp->processEvents(); + + delete view; +} + +void tst_qquickanchors::fill() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rect->x(), 0.0 + 10.0); + QCOMPARE(rect->y(), 0.0 + 30.0); + QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0); + //Alter Offsets (tests QTBUG-6631) + rectPrivate->anchors()->setLeftMargin(20.0); + rectPrivate->anchors()->setRightMargin(0.0); + rectPrivate->anchors()->setBottomMargin(0.0); + rectPrivate->anchors()->setTopMargin(10.0); + QCOMPARE(rect->x(), 0.0 + 20.0); + QCOMPARE(rect->y(), 0.0 + 10.0); + QCOMPARE(rect->width(), 200.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 10.0); + + delete view; +} + +void tst_qquickanchors::fillRTL() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("fill.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + mirrorAnchors(rect); + + QCOMPARE(rect->x(), 0.0 + 20.0); + QCOMPARE(rect->y(), 0.0 + 30.0); + QCOMPARE(rect->width(), 200.0 - 10.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 30.0 - 40.0); + //Alter Offsets (tests QTBUG-6631) + rectPrivate->anchors()->setLeftMargin(20.0); + rectPrivate->anchors()->setRightMargin(0.0); + rectPrivate->anchors()->setBottomMargin(0.0); + rectPrivate->anchors()->setTopMargin(10.0); + QCOMPARE(rect->x(), 0.0 + 0.0); + QCOMPARE(rect->y(), 0.0 + 10.0); + QCOMPARE(rect->width(), 200.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 10.0); + + delete view; +} + +void tst_qquickanchors::centerIn() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + QCOMPARE(rect->x(), 75.0 + 10); + QCOMPARE(rect->y(), 75.0 + 30); + //Alter Offsets (tests QTBUG-6631) + rectPrivate->anchors()->setHorizontalCenterOffset(-20.0); + rectPrivate->anchors()->setVerticalCenterOffset(-10.0); + QCOMPARE(rect->x(), 75.0 - 20.0); + QCOMPARE(rect->y(), 75.0 - 10.0); + + delete view; +} + +void tst_qquickanchors::centerInRTL() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerin.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + mirrorAnchors(rect); + + QCOMPARE(rect->x(), 75.0 - 10); + QCOMPARE(rect->y(), 75.0 + 30); + //Alter Offsets (tests QTBUG-6631) + rectPrivate->anchors()->setHorizontalCenterOffset(-20.0); + rectPrivate->anchors()->setVerticalCenterOffset(-10.0); + QCOMPARE(rect->x(), 75.0 + 20.0); + QCOMPARE(rect->y(), 75.0 - 10.0); + + delete view; +} + +//QTBUG-12441 +void tst_qquickanchors::centerInRotation() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("centerinRotation.qml"))); + + qApp->processEvents(); + QQuickRectangle* outer = findItem(view->rootObject(), QLatin1String("outer")); + QQuickRectangle* inner = findItem(view->rootObject(), QLatin1String("inner")); + + QEXPECT_FAIL("", "QTBUG-12441", Abort); + QCOMPARE(outer->x(), qreal(49.5)); + QCOMPARE(outer->y(), qreal(49.5)); + QCOMPARE(inner->x(), qreal(25.5)); + QCOMPARE(inner->y(), qreal(25.5)); + + delete view; +} + +void tst_qquickanchors::hvCenter() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + + // test QTBUG-10999 + QCOMPARE(rect->x(), 10.0); + QCOMPARE(rect->y(), 19.0); + + rectPrivate->anchors()->setHorizontalCenterOffset(-5.0); + rectPrivate->anchors()->setVerticalCenterOffset(5.0); + QCOMPARE(rect->x(), 10.0 - 5.0); + QCOMPARE(rect->y(), 19.0 + 5.0); + + delete view; +} + +void tst_qquickanchors::hvCenterRTL() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("hvCenter.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("centered")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + mirrorAnchors(rect); + + // test QTBUG-10999 + QCOMPARE(rect->x(), 10.0); + QCOMPARE(rect->y(), 19.0); + + rectPrivate->anchors()->setHorizontalCenterOffset(-5.0); + rectPrivate->anchors()->setVerticalCenterOffset(5.0); + QCOMPARE(rect->x(), 10.0 + 5.0); + QCOMPARE(rect->y(), 19.0 + 5.0); + + delete view; +} +void tst_qquickanchors::margins() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml"))); + + qApp->processEvents(); + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + QCOMPARE(rect->x(), 5.0); + QCOMPARE(rect->y(), 6.0); + QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0); + QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0); + + rectPrivate->anchors()->setTopMargin(0.0); + rectPrivate->anchors()->setMargins(20.0); + + QCOMPARE(rect->x(), 5.0); + QCOMPARE(rect->y(), 20.0); + QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0); + + delete view; +} + +void tst_qquickanchors::marginsRTL() +{ + QQuickView *view = new QQuickView(QUrl::fromLocalFile(TESTDATA("margins.qml"))); + + QQuickRectangle* rect = findItem(view->rootObject(), QLatin1String("filler")); + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + mirrorAnchors(rect); + + QCOMPARE(rect->x(), 10.0); + QCOMPARE(rect->y(), 6.0); + QCOMPARE(rect->width(), 200.0 - 5.0 - 10.0); + QCOMPARE(rect->height(), 200.0 - 6.0 - 10.0); + + rectPrivate->anchors()->setTopMargin(0.0); + rectPrivate->anchors()->setMargins(20.0); + + QCOMPARE(rect->x(), 20.0); + QCOMPARE(rect->y(), 20.0); + QCOMPARE(rect->width(), 200.0 - 5.0 - 20.0); + QCOMPARE(rect->height(), 200.0 - 20.0 - 20.0); + + delete view; +} + + +QTEST_MAIN(tst_qquickanchors) + +#include "tst_qquickanchors.moc" diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/colors.gif b/tests/auto/qtquick2/qquickanimatedimage/data/colors.gif new file mode 100644 index 0000000000..1270bfaa79 Binary files /dev/null and b/tests/auto/qtquick2/qquickanimatedimage/data/colors.gif differ diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/colors.qml b/tests/auto/qtquick2/qquickanimatedimage/data/colors.qml new file mode 100644 index 0000000000..5ccc0148dd --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/colors.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +AnimatedImage { + source: "colors.gif" +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/hearts.gif b/tests/auto/qtquick2/qquickanimatedimage/data/hearts.gif new file mode 100644 index 0000000000..cfb55f27f5 Binary files /dev/null and b/tests/auto/qtquick2/qquickanimatedimage/data/hearts.gif differ diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/hearts.qml b/tests/auto/qtquick2/qquickanimatedimage/data/hearts.qml new file mode 100644 index 0000000000..717bab430b --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/hearts.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +AnimatedImage { + source: "hearts.gif" + playing: false +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/qmldir b/tests/auto/qtquick2/qquickanimatedimage/data/qmldir new file mode 100644 index 0000000000..ef7c1f44f3 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/qmldir @@ -0,0 +1 @@ +# No local types diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/qtbug-16520.qml b/tests/auto/qtquick2/qquickanimatedimage/data/qtbug-16520.qml new file mode 100644 index 0000000000..da77a4063b --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/qtbug-16520.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + width: 500 + height: 500 + + AnimatedImage { + objectName: "anim" + anchors.centerIn: parent + asynchronous: true + opacity: status == AnimatedImage.Ready ? 1 : 0 + + Behavior on opacity { + NumberAnimation { duration: 1000 } + } + } +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickman.gif b/tests/auto/qtquick2/qquickanimatedimage/data/stickman.gif new file mode 100644 index 0000000000..7c4cd18687 Binary files /dev/null and b/tests/auto/qtquick2/qquickanimatedimage/data/stickman.gif differ diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickman.qml b/tests/auto/qtquick2/qquickanimatedimage/data/stickman.qml new file mode 100644 index 0000000000..a47924de21 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/stickman.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +AnimatedImage { + source: "stickman.gif" +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickmanerror1.qml b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanerror1.qml new file mode 100644 index 0000000000..4f823b3d70 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanerror1.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +AnimatedImage { + sourceSize: "240x180" + source: "stickman.gif" +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickmanpause.qml b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanpause.qml new file mode 100644 index 0000000000..ef771ed56f --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanpause.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +AnimatedImage { + source: "stickman.gif" + paused: true + currentFrame: 2 +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickmanscaled.qml b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanscaled.qml new file mode 100644 index 0000000000..1ef1f95165 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanscaled.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +AnimatedImage { + width: 240 + height: 180 + source: "stickman.gif" +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/data/stickmanstopped.qml b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanstopped.qml new file mode 100644 index 0000000000..0bf80b8972 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/data/stickmanstopped.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +AnimatedImage { + source: "stickman.gif" + playing: false +} diff --git a/tests/auto/qtquick2/qquickanimatedimage/qquickanimatedimage.pro b/tests/auto/qtquick2/qquickanimatedimage/qquickanimatedimage.pro new file mode 100644 index 0000000000..56394592b8 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/qquickanimatedimage.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickanimatedimage +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qquickanimatedimage.cpp ../../shared/testhttpserver.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/qtquick2/qquickanimatedimage/tst_qquickanimatedimage.cpp new file mode 100644 index 0000000000..bf1017fe21 --- /dev/null +++ b/tests/auto/qtquick2/qquickanimatedimage/tst_qquickanimatedimage.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/testhttpserver.h" +#include "../../shared/util.h" + +Q_DECLARE_METATYPE(QQuickImageBase::Status) + +class tst_qquickanimatedimage : public QObject +{ + Q_OBJECT +public: + tst_qquickanimatedimage() {} + +private slots: + void play(); + void pause(); + void stopped(); + void setFrame(); + void frameCount(); + void mirror_running(); + void mirror_notRunning(); + void mirror_notRunning_data(); + void remote(); + void remote_data(); + void sourceSize(); + void sourceSizeReadOnly(); + void invalidSource(); + void qtbug_16520(); + void progressAndStatusChanges(); + +}; + +void tst_qquickanimatedimage::play() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickman.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QVERIFY(anim->isPlaying()); + + delete anim; +} + +void tst_qquickanimatedimage::pause() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QVERIFY(anim->isPlaying()); + QVERIFY(anim->isPaused()); + + delete anim; +} + +void tst_qquickanimatedimage::stopped() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QVERIFY(!anim->isPlaying()); + QCOMPARE(anim->currentFrame(), 0); + + delete anim; +} + +void tst_qquickanimatedimage::setFrame() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanpause.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QVERIFY(anim->isPlaying()); + QCOMPARE(anim->currentFrame(), 2); + + delete anim; +} + +void tst_qquickanimatedimage::frameCount() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("colors.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QVERIFY(anim->isPlaying()); + QCOMPARE(anim->frameCount(), 3); + + delete anim; +} + +void tst_qquickanimatedimage::mirror_running() +{ + // test where mirror is set to true after animation has started + + QQuickView *canvas = new QQuickView; + canvas->show(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("hearts.qml"))); + QQuickAnimatedImage *anim = qobject_cast(canvas->rootObject()); + QVERIFY(anim); + + int width = anim->property("width").toInt(); + + QCOMPARE(anim->currentFrame(), 0); + QPixmap frame0 = QPixmap::fromImage(canvas->grabFrameBuffer()); + + anim->setCurrentFrame(1); + QPixmap frame1 = QPixmap::fromImage(canvas->grabFrameBuffer()); + + anim->setCurrentFrame(0); + + QSignalSpy spy(anim, SIGNAL(frameChanged())); + anim->setPlaying(true); + + QTRY_VERIFY(spy.count() == 1); spy.clear(); + anim->setProperty("mirror", true); + + QCOMPARE(anim->currentFrame(), 1); + QPixmap frame1_flipped = QPixmap::fromImage(canvas->grabFrameBuffer()); + + QTRY_VERIFY(spy.count() == 1); spy.clear(); + QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first + QPixmap frame0_flipped = QPixmap::fromImage(canvas->grabFrameBuffer()); + + QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved"); + + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + QPixmap frame0_expected = frame0.transformed(transform); + QPixmap frame1_expected = frame1.transformed(transform); + + QCOMPARE(frame0_flipped, frame0_expected); + QCOMPARE(frame1_flipped, frame1_expected); + + delete canvas; +} + +void tst_qquickanimatedimage::mirror_notRunning() +{ + QFETCH(QUrl, fileUrl); + + QQuickView *canvas = new QQuickView; + canvas->show(); + + canvas->setSource(fileUrl); + QQuickAnimatedImage *anim = qobject_cast(canvas->rootObject()); + QVERIFY(anim); + + int width = anim->property("width").toInt(); + QPixmap screenshot = QPixmap::fromImage(canvas->grabFrameBuffer()); + + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + QPixmap expected = screenshot.transformed(transform); + + int frame = anim->currentFrame(); + bool playing = anim->isPlaying(); + bool paused = anim->isPlaying(); + + anim->setProperty("mirror", true); + screenshot = QPixmap::fromImage(canvas->grabFrameBuffer()); + + QSKIP("Skip while QTBUG-19351 and QTBUG-19252 are not resolved"); + QCOMPARE(screenshot, expected); + + // mirroring should not change the current frame or playing status + QCOMPARE(anim->currentFrame(), frame); + QCOMPARE(anim->isPlaying(), playing); + QCOMPARE(anim->isPaused(), paused); + + delete canvas; +} + +void tst_qquickanimatedimage::mirror_notRunning_data() +{ + QTest::addColumn("fileUrl"); + + QTest::newRow("paused") << QUrl::fromLocalFile(TESTDATA("stickmanpause.qml")); + QTest::newRow("stopped") << QUrl::fromLocalFile(TESTDATA("stickmanstopped.qml")); +} + +void tst_qquickanimatedimage::remote() +{ + QFETCH(QString, fileName); + QFETCH(bool, paused); + + TestHTTPServer server(14449); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl("http://127.0.0.1:14449/" + fileName)); + QTRY_VERIFY(component.isReady()); + + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + + QTRY_VERIFY(anim->isPlaying()); + if (paused) { + QTRY_VERIFY(anim->isPaused()); + QCOMPARE(anim->currentFrame(), 2); + } + QVERIFY(anim->status() != QQuickAnimatedImage::Error); + + delete anim; +} + +void tst_qquickanimatedimage::sourceSize() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanscaled.qml"))); + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + QCOMPARE(anim->width(),240.0); + QCOMPARE(anim->height(),180.0); + QCOMPARE(anim->sourceSize(),QSize(160,120)); + + delete anim; +} + +void tst_qquickanimatedimage::sourceSizeReadOnly() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("stickmanerror1.qml"))); + QVERIFY(component.isError()); + QCOMPARE(component.errors().at(0).description(), QString("Invalid property assignment: \"sourceSize\" is a read-only property")); +} + +void tst_qquickanimatedimage::remote_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("paused"); + + QTest::newRow("playing") << "stickman.qml" << false; + QTest::newRow("paused") << "stickmanpause.qml" << true; +} + +void tst_qquickanimatedimage::invalidSource() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0\n AnimatedImage { source: \"no-such-file.gif\" }", QUrl::fromLocalFile("")); + QVERIFY(component.isReady()); + + QTest::ignoreMessage(QtWarningMsg, "file::2:2: QML AnimatedImage: Error Reading Animated Image File file:no-such-file.gif"); + + QQuickAnimatedImage *anim = qobject_cast(component.create()); + QVERIFY(anim); + + QVERIFY(!anim->isPlaying()); + QVERIFY(!anim->isPaused()); + QCOMPARE(anim->currentFrame(), 0); + QCOMPARE(anim->frameCount(), 0); + QTRY_VERIFY(anim->status() == 3); +} + +void tst_qquickanimatedimage::qtbug_16520() +{ + TestHTTPServer server(14449); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("qtbug-16520.qml"))); + QTRY_VERIFY(component.isReady()); + + QQuickRectangle *root = qobject_cast(component.create()); + QVERIFY(root); + QQuickAnimatedImage *anim = root->findChild("anim"); + + anim->setProperty("source", "http://127.0.0.1:14449/stickman.gif"); + + QTRY_VERIFY(anim->opacity() == 0); + QTRY_VERIFY(anim->opacity() == 1); + + delete anim; +} + +void tst_qquickanimatedimage::progressAndStatusChanges() +{ + TestHTTPServer server(14449); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + QDeclarativeEngine engine; + QString componentStr = "import QtQuick 2.0\nAnimatedImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("stickman.gif"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QVERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + + qRegisterMetaType(); + QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &))); + QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); + QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status))); + + // Loading local file + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.gif"))); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 1); + QTRY_COMPARE(progressSpy.count(), 0); + QTRY_COMPARE(statusSpy.count(), 0); + + // Loading remote file + ctxt->setContextProperty("srcImage", "http://127.0.0.1:14449/stickman.gif"); + QTRY_VERIFY(obj->status() == QQuickImage::Loading); + QTRY_VERIFY(obj->progress() == 0.0); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 2); + QTRY_VERIFY(progressSpy.count() > 1); + QTRY_COMPARE(statusSpy.count(), 2); + + ctxt->setContextProperty("srcImage", ""); + QTRY_VERIFY(obj->status() == QQuickImage::Null); + QTRY_VERIFY(obj->progress() == 0.0); + QTRY_COMPARE(sourceSpy.count(), 3); + QTRY_VERIFY(progressSpy.count() > 2); + QTRY_COMPARE(statusSpy.count(), 3); +} + +QTEST_MAIN(tst_qquickanimatedimage) + +#include "tst_qquickanimatedimage.moc" diff --git a/tests/auto/qtquick2/qquickborderimage/data/colors-mirror.png b/tests/auto/qtquick2/qquickborderimage/data/colors-mirror.png new file mode 100644 index 0000000000..e30870dd1e Binary files /dev/null and b/tests/auto/qtquick2/qquickborderimage/data/colors-mirror.png differ diff --git a/tests/auto/qtquick2/qquickborderimage/data/colors-round-quotes.sci b/tests/auto/qtquick2/qquickborderimage/data/colors-round-quotes.sci new file mode 100644 index 0000000000..294f3cfe48 --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/data/colors-round-quotes.sci @@ -0,0 +1,7 @@ +border.left:10 +border.top:20 +border.right:30 +border.bottom:40 +horizontalTileRule:Round +verticalTileRule:Repeat +source:"colors.png" diff --git a/tests/auto/qtquick2/qquickborderimage/data/colors-round-remote.sci b/tests/auto/qtquick2/qquickborderimage/data/colors-round-remote.sci new file mode 100644 index 0000000000..c673bed598 --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/data/colors-round-remote.sci @@ -0,0 +1,7 @@ +border.left:10 +border.top:20 +border.right:30 +border.bottom:40 +horizontalTileRule:Round +verticalTileRule:Repeat +source:http://127.0.0.1:14446/colors.png diff --git a/tests/auto/qtquick2/qquickborderimage/data/colors-round.sci b/tests/auto/qtquick2/qquickborderimage/data/colors-round.sci new file mode 100644 index 0000000000..5d2f49f0e1 --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/data/colors-round.sci @@ -0,0 +1,7 @@ +border.left:10 +border.top:20 +border.right:30 +border.bottom:40 +horizontalTileRule:Round +verticalTileRule:Repeat +source:colors.png diff --git a/tests/auto/qtquick2/qquickborderimage/data/colors.png b/tests/auto/qtquick2/qquickborderimage/data/colors.png new file mode 100644 index 0000000000..dfb62f3d64 Binary files /dev/null and b/tests/auto/qtquick2/qquickborderimage/data/colors.png differ diff --git a/tests/auto/qtquick2/qquickborderimage/data/heart200.png b/tests/auto/qtquick2/qquickborderimage/data/heart200.png new file mode 100644 index 0000000000..5a31ae8f4d Binary files /dev/null and b/tests/auto/qtquick2/qquickborderimage/data/heart200.png differ diff --git a/tests/auto/qtquick2/qquickborderimage/data/invalid.sci b/tests/auto/qtquick2/qquickborderimage/data/invalid.sci new file mode 100644 index 0000000000..98c72c9bf1 --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/data/invalid.sci @@ -0,0 +1,7 @@ +border.left:10 +border.top:20 +border.down:30 +border.up:40 +horizontalTileRule:Roun +verticalTileRule:Repea +source:colors.png diff --git a/tests/auto/qtquick2/qquickborderimage/data/mirror.qml b/tests/auto/qtquick2/qquickborderimage/data/mirror.qml new file mode 100644 index 0000000000..abab076e08 --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/data/mirror.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +BorderImage { + source: "colors-mirror.png" + width: 300; height: 300 + border { top: 30; right: 30; bottom: 30; left: 30 } +} diff --git a/tests/auto/qtquick2/qquickborderimage/qquickborderimage.pro b/tests/auto/qtquick2/qquickborderimage/qquickborderimage.pro new file mode 100644 index 0000000000..34d08aa37f --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/qquickborderimage.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qquickborderimage +macx:CONFIG -= app_bundle + +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qquickborderimage.cpp ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network widgets testlib diff --git a/tests/auto/qtquick2/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/qtquick2/qquickborderimage/tst_qquickborderimage.cpp new file mode 100644 index 0000000000..b9fd91d7fb --- /dev/null +++ b/tests/auto/qtquick2/qquickborderimage/tst_qquickborderimage.cpp @@ -0,0 +1,376 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/testhttpserver.h" +#include "../../shared/util.h" + +#define SERVER_PORT 14446 +#define SERVER_ADDR "http://127.0.0.1:14446" + +class tst_qquickborderimage : public QObject + +{ + Q_OBJECT +public: + tst_qquickborderimage(); + +private slots: + void noSource(); + void imageSource(); + void imageSource_data(); + void clearSource(); + void resized(); + void smooth(); + void mirror(); + void tileModes(); + void sciSource(); + void sciSource_data(); + void invalidSciFile(); + void pendingRemoteRequest(); + void pendingRemoteRequest_data(); + +private: + QDeclarativeEngine engine; +}; + +tst_qquickborderimage::tst_qquickborderimage() +{ +} + +void tst_qquickborderimage::noSource() +{ + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->source(), QUrl()); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); + + delete obj; +} + +void tst_qquickborderimage::imageSource_data() +{ + QTest::addColumn("source"); + QTest::addColumn("remote"); + QTest::addColumn("error"); + + QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << false << ""; + QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << false + << "file::2:1: QML BorderImage: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString(); + QTest::newRow("remote") << SERVER_ADDR "/colors.png" << true << ""; + QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << true + << "file::2:1: QML BorderImage: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; +} + +void tst_qquickborderimage::imageSource() +{ + QFETCH(QString, source); + QFETCH(bool, remote); + QFETCH(QString, error); + + TestHTTPServer *server = 0; + if (remote) { + server = new TestHTTPServer(SERVER_PORT); + QVERIFY(server->isValid()); + server->serveDirectory(TESTDATA("")); + } + + if (!error.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); + + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + + if (remote) + QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); + + QCOMPARE(obj->source(), remote ? source : QUrl(source)); + + if (error.isEmpty()) { + QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); + QCOMPARE(obj->width(), 120.); + QCOMPARE(obj->height(), 120.); + QCOMPARE(obj->sourceSize().width(), 120); + QCOMPARE(obj->sourceSize().height(), 120); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); + } else { + QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); + } + + delete obj; + delete server; +} + +void tst_qquickborderimage::clearSource() +{ + QString componentStr = "import QtQuick 2.0\nBorderImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QVERIFY(obj->status() == QQuickBorderImage::Ready); + QCOMPARE(obj->width(), 120.); + QCOMPARE(obj->height(), 120.); + + ctxt->setContextProperty("srcImage", ""); + QVERIFY(obj->source().isEmpty()); + QVERIFY(obj->status() == QQuickBorderImage::Null); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); +} + +void tst_qquickborderimage::resized() +{ + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("colors.png")).toString() + "\"; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->sourceSize().width(), 120); + QCOMPARE(obj->sourceSize().height(), 120); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); + + delete obj; +} + +void tst_qquickborderimage::smooth() +{ + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->smooth(), true); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); + + delete obj; +} + +void tst_qquickborderimage::mirror() +{ + QQuickView *canvas = new QQuickView; + canvas->show(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml"))); + QQuickBorderImage *image = qobject_cast(canvas->rootObject()); + QVERIFY(image != 0); + canvas->show(); + + QImage screenshot = canvas->grabFrameBuffer(); + + QImage srcPixmap(screenshot); + QTransform transform; + transform.translate(image->width(), 0).scale(-1, 1.0); + srcPixmap = srcPixmap.transformed(transform); + + image->setProperty("mirror", true); + screenshot = canvas->grabFrameBuffer(); + QCOMPARE(screenshot, srcPixmap); + + delete canvas; +} + +void tst_qquickborderimage::tileModes() +{ + { + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 100; height: 300; horizontalTileMode: BorderImage.Repeat; verticalTileMode: BorderImage.Repeat }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 100.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Repeat); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat); + + delete obj; + } + { + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 150; horizontalTileMode: BorderImage.Round; verticalTileMode: BorderImage.Round }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 150.); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Round); + + delete obj; + } +} + +void tst_qquickborderimage::sciSource() +{ + QFETCH(QString, source); + QFETCH(bool, valid); + + bool remote = source.startsWith("http"); + TestHTTPServer *server = 0; + if (remote) { + server = new TestHTTPServer(SERVER_PORT); + QVERIFY(server->isValid()); + server->serveDirectory(TESTDATA("")); + } + + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\"; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + + if (remote) + QTRY_VERIFY(obj->status() == QQuickBorderImage::Loading); + + QCOMPARE(obj->source(), remote ? source : QUrl(source)); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + + if (valid) { + QTRY_VERIFY(obj->status() == QQuickBorderImage::Ready); + QCOMPARE(obj->border()->left(), 10); + QCOMPARE(obj->border()->top(), 20); + QCOMPARE(obj->border()->right(), 30); + QCOMPARE(obj->border()->bottom(), 40); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Round); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Repeat); + } else { + QTRY_VERIFY(obj->status() == QQuickBorderImage::Error); + } + + delete obj; + delete server; +} + +void tst_qquickborderimage::sciSource_data() +{ + QTest::addColumn("source"); + QTest::addColumn("valid"); + + QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors-round.sci")).toString() << true; + QTest::newRow("local quoted filename") << QUrl::fromLocalFile(TESTDATA("colors-round-quotes.sci")).toString() << true; + QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.sci")).toString() << false; + QTest::newRow("remote") << SERVER_ADDR "/colors-round.sci" << true; + QTest::newRow("remote filename quoted") << SERVER_ADDR "/colors-round-quotes.sci" << true; + QTest::newRow("remote image") << SERVER_ADDR "/colors-round-remote.sci" << true; + QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.sci" << false; +} + +void tst_qquickborderimage::invalidSciFile() +{ + QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Roun" + QTest::ignoreMessage(QtWarningMsg, "QQuickGridScaledImage: Invalid tile rule specified. Using Stretch."); // for "Repea" + + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + QUrl::fromLocalFile(TESTDATA("invalid.sci")).toString() +"\"; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->status(), QQuickImageBase::Error); + QCOMPARE(obj->horizontalTileMode(), QQuickBorderImage::Stretch); + QCOMPARE(obj->verticalTileMode(), QQuickBorderImage::Stretch); + + delete obj; +} + +void tst_qquickborderimage::pendingRemoteRequest() +{ + QFETCH(QString, source); + + QString componentStr = "import QtQuick 2.0\nBorderImage { source: \"" + source + "\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickBorderImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->status(), QQuickBorderImage::Loading); + + // verify no crash + // This will cause a delayed "QThread: Destroyed while thread is still running" warning + delete obj; + QTest::qWait(50); +} + +void tst_qquickborderimage::pendingRemoteRequest_data() +{ + QTest::addColumn("source"); + + QTest::newRow("png file") << "http://localhost/none.png"; + QTest::newRow("sci file") << "http://localhost/none.sci"; +} + +QTEST_MAIN(tst_qquickborderimage) + +#include "tst_qquickborderimage.moc" diff --git a/tests/auto/qtquick2/qquickcanvas/data/window.qml b/tests/auto/qtquick2/qquickcanvas/data/window.qml new file mode 100644 index 0000000000..d79d5161b5 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvas/data/window.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import QtQuick.Window 2.0 as Window + +Window.Window { + color: "#00FF00" + Item { + objectName: "item" + } +} diff --git a/tests/auto/qtquick2/qquickcanvas/qquickcanvas.pro b/tests/auto/qtquick2/qquickcanvas/qquickcanvas.pro new file mode 100644 index 0000000000..c95d474a21 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvas/qquickcanvas.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qquickcanvas +SOURCES += tst_qquickcanvas.cpp + +macx:CONFIG -= app_bundle + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp b/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp new file mode 100644 index 0000000000..f894ff3d39 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvas/tst_qquickcanvas.cpp @@ -0,0 +1,557 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +struct TouchEventData { + QEvent::Type type; + QWidget *widget; + QWindow *window; + Qt::TouchPointStates states; + QList touchPoints; +}; + +static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p, const QPointF &lastPoint = QPointF()) +{ + QPointF last = lastPoint.isNull() ? p : lastPoint; + + QTouchEvent::TouchPoint tp; + + tp.setPos(p); + tp.setLastPos(last); + tp.setScenePos(item->mapToScene(p)); + tp.setLastScenePos(item->mapToScene(last)); + tp.setScreenPos(item->canvas()->mapToGlobal(tp.scenePos().toPoint())); + tp.setLastScreenPos(item->canvas()->mapToGlobal(tp.lastScenePos().toPoint())); + return tp; +} + +static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QList &touchPoints) +{ + TouchEventData d = { type, w, 0, states, touchPoints }; + return d; +} + +static TouchEventData makeTouchData(QEvent::Type type, QWidget *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint) +{ + QList points; + points << touchPoint; + return makeTouchData(type, w, states, points); +} +static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QList& touchPoints) +{ + TouchEventData d = { type, 0, w, states, touchPoints }; + return d; +} +static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states, const QTouchEvent::TouchPoint &touchPoint) +{ + QList points; + points << touchPoint; + return makeTouchData(type, w, states, points); +} + +#define COMPARE_TOUCH_POINTS(tp1, tp2) \ +{ \ + QCOMPARE(tp1.pos(), tp2.pos()); \ + QCOMPARE(tp1.lastPos(), tp2.lastPos()); \ + QCOMPARE(tp1.scenePos(), tp2.scenePos()); \ + QCOMPARE(tp1.lastScenePos(), tp2.lastScenePos()); \ + QCOMPARE(tp1.screenPos(), tp2.screenPos()); \ + QCOMPARE(tp1.lastScreenPos(), tp2.lastScreenPos()); \ +} + +#define COMPARE_TOUCH_DATA(d1, d2) \ +{ \ + QCOMPARE((int)d1.type, (int)d2.type); \ + QCOMPARE(d1.widget, d2.widget); \ + QCOMPARE((int)d1.states, (int)d2.states); \ + QCOMPARE(d1.touchPoints.count(), d2.touchPoints.count()); \ + for (int i=0; isetWidth(1); + setAcceptedMouseButtons(Qt::LeftButton); + setFiltersChildMouseEvents(true); + } + + void reset() { + acceptEvents = true; + setEnabled(true); + setOpacity(1.0); + + lastEvent = makeTouchData(QEvent::None, canvas(), 0, QList());//CHECK_VALID + } + + bool acceptEvents; + TouchEventData lastEvent; + int mousePressId; + +protected: + virtual void touchEvent(QTouchEvent *event) { + if (!acceptEvents) { + event->ignore(); + return; + } + lastEvent = makeTouchData(event->type(), event->widget(), event->touchPointStates(), event->touchPoints()); + event->accept(); + } + + virtual void mousePressEvent(QMouseEvent *) { + mousePressId = ++mousePressNum; + } + + bool childMouseEventFilter(QQuickItem *, QEvent *event) { + if (event->type() == QEvent::MouseButtonPress) + mousePressId = ++mousePressNum; + return false; + } + + static int mousePressNum; +}; + +int TestTouchItem::mousePressNum = 0; + +class ConstantUpdateItem : public QQuickItem +{ +Q_OBJECT +public: + ConstantUpdateItem(QQuickItem *parent = 0) : QQuickItem(parent), iterations(0) {setFlag(ItemHasContents);} + + int iterations; +protected: + QSGNode* updatePaintNode(QSGNode *, UpdatePaintNodeData *){ + iterations++; + update(); + return 0; + } +}; + +class tst_qquickcanvas : public QObject +{ + Q_OBJECT +public: + tst_qquickcanvas(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void constantUpdates(); + + void touchEvent_basic(); + void touchEvent_propagation(); + void touchEvent_propagation_data(); + + void clearCanvas(); + void mouseFiltering(); + + void qmlCreation(); + void clearColor(); +}; + +tst_qquickcanvas::tst_qquickcanvas() +{ +} + +void tst_qquickcanvas::initTestCase() +{ +} + +void tst_qquickcanvas::cleanupTestCase() +{ +} + +//If the item calls update inside updatePaintNode, it should schedule another update +void tst_qquickcanvas::constantUpdates() +{ + QQuickCanvas canvas; + ConstantUpdateItem item(canvas.rootItem()); + canvas.show(); + QTRY_VERIFY(item.iterations > 60); +} + +void tst_qquickcanvas::touchEvent_basic() +{ + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->show(); + + TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); + bottomItem->setObjectName("Bottom Item"); + bottomItem->setSize(QSizeF(150, 150)); + + TestTouchItem *middleItem = new TestTouchItem(bottomItem); + middleItem->setObjectName("Middle Item"); + middleItem->setPos(QPointF(50, 50)); + middleItem->setSize(QSizeF(150, 150)); + + TestTouchItem *topItem = new TestTouchItem(middleItem); + topItem->setObjectName("Top Item"); + topItem->setPos(QPointF(50, 50)); + topItem->setSize(QSizeF(150, 150)); + + QPointF pos(10, 10); + + // press single point + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas); + QTest::qWait(50); + + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); + TouchEventData d = makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem,pos)); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); + topItem->reset(); + + // press multiple points + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas) + .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); + topItem->reset(); + bottomItem->reset(); + + // touch point on top item moves to bottom item, but top item should still receive the event + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved, + makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos))); + topItem->reset(); + + // touch point on bottom item moves to top item, but bottom item should still receive the event + QTest::touchEvent(canvas).press(0, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).move(0, topItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchUpdate, canvas, Qt::TouchPointMoved, + makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos), pos))); + bottomItem->reset(); + + // a single stationary press on an item shouldn't cause an event + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).stationary(0) + .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); // received press only, not stationary + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(topItem, pos))); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); + topItem->reset(); + bottomItem->reset(); + + // move touch point from top item to bottom, and release + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(),canvas); + QTest::qWait(50); + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased, + makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos), pos))); + topItem->reset(); + + // release while another point is pressed + QTest::touchEvent(canvas).press(0, topItem->mapToScene(pos).toPoint(),canvas) + .press(1, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).move(0, bottomItem->mapToScene(pos).toPoint(), canvas); + QTest::qWait(50); + QTest::touchEvent(canvas).release(0, bottomItem->mapToScene(pos).toPoint(), canvas) + .stationary(1); + QTest::qWait(50); + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchEnd, canvas, Qt::TouchPointReleased, + makeTouchPoint(topItem, topItem->mapFromItem(bottomItem, pos)))); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, makeTouchPoint(bottomItem, pos))); + topItem->reset(); + bottomItem->reset(); + + delete topItem; + delete middleItem; + delete bottomItem; + delete canvas; +} + +void tst_qquickcanvas::touchEvent_propagation() +{ + QFETCH(bool, acceptEvents); + QFETCH(bool, enableItem); + QFETCH(qreal, itemOpacity); + + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->show(); + + TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); + bottomItem->setObjectName("Bottom Item"); + bottomItem->setSize(QSizeF(150, 150)); + + TestTouchItem *middleItem = new TestTouchItem(bottomItem); + middleItem->setObjectName("Middle Item"); + middleItem->setPos(QPointF(50, 50)); + middleItem->setSize(QSizeF(150, 150)); + + TestTouchItem *topItem = new TestTouchItem(middleItem); + topItem->setObjectName("Top Item"); + topItem->setPos(QPointF(50, 50)); + topItem->setSize(QSizeF(150, 150)); + + QPointF pos(10, 10); + QPoint pointInBottomItem = bottomItem->mapToScene(pos).toPoint(); // (10, 10) + QPoint pointInMiddleItem = middleItem->mapToScene(pos).toPoint(); // (60, 60) overlaps with bottomItem + QPoint pointInTopItem = topItem->mapToScene(pos).toPoint(); // (110, 110) overlaps with bottom & top items + + // disable topItem + topItem->acceptEvents = acceptEvents; + topItem->setEnabled(enableItem); + topItem->setOpacity(itemOpacity); + + // single touch to top item, should be received by middle item + QTest::touchEvent(canvas).press(0, pointInTopItem, canvas); + QTest::qWait(50); + QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(middleItem->lastEvent.touchPoints.count(), 1); + QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); + COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, + makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos)))); + + // touch top and middle items, middle item should get both events + QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) + .press(1, pointInMiddleItem, canvas); + QTest::qWait(50); + QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(middleItem->lastEvent.touchPoints.count(), 2); + QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); + COMPARE_TOUCH_DATA(middleItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, + (QList() << makeTouchPoint(middleItem, middleItem->mapFromItem(topItem, pos)) + << makeTouchPoint(middleItem, pos) ))); + middleItem->reset(); + + // disable middleItem as well + middleItem->acceptEvents = acceptEvents; + middleItem->setEnabled(enableItem); + middleItem->setOpacity(itemOpacity); + + // touch top and middle items, bottom item should get all events + QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) + .press(1, pointInMiddleItem, canvas); + QTest::qWait(50); + QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 2); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, + (QList() << makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos)) + << makeTouchPoint(bottomItem, bottomItem->mapFromItem(middleItem, pos)) ))); + bottomItem->reset(); + + // disable bottom item as well + bottomItem->acceptEvents = acceptEvents; + bottomItem->setEnabled(enableItem); + bottomItem->setOpacity(itemOpacity); + + // no events should be received + QTest::touchEvent(canvas).press(0, pointInTopItem, canvas) + .press(1, pointInMiddleItem, canvas) + .press(2, pointInBottomItem, canvas); + QTest::qWait(50); + QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); + + topItem->reset(); + middleItem->reset(); + bottomItem->reset(); + + // disable middle item, touch on top item + middleItem->acceptEvents = acceptEvents; + middleItem->setEnabled(enableItem); + middleItem->setOpacity(itemOpacity); + QTest::touchEvent(canvas).press(0, pointInTopItem, canvas); + QTest::qWait(50); + if (!enableItem || itemOpacity == 0) { + // middle item is disabled or has 0 opacity, bottom item receives the event + QVERIFY(topItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QCOMPARE(bottomItem->lastEvent.touchPoints.count(), 1); + COMPARE_TOUCH_DATA(bottomItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, + makeTouchPoint(bottomItem, bottomItem->mapFromItem(topItem, pos)))); + } else { + // middle item ignores event, sends it to the top item (top-most child) + QCOMPARE(topItem->lastEvent.touchPoints.count(), 1); + QVERIFY(middleItem->lastEvent.touchPoints.isEmpty()); + QVERIFY(bottomItem->lastEvent.touchPoints.isEmpty()); + COMPARE_TOUCH_DATA(topItem->lastEvent, makeTouchData(QEvent::TouchBegin, canvas, Qt::TouchPointPressed, + makeTouchPoint(topItem, pos))); + } + + delete topItem; + delete middleItem; + delete bottomItem; + delete canvas; +} + +void tst_qquickcanvas::touchEvent_propagation_data() +{ + QTest::addColumn("acceptEvents"); + QTest::addColumn("enableItem"); + QTest::addColumn("itemOpacity"); + + QTest::newRow("disable events") << false << true << 1.0; + QTest::newRow("disable item") << true << false << 1.0; + QTest::newRow("opacity of 0") << true << true << 0.0; +} + +void tst_qquickcanvas::clearCanvas() +{ + QQuickCanvas *canvas = new QQuickCanvas; + QQuickItem *item = new QQuickItem; + item->setParentItem(canvas->rootItem()); + + QVERIFY(item->canvas() == canvas); + + delete canvas; + + QVERIFY(item->canvas() == 0); + + delete item; +} + +void tst_qquickcanvas::mouseFiltering() +{ + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->show(); + + TestTouchItem *bottomItem = new TestTouchItem(canvas->rootItem()); + bottomItem->setObjectName("Bottom Item"); + bottomItem->setSize(QSizeF(150, 150)); + + TestTouchItem *middleItem = new TestTouchItem(bottomItem); + middleItem->setObjectName("Middle Item"); + middleItem->setPos(QPointF(50, 50)); + middleItem->setSize(QSizeF(150, 150)); + + TestTouchItem *topItem = new TestTouchItem(middleItem); + topItem->setObjectName("Top Item"); + topItem->setPos(QPointF(50, 50)); + topItem->setSize(QSizeF(150, 150)); + + QPoint pos(100, 100); + + QTest::mousePress(canvas, Qt::LeftButton, 0, pos); + QTest::qWait(50); + + // Mouse filtering propagates down the stack, so the + // correct order is + // 1. middleItem filters event + // 2. bottomItem filters event + // 3. topItem receives event + QCOMPARE(middleItem->mousePressId, 1); + QCOMPARE(bottomItem->mousePressId, 2); + QCOMPARE(topItem->mousePressId, 3); +} + +void tst_qquickcanvas::qmlCreation() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + component.loadUrl(TESTDATA("window.qml")); + QObject* created = component.create(); + QVERIFY(created); + + QQuickCanvas* canvas = qobject_cast(created); + QVERIFY(canvas); + QCOMPARE(canvas->clearColor(), QColor(Qt::green)); + + QQuickItem* item = canvas->findChild("item"); + QVERIFY(item); + QCOMPARE(item->canvas(), canvas); +} + +void tst_qquickcanvas::clearColor() +{ + //### Can we examine rendering to make sure it is really blue? + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(250, 250); + canvas->move(100, 100); + canvas->setClearColor(Qt::blue); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + QCOMPARE(canvas->clearColor(), QColor(Qt::blue)); + delete canvas; +} + +QTEST_MAIN(tst_qquickcanvas) + +#include "tst_qquickcanvas.moc" diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.gif b/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.gif new file mode 100644 index 0000000000..45263e0afb Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.gif differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.png b/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.png new file mode 100644 index 0000000000..925e2efc9a Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/anim-gr.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/anim-poster-gr.png b/tests/auto/qtquick2/qquickcanvasitem/data/anim-poster-gr.png new file mode 100644 index 0000000000..6941207373 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/anim-poster-gr.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/background.png b/tests/auto/qtquick2/qquickcanvasitem/data/background.png new file mode 100644 index 0000000000..6db6c6b1b9 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/background.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/broken.png b/tests/auto/qtquick2/qquickcanvasitem/data/broken.png new file mode 100644 index 0000000000..f2581017b4 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/broken.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/ggrr-256x256.png b/tests/auto/qtquick2/qquickcanvasitem/data/ggrr-256x256.png new file mode 100644 index 0000000000..0342e4a384 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/ggrr-256x256.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/green-16x16.png b/tests/auto/qtquick2/qquickcanvasitem/data/green-16x16.png new file mode 100644 index 0000000000..e19a3ffddd Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/green-16x16.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/green-1x1.png b/tests/auto/qtquick2/qquickcanvasitem/data/green-1x1.png new file mode 100644 index 0000000000..862d1dd10c Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/green-1x1.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/green-256x256.png b/tests/auto/qtquick2/qquickcanvasitem/data/green-256x256.png new file mode 100644 index 0000000000..b06945c310 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/green-256x256.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/green-2x2.png b/tests/auto/qtquick2/qquickcanvasitem/data/green-2x2.png new file mode 100644 index 0000000000..adc059449c Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/green-2x2.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/green.png b/tests/auto/qtquick2/qquickcanvasitem/data/green.png new file mode 100644 index 0000000000..28a1faab37 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/green.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/grgr-256x256.png b/tests/auto/qtquick2/qquickcanvasitem/data/grgr-256x256.png new file mode 100644 index 0000000000..b8c7189d62 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/grgr-256x256.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/red-16x16.png b/tests/auto/qtquick2/qquickcanvasitem/data/red-16x16.png new file mode 100644 index 0000000000..9038fef784 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/red-16x16.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/red.png b/tests/auto/qtquick2/qquickcanvasitem/data/red.png new file mode 100644 index 0000000000..a6e195d59c Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/red.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/redtransparent.png b/tests/auto/qtquick2/qquickcanvasitem/data/redtransparent.png new file mode 100644 index 0000000000..75da08c3d6 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/redtransparent.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/rgrg-256x256.png b/tests/auto/qtquick2/qquickcanvasitem/data/rgrg-256x256.png new file mode 100644 index 0000000000..e6fba3daa5 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/rgrg-256x256.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/rrgg-256x256.png b/tests/auto/qtquick2/qquickcanvasitem/data/rrgg-256x256.png new file mode 100644 index 0000000000..7f63515654 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/rrgg-256x256.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/testhelper.js b/tests/auto/qtquick2/qquickcanvasitem/data/testhelper.js new file mode 100644 index 0000000000..bac0210e16 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/testhelper.js @@ -0,0 +1,18 @@ +function comparePixel(ctx,x,y,r,g,b,a, d) +{ + var c = ctx.getImageData(x,y,1,1).data; + if (d === undefined) + d = 0; + r = Math.round(r); + g = Math.round(g); + b = Math.round(b); + a = Math.round(a); + + if (Math.abs(c[0]-r)>d || Math.abs(c[1]-g)>d || Math.abs(c[2]-b)>d || Math.abs(c[3]-a)>d) { + console.log('Pixel compare fail:\nactual :[' + c[0]+','+c[1]+','+c[2]+','+c[3] + ']\nexpected:['+r+','+g+','+b+','+a+'] +/- '+d); + return false; + } + return true; +} + + diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/transparent.png b/tests/auto/qtquick2/qquickcanvasitem/data/transparent.png new file mode 100644 index 0000000000..2b498699a8 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/transparent.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/transparent50.png b/tests/auto/qtquick2/qquickcanvasitem/data/transparent50.png new file mode 100644 index 0000000000..55f8e69325 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/transparent50.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_arc.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_arc.qml new file mode 100644 index 0000000000..6006a5a4c0 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_arc.qml @@ -0,0 +1,487 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper + +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + name: "arc"; when: windowShown + function test_angle_1() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, Math.PI/2, -Math.PI, true); + ctx.fill(); + verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_angle_2() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, -3*Math.PI/2, -Math.PI, true); + ctx.fill(); + verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_angle_3() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (512+1/2)*Math.PI, (1024-1)*Math.PI, true); + ctx.fill(); + //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_angle_4() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (512+1/2)*Math.PI, (1024-1)*Math.PI, false); + ctx.fill(); + verify(Helper.comparePixel(ctx,1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx,98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx,1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx,98,48, 0,255,0,255)); + } + function test_angle_5() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 0); + ctx.arc(100, 0, 150, (1024-1)*Math.PI, (512+1/2)*Math.PI, false); + ctx.fill(); + /*FIXME: + actual :[255,0,0,255] + expected:[0,255,0,255] +/- 0 + */ + //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + + function test_angle_6() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 60, (1024-1)*Math.PI, (512+1/2)*Math.PI, true); + ctx.fill(); + + verify(Helper.comparePixel(ctx,1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx,98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx,1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx,98,48, 0,255,0,255)); + } + + function test_empty() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + /*FIXME: + actual :[255,0,0,255] + expected:[0,255,0,255] +/- 0 + */ + //verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_nonempty() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 5, 0, 2*Math.PI, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_nonfinite() { + skip("FIXME"); + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.arc(Infinity, 0, 50, 0, 2*Math.PI, true); + ctx.arc(-Infinity, 0, 50, 0, 2*Math.PI, true); + ctx.arc(NaN, 0, 50, 0, 2*Math.PI, true); + ctx.arc(0, Infinity, 50, 0, 2*Math.PI, true); + ctx.arc(0, -Infinity, 50, 0, 2*Math.PI, true); + ctx.arc(0, NaN, 50, 0, 2*Math.PI, true); + ctx.arc(0, 0, Infinity, 0, 2*Math.PI, true); + ctx.arc(0, 0, -Infinity, 0, 2*Math.PI, true); + ctx.arc(0, 0, NaN, 0, 2*Math.PI, true); + ctx.arc(0, 0, 50, Infinity, 2*Math.PI, true); + ctx.arc(0, 0, 50, -Infinity, 2*Math.PI, true); + ctx.arc(0, 0, 50, NaN, 2*Math.PI, true); + ctx.arc(0, 0, 50, 0, Infinity, true); + ctx.arc(0, 0, 50, 0, -Infinity, true); + ctx.arc(0, 0, 50, 0, NaN, true); + ctx.arc(Infinity, Infinity, 50, 0, 2*Math.PI, true); + ctx.arc(Infinity, Infinity, Infinity, 0, 2*Math.PI, true); + ctx.arc(Infinity, Infinity, Infinity, Infinity, 2*Math.PI, true); + ctx.arc(Infinity, Infinity, Infinity, Infinity, Infinity, true); + ctx.arc(Infinity, Infinity, Infinity, 0, Infinity, true); + ctx.arc(Infinity, Infinity, 50, Infinity, 2*Math.PI, true); + ctx.arc(Infinity, Infinity, 50, Infinity, Infinity, true); + ctx.arc(Infinity, Infinity, 50, 0, Infinity, true); + ctx.arc(Infinity, 0, Infinity, 0, 2*Math.PI, true); + ctx.arc(Infinity, 0, Infinity, Infinity, 2*Math.PI, true); + ctx.arc(Infinity, 0, Infinity, Infinity, Infinity, true); + ctx.arc(Infinity, 0, Infinity, 0, Infinity, true); + ctx.arc(Infinity, 0, 50, Infinity, 2*Math.PI, true); + ctx.arc(Infinity, 0, 50, Infinity, Infinity, true); + ctx.arc(Infinity, 0, 50, 0, Infinity, true); + ctx.arc(0, Infinity, Infinity, 0, 2*Math.PI, true); + ctx.arc(0, Infinity, Infinity, Infinity, 2*Math.PI, true); + ctx.arc(0, Infinity, Infinity, Infinity, Infinity, true); + ctx.arc(0, Infinity, Infinity, 0, Infinity, true); + ctx.arc(0, Infinity, 50, Infinity, 2*Math.PI, true); + ctx.arc(0, Infinity, 50, Infinity, Infinity, true); + ctx.arc(0, Infinity, 50, 0, Infinity, true); + ctx.arc(0, 0, Infinity, Infinity, 2*Math.PI, true); + ctx.arc(0, 0, Infinity, Infinity, Infinity, true); + ctx.arc(0, 0, Infinity, 0, Infinity, true); + ctx.arc(0, 0, 50, Infinity, Infinity, true); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx,90,45, 0,255,0,255)); + } + function test_end() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(-100, 0); + ctx.arc(-100, 0, 25, -Math.PI/2, Math.PI/2, true); + ctx.lineTo(100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx,50,25, 0,255,0,255)); + } + function test_negative() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + try { var err = false; + ctx.arc(0, 0, -1, 0, 0, true); + } catch (e) { + if (e.code != DOMException.INDEX_SIZE_ERR) + fail("expected exception of type INDEX_SIZE_ERR, got: "+e.message); + err = true; + } finally { + verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.arc(0, 0, -1, 0, 0, true)"); + } + + } + + function test_scale_1() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(2, 0.5); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(25, 50, 56, 0, 2*Math.PI, false); + ctx.fill(); + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-25, 50); + ctx.arc(-25, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(75, 50); + ctx.arc(75, 50, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, -25); + ctx.arc(25, -25, 24, 0, 2*Math.PI, false); + ctx.moveTo(25, 125); + ctx.arc(25, 125, 24, 0, 2*Math.PI, false); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + } + + function test_scale_2() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(100, 100); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 1.2; + ctx.beginPath(); + ctx.arc(0, 0, 0.6, 0, Math.PI/2, false); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_selfintersect_1() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(100, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(0, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_selfintersect_2() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 180; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 25, 0, -Math.PI/2, true); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(100, 0, 25, 0, -Math.PI/2, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 97,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 97,2, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 97,3, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 2,48, 0,255,0,255)); + } + + function test_shape_1() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, false); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_shape_2() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(50, 50, 50, 0, Math.PI, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 20,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + function test_shape_3() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 100; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(0, 50, 50, 0, -Math.PI/2, false); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_shape_4() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 150; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arc(-50, 50, 100, 0, -Math.PI/2, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_shape_5() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 200; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arc(300, 0, 100, 0, 5*Math.PI, false); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_twopie() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, true); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI - 1e-4, false); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 2*Math.PI + 1e-4, false); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + } + + function test_zero() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, true); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.arc(50, 25, 50, 0, 0, false); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,20, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00' + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arc(200, 25, 0, 0, Math.PI, true); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_arcto.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_arcto.qml new file mode 100644 index 0000000000..cc1d88672b --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_arcto.qml @@ -0,0 +1,410 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper + +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + name: "arcTo"; when: windowShown + function test_coincide() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(0, 25, 50, 1000, 1); + ctx.lineTo(100, 25); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 100, 25, 1); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 25, 1); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_collinear() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 200, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, 100, 25, 1); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 10, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 110, 25, 1); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 1); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 0, 25, 1); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.arcTo(0, 25, -200, 25, 1); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_subpath() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.arcTo(100, 50, 200, 50, 0.1); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.arcTo(0, 25, 50, 250, 0.1); + ctx.lineTo(100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_negative() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + try { var err = false; + ctx.arcTo(0, 0, 0, 0, -1); + } catch (e) { + if (e.code != DOMException.INDEX_SIZE_ERR) + fail("expectes INDEX_SIZE_ERR, got: "+e.message); + err = true; + } + finally { + verify(err, "should throw INDEX_SIZE_ERR: ctx.arcTo(0, 0, 0, 0, -1)"); + } + } + + function test_nonfinite() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + skip("FIXME"); + + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.arcTo(Infinity, 50, 0, 50, 0); + ctx.arcTo(-Infinity, 50, 0, 50, 0); + ctx.arcTo(NaN, 50, 0, 50, 0); + ctx.arcTo(0, Infinity, 0, 50, 0); + ctx.arcTo(0, -Infinity, 0, 50, 0); + ctx.arcTo(0, NaN, 0, 50, 0); + ctx.arcTo(0, 50, Infinity, 50, 0); + ctx.arcTo(0, 50, -Infinity, 50, 0); + ctx.arcTo(0, 50, NaN, 50, 0); + ctx.arcTo(0, 50, 0, Infinity, 0); + ctx.arcTo(0, 50, 0, -Infinity, 0); + ctx.arcTo(0, 50, 0, NaN, 0); + ctx.arcTo(0, 50, 0, 50, Infinity); + ctx.arcTo(0, 50, 0, 50, -Infinity); + ctx.arcTo(0, 50, 0, 50, NaN); + ctx.arcTo(Infinity, Infinity, 0, 50, 0); + ctx.arcTo(Infinity, Infinity, Infinity, 50, 0); + ctx.arcTo(Infinity, Infinity, Infinity, Infinity, 0); + ctx.arcTo(Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.arcTo(Infinity, Infinity, Infinity, 50, Infinity); + ctx.arcTo(Infinity, Infinity, 0, Infinity, 0); + ctx.arcTo(Infinity, Infinity, 0, Infinity, Infinity); + ctx.arcTo(Infinity, Infinity, 0, 50, Infinity); + ctx.arcTo(Infinity, 50, Infinity, 50, 0); + ctx.arcTo(Infinity, 50, Infinity, Infinity, 0); + ctx.arcTo(Infinity, 50, Infinity, Infinity, Infinity); + ctx.arcTo(Infinity, 50, Infinity, 50, Infinity); + ctx.arcTo(Infinity, 50, 0, Infinity, 0); + ctx.arcTo(Infinity, 50, 0, Infinity, Infinity); + ctx.arcTo(Infinity, 50, 0, 50, Infinity); + ctx.arcTo(0, Infinity, Infinity, 50, 0); + ctx.arcTo(0, Infinity, Infinity, Infinity, 0); + ctx.arcTo(0, Infinity, Infinity, Infinity, Infinity); + ctx.arcTo(0, Infinity, Infinity, 50, Infinity); + ctx.arcTo(0, Infinity, 0, Infinity, 0); + ctx.arcTo(0, Infinity, 0, Infinity, Infinity); + ctx.arcTo(0, Infinity, 0, 50, Infinity); + ctx.arcTo(0, 50, Infinity, Infinity, 0); + ctx.arcTo(0, 50, Infinity, Infinity, Infinity); + ctx.arcTo(0, 50, Infinity, 50, Infinity); + ctx.arcTo(0, 50, 0, Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); + + } + function test_scale() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.scale(0.1, 1); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-1000, 0); + ctx.fill(); + + skip("FIXME"); + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + } + + function test_shape() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + var tol = 1.5; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25+tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15-tol, -Math.PI/2, 0, false); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 65,45, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.rect(10, 20, 45, 10); + ctx.moveTo(80, 45); + ctx.arc(55, 45, 25-tol, 0, -Math.PI/2, true); + ctx.arc(55, 45, 15+tol, -Math.PI/2, 0, false); + ctx.fill(); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(10, 25); + ctx.arcTo(75, 25, 75, 60, 20); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,20, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 55,21, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 64,22, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 65,21, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 72,28, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 73,27, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 78,36, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,35, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,44, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,45, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 80,46, 0,255,0,255)); + ctx.reset(); + + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.arcTo(-100, 25, 200, 25, 10); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(200, 25, 200, 50, 10); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + + function test_transform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 50); + ctx.translate(100, 0); + ctx.arcTo(50, 50, 50, 0, 50); + ctx.lineTo(-100, 0); + ctx.fill(); + + skip("FIXME"); + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + } + function test_zero() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, 100, 100, 0); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(0, -25); + ctx.arcTo(50, -25, 50, 50, 0); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.lineWidth = 50; + + ctx.strokeStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.arcTo(100, 25, -100, 25, 0); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(100, 25); + ctx.arcTo(200, 25, 50, 25, 0); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_canvas.qml new file mode 100644 index 0000000000..70bedb2131 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_canvas.qml @@ -0,0 +1,274 @@ +import QtQuick 2.0 +import QtTest 1.0 + +Rectangle { + id:container + width:100 + height:100 + Component { + id:canvas + Canvas { + id:c + width:100;height:100 + onPaint: { + context.fillStyle = "red"; + context.fillRect(0, 0, 100, 100); + } + property int paintCount:spyPaint.count + property int paintedCount:spyPainted.count + property int canvasSizeChangedCount:spyCanvasSizeChanged.count + property int tileSizeChangedCount:spyTileSizeChanged.count + property int renderInThreadChangedCount:spyRenderInThreadChanged.count + property int canvasWindowChangedCount:spyCanvasWindowChanged.count + property int renderTargetChangedCount:spyRenderTargetChanged.count + property int imageLoadedCount:spyImageLoaded.count + + SignalSpy {id: spyPaint;target:c;signalName: "paint"} + SignalSpy {id: spyPainted;target:c;signalName: "painted"} + SignalSpy {id: spyCanvasSizeChanged;target:c;signalName: "canvasSizeChanged"} + SignalSpy {id: spyTileSizeChanged;target:c;signalName: "tileSizeChanged"} + SignalSpy {id: spyRenderInThreadChanged;target:c;signalName: "renderInThreadChanged"} + SignalSpy {id: spyCanvasWindowChanged;target:c;signalName: "canvasWindowChanged"} + SignalSpy {id: spyRenderTargetChanged;target:c;signalName: "renderTargetChanged"} + SignalSpy {id: spyImageLoaded;target:c;signalName: "imageLoaded"} + } + } + + TestCase { + name: "Canvas"; when: windowShown + function test_canvasSize() { + var c = canvas.createObject(); + verify(c); + + //by default canvasSize is same with canvas' actual size + // when canvas size changes, canvasSize should be changed as well. + compare(c.canvasSize.width, c.width); + compare(c.canvasSize.height, c.height); + c.width = 20; + compare(c.canvasSize.width, 20); + compare(c.canvasSizeChangedCount, 1); + c.height = 5; + compare(c.canvasSizeChangedCount, 2); + compare(c.canvasSize.height, 5); + + //change canvasSize manually, then canvasSize detaches from canvas + //actual size. + c.canvasSize.width = 100; + compare(c.canvasSizeChangedCount, 3); + compare(c.canvasSize.width, 100); + compare(c.width, 20); + c.canvasSize.height = 50; + compare(c.canvasSizeChangedCount, 4); + compare(c.canvasSize.height, 50); + compare(c.height, 5); + + c.width = 10; + compare(c.canvasSizeChangedCount, 4); + compare(c.canvasSize.width, 100); + compare(c.canvasSize.height, 50); + + c.height = 10; + compare(c.canvasSizeChangedCount, 4); + compare(c.canvasSize.width, 100); + compare(c.canvasSize.height, 50); + c.destroy(); + } + function test_tileSize() { + var c = canvas.createObject(); + verify(c); + + compare(c.tileSize.width, c.width); + compare(c.tileSize.height, c.height); + c.width = 20; + compare(c.tileSize.width, 20); + compare(c.tileSizeChangedCount, 1); + c.height = 5; + compare(c.tileSizeChangedCount, 2); + compare(c.tileSize.height, 5); + + c.tileSize.width = 100; + compare(c.tileSizeChangedCount, 3); + compare(c.tileSize.width, 100); + compare(c.width, 20); + c.tileSize.height = 50; + compare(c.tileSizeChangedCount, 4); + compare(c.tileSize.height, 50); + compare(c.height, 5); + + c.width = 10; + compare(c.tileSizeChangedCount, 4); + compare(c.tileSize.width, 100); + compare(c.tileSize.height, 50); + + c.height = 10; + compare(c.tileSizeChangedCount, 4); + compare(c.tileSize.width, 100); + compare(c.tileSize.height, 50); + c.destroy(); + + } + + function test_canvasWindow() { + var c = canvas.createObject(); + verify(c); + compare(c.canvasWindow.x, 0); + compare(c.canvasWindow.y, 0); + compare(c.canvasWindow.width, c.width); + compare(c.canvasWindow.height, c.height); + + c.width = 20; + compare(c.canvasWindow.width, 20); + compare(c.canvasWindowChangedCount, 1); + c.height = 5; + compare(c.canvasWindowChangedCount, 2); + compare(c.canvasWindow.height, 5); + + c.canvasWindow.x = 5; + c.canvasWindow.y = 6; + c.canvasWindow.width = 10; + c.canvasWindow.height =20; + compare(c.canvasWindowChangedCount, 6); + compare(c.canvasWindow.width, 10); + compare(c.canvasWindow.height, 20); + compare(c.canvasWindow.x, 5); + compare(c.canvasWindow.y, 6); + c.destroy(); + + } + function test_renderTargetAndThread() { + var c = canvas.createObject(); + verify(c); + + compare(c.renderTarget, Canvas.FramebufferObject); + verify(!c.renderInThread); + c.renderTarget = Canvas.Image; + compare(c.renderTargetChangedCount, 1); + compare(c.renderInThreadChangedCount, 0); + + compare(c.renderTarget, Canvas.Image); + verify(!c.renderInThread); + c.renderInThread = true; + verify(c.renderInThread); + compare(c.renderTargetChangedCount, 1); + compare(c.renderInThreadChangedCount, 1); + + ignoreWarning("Canvas: render target does not support thread rendering, force to non-thread rendering mode."); + c.renderTarget = Canvas.FramebufferObject; + verify(!c.renderInThread); + compare(c.renderTargetChangedCount, 2); + compare(c.renderInThreadChangedCount, 2); + c.destroy(); + + } + function test_save() { + var c = canvas.createObject(); + verify(c); + + c.renderTarget = Canvas.Image; + c.requestPaint(); + wait(100); + verify(c.save("c.png")); + c.loadImage("c.png"); + wait(200); + compare(c.imageLoadedCount, 1); + verify(c.isImageLoaded("c.png")); + verify(!c.isImageLoading("c.png")); + verify(!c.isImageError("c.png")); + c.destroy(); + + } + function test_toDataURL_data() { + return [{mimeType:"image/png"}, + {mimeType:"image/bmp"}, + {mimeType:"image/jpeg"}, + {mimeType:"image/x-portable-pixmap"}, + {mimeType:"image/tiff"}, + {mimeType:"image/xpm"}, + ]; + } + + function test_toDataURL(data) { + var c = canvas.createObject(); + verify(c); + + c.renderTarget = Canvas.Image; + var ctx = c.getContext(); + ctx.fillStyle = "red"; + ctx.fillRect(0, 0, c.width, c.height); + + c.requestPaint(); + wait(100); + var dataUrl = c.toDataURL(); + verify(dataUrl != "data:,"); + dataUrl = c.toDataURL("image/invalid"); + verify(dataUrl == "data:,"); + + dataUrl = c.toDataURL(data.mimeType); + verify(dataUrl != "data:,"); + ctx.save(); + ctx.fillStyle = "blue"; + ctx.fillRect(0, 0, c.width, c.height); + ctx.restore(); + c.requestPaint(); + wait(100); + var dataUrl2 = c.toDataURL(data.mimeType); + verify (dataUrl2 != "data:,"); + verify (dataUrl2 != dataUrl); + c.destroy(); + + } + function test_paint() { + var c = canvas.createObject(); + verify(c); + + c.renderTarget = Canvas.Image; + c.renderInThread = true; + var ctx = c.getContext(); + ctx.fillRect(0, 0, c.width, c.height); + c.toDataURL(); + wait(100); + + compare(c.paintedCount, 1); + compare(c.paintCount, 1); + c.destroy(); + + } + function test_loadImage() { + var c = canvas.createObject(); + verify(c); + + c.loadImage("red.png"); + wait(200); + compare(c.imageLoadedCount, 1); + verify(c.isImageLoaded("red.png")); + verify(!c.isImageLoading("red.png")); + verify(!c.isImageError("red.png")); + + c.unloadImage("red.png"); + verify(!c.isImageLoaded("red.png")); + verify(!c.isImageLoading("red.png")); + verify(!c.isImageError("red.png")); + c.destroy(); + + } + + function test_getContext() { + var c = canvas.createObject(); + verify(c); + + var ctx = c.getContext(); + verify(ctx); + compare(ctx.canvas, c); + ctx = c.getContext('2d'); + verify(ctx); + compare(ctx.canvas, c); + ctx = c.getContext('2D'); + verify(ctx); + compare(ctx.canvas, c); + ctx = c.getContext('invalid'); + verify(!ctx); + c.destroy(); + + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_composite.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_composite.qml new file mode 100644 index 0000000000..11e1dce902 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_composite.qml @@ -0,0 +1,380 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget:Canvas.Image + TestCase { + name: "composite"; when: windowShown + function test_clearRect() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-atop'; + ctx.clearRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0)); + } + + function test_clip_data() { + return [ {compsite:"copy"}, + {compsite:"destination-atop"}, + {compsite:"destination-in"}, + {compsite:"destination-out"}, + {compsite:"destination-over"}, + {compsite:"lighter"}, + {compsite:"source-atop"}, + {compsite:"source-in"}, + {compsite:"source-out"}, + {compsite:"source-over"}, + {compsite:"xor"} + ]; + } + + function test_clip(data) { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = data.compsite; + ctx.rect(-20, -20, 10, 10); + ctx.clip(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 50, 50); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + } + + function test_globalAlpha() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + compare(ctx.globalAlpha, 1.0); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 2,253,0,255, 2)); + + ctx.reset(); + ctx.globalAlpha = 0.5; + var a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = Infinity; + compare(ctx.globalAlpha, a); + ctx.globalAlpha = -Infinity; + compare(ctx.globalAlpha, a); + ctx.globalAlpha = NaN; + compare(ctx.globalAlpha, a); + + ctx.globalAlpha = 0.5; + a = ctx.globalAlpha; // might not be exactly 0.5, if it is rounded/quantised, so remember for future comparisons + ctx.globalAlpha = 1.1; + compare(ctx.globalAlpha, a); + ctx.globalAlpha = -0.1; + compare(ctx.globalAlpha, a); + ctx.globalAlpha = 0; + compare(ctx.globalAlpha, 0); + ctx.globalAlpha = 1; + compare(ctx.globalAlpha, 1); + + } + + function test_operation() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'Source-over'; + compare(ctx.globalCompositeOperation, 'xor'); + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'clear'; + compare(ctx.globalCompositeOperation, 'xor'); + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'darker'; + compare(ctx.globalCompositeOperation, 'xor'); + + ctx.reset(); + compare(ctx.globalCompositeOperation, 'source-over'); + + + ctx.reset(); + var modes = ['source-atop', 'source-in', 'source-out', 'source-over', + 'destination-atop', 'destination-in', 'destination-out', 'destination-over', + 'lighter', 'copy', 'xor']; + for (var i = 0; i < modes.length; ++i) + { + ctx.globalCompositeOperation = modes[i]; + compare(ctx.globalCompositeOperation, modes[i]); + } + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'highlight'; + compare(ctx.globalCompositeOperation, 'xor'); + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'source-over\\0'; + compare(ctx.globalCompositeOperation, 'xor'); + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'over'; + compare(ctx.globalCompositeOperation, 'xor'); + + + ctx.reset(); + ctx.globalCompositeOperation = 'xor'; + ctx.globalCompositeOperation = 'nonexistent'; + compare(ctx.globalCompositeOperation, 'xor'); + } + + function test_solid() { + skip("FIXME"); + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = Qt.rgba(0, 1, 1, 1.0); + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'copy'; + ctx.fillStyle = Qt.rgba(1, 1, 0, 1.0); + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-atop'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-in'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-out'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,255,255, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'lighter'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 255,255,255,255, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-atop'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-in'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-out'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + // verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-over'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 255,255,0, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 255, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.fillStyle = 'rgba(255, 255, 0, 1.0)'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + } + function test_transparent() { + + skip("FIXME"); + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'copy'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'copy'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,255,191, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-in'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,95, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-out'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,31, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,145,109,223, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'lighter'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,127,191,255, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-atop'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-in'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-out'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,255,95, 5)); + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-over'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,36,218,223, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'xor'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,63,191,127, 5)); + + } + + function test_uncovered() { + skip("FIXME"); + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'copy'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-atop'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-in'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-in'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + ctx.reset(); + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'source-out'; + ctx.fillStyle = 'rgba(0, 0, 255, 0.75)'; + ctx.translate(0, 25); + ctx.fillRect(0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,0,0,0, 5)); + + } + + } +} \ No newline at end of file diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_drawimage.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_drawimage.qml new file mode 100644 index 0000000000..3752f528be --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_drawimage.qml @@ -0,0 +1,662 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + Component.onCompleted: { + canvas.loadImage('green.png'); + canvas.loadImage('red.png'); + canvas.loadImage('rgrg-256x256.png'); + canvas.loadImage('ggrr-256x256.png'); + canvas.loadImage('broken.png'); + } + + TestCase { + //TODO + name: "image"; when: windowShown + function test_3args() { + //make sure all images are loaded + wait(200); + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.drawImage('green.png', 0, 0); + ctx.drawImage('red.png', -100, 0); + ctx.drawImage('red.png', 100, 0); + ctx.drawImage('red.png', 0, -50); + ctx.drawImage('red.png', 0, 50); + + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + } + function test_5args() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('green.png', 50, 0, 50, 50); + ctx.drawImage('red.png', 0, 0, 50, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + } + function test_9args() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('green.png', 0, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, -100, 0, 100, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 100, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, 0, -50, 100, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 50); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('green.png', 1, 1, 1, 1, 0, 0, 100, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, -50, 0, 50, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, 100, 0, 50, 50); + ctx.drawImage('red.png', 0, 0, 100, 50, 0, -25, 100, 25); + ctx.drawImage('red.png', 0, 0, 100, 50, 0, 50, 100, 25); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('rgrg-256x256.png', 140, 20, 100, 50, 0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('rgrg-256x256.png', 0, 0, 256, 256, 0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 51, 26); + ctx.fillRect(49, 24, 51, 26); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 20,20, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 80,20, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 20,30, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 80,30, 0,255,0,255,2)); + + } + function test_animated() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + //should animated image be supported at all? + } + function test_clip() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(-10, -10, 1, 1); + ctx.clip(); + ctx.drawImage('red.png', 0, 0); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + + } + function test_self() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(50, 0, 50, 50); + ctx.drawImage(canvas, 50, 0); + + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 1, 100, 49); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 1); + ctx.drawImage(canvas, 0, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 2); + + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + + } + + function test_outsidesource() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.drawImage('green.png', 10.5, 10.5, 89.5, 39.5, 0, 0, 100, 50); + ctx.drawImage('green.png', 5.5, 5.5, -5.5, -5.5, 0, 0, 100, 50); + ctx.drawImage('green.png', 100, 50, -5, -5, 0, 0, 100, 50); + try { var err = false; + ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', -0.001, 0, 100, 50, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, -0.001, 100, 50, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100.001, 50, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 100, 50.001, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 50, 0, 50.001, 50, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, -5, 5, 0, 0, 100, 50)"); } + try { var err = false; + ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 0, 0, 5, -5, 0, 0, 100, 50)"); } +// try { var err = false; +// ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50); +// } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.drawImage('red.png', 110, 60, -20, -20, 0, 0, 100, 50)"); } +// verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + } + + function test_null() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + try { var err = false; + ctx.drawImage(null, 0, 0); + } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(null, 0, 0)"); } + + } + + function test_composite() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalCompositeOperation = 'destination-over'; + ctx.drawImage('red.png', 0, 0); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + } + function test_path() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_transform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(100, 0); + ctx.drawImage('red.png', 0, 0); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + } + + function test_imageitem() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + //TODO + } + + function test_imageData() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + //TODO + } + + function test_wrongtype() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + try { var err = false; + ctx.drawImage(undefined, 0, 0); + } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(undefined, 0, 0)"); } + try { var err = false; + ctx.drawImage(0, 0, 0); + } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(0, 0, 0)"); } + try { var err = false; + ctx.drawImage("", 0, 0); + } catch (e) { if (e.code != DOMException.TYPE_MISMATCH_ERR) fail("Failed assertion: expected exception of type TYPE_MISMATCH_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type TYPE_MISMATCH_ERR: ctx.drawImage(\"\", 0, 0)"); } + } + + function test_nonfinite() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var red = 'red.png'; + ctx.drawImage(red, Infinity, 0); + ctx.drawImage(red, -Infinity, 0); + ctx.drawImage(red, NaN, 0); + ctx.drawImage(red, 0, Infinity); + ctx.drawImage(red, 0, -Infinity); + ctx.drawImage(red, 0, NaN); + ctx.drawImage(red, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50); + ctx.drawImage(red, -Infinity, 0, 100, 50); + ctx.drawImage(red, NaN, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, -Infinity, 100, 50); + ctx.drawImage(red, 0, NaN, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, -Infinity, 50); + ctx.drawImage(red, 0, 0, NaN, 50); + ctx.drawImage(red, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, -Infinity); + ctx.drawImage(red, 0, 0, 100, NaN); + ctx.drawImage(red, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, -Infinity, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, NaN, 0, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, -Infinity, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, NaN, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, -Infinity, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, NaN, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, -Infinity, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, NaN, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, -Infinity, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, NaN, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, -Infinity, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, NaN, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, -Infinity, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, NaN, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, -Infinity); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, 100, NaN); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, Infinity, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, Infinity, 100, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, Infinity, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, Infinity, 0, 100, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, Infinity, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, Infinity, 100, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, Infinity, 50, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, Infinity, 0, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, 50); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, Infinity, 0, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, 50); + ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, Infinity, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, 0, Infinity, 100, Infinity); + ctx.drawImage(red, 0, 0, 100, 50, 0, 0, Infinity, Infinity); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + + function test_negative() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('ggrr-256x256.png', 100, 78, 50, 50, 0, 50, 50, -50); + ctx.drawImage('ggrr-256x256.png', 100, 128, 50, -50, 100, 50, -50, -50); +// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('ggrr-256x256.png', 0, 178, 50, -100, 0, 0, 50, 100); + ctx.drawImage('ggrr-256x256.png', 0, 78, 50, 100, 50, 100, 50, -100); +// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.drawImage('ggrr-256x256.png', 100, 78, -100, 50, 0, 0, 50, 50); + ctx.drawImage('ggrr-256x256.png', 100, 128, -100, -50, 50, 0, 50, 50); +// verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,1, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 51,48, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255,2)); +// verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255,2)); + + } + + function test_canvas() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + var canvas2 = Qt.createQmlObject("import QtQuick 2.0; Canvas{renderTarget:Canvas.Image}", canvas); + canvas2.width = 100; + canvas2.height = 50; + var ctx2 = canvas2.getContext('2d'); + ctx2.fillStyle = '#0f0'; + ctx2.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.drawImage(canvas2, 0, 0); + + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255,2)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255,2)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255,2)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255,2)); + + } + + function test_broken() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + var img = 'broken.png'; + verify(!img.complete); + ctx.drawImage(img, 0, 0); + } + + function test_alpha() { + var ctx=canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.globalAlpha = 0; + ctx.drawImage('red.png', 0, 0); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255, 2)); + + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillStyle.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillStyle.qml new file mode 100644 index 0000000000..8f5a78cec0 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillStyle.qml @@ -0,0 +1,113 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper + +Canvas { + id:canvas; width:1;height:1;renderTarget:Canvas.Image + TestCase { + name: "fillStyle"; when: windowShown + function test_default() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + verify(ctx.fillStyle, "#000000"); + ctx.clearRect(0, 0, 1, 1); + compare(ctx.fillStyle, "#000000"); + } + function test_get() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#fa0'; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = Qt.rgba(0,0,0,0); + compare(ctx.fillStyle, 'rgba(0, 0, 0, 0.0)'); + } + function test_hex() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + compare(ctx.fillStyle, '#ff0000'); + ctx.fillStyle = "#0f0"; + compare(ctx.fillStyle, '#00ff00'); + ctx.fillStyle = "#0fF"; + compare(ctx.fillStyle, '#00ffff'); + ctx.fillStyle = "#0aCCfb"; + compare(ctx.fillStyle, '#0accfb'); + + } + function test_invalid() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#fa0'; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "invalid"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "rgb (1, 2, 3)"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = '#fa0'; + + ctx.fillStyle = "rgba(3, 1, 2)"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "rgb((3,4,1)"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "rgb(1, 3, 4, 0.5)"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "hsl(2, 3, 4, 0.8)"; + compare(ctx.fillStyle, '#ffaa00'); + ctx.fillStyle = "hsl(2, 3, 4"; + compare(ctx.fillStyle, '#ffaa00'); + } + function test_saverestore() { + var ctx = canvas.getContext('2d'); + var old = ctx.fillStyle; + ctx.save(); + ctx.fillStyle = "#ffaaff"; + ctx.restore(); + compare(ctx.fillStyle, old); + + ctx.fillStyle = "#ffcc88"; + old = ctx.fillStyle; + ctx.save(); + compare(ctx.fillStyle, old); + ctx.restore(); + } + function test_namedColor() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = "red"; + ctx.fillRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,255,0,0,255)); + + ctx.fillStyle = "black"; + ctx.fillRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,0,0,0,255)); + + ctx.fillStyle = "white"; + ctx.fillRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,255,255,255,255)); + } + function test_rgba() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = "rgb(-100, 300, 255)"; + compare(ctx.fillStyle, "#00ffff"); + ctx.fillStyle = "rgba(-100, 300, 255, 0.0)"; + compare(ctx.fillStyle, "rgba(0, 255, 255, 0.0)"); + ctx.fillStyle = "rgb(-10%, 110%, 50%)"; + compare(ctx.fillStyle, "#00ff80"); + + ctx.clearRect(0, 0, 1, 1); + ctx.fillStyle = 'rgba(0%, 100%, 0%, 0.499)'; + ctx.fillRect(0, 0, 1, 1); + verify(Helper.comparePixel(ctx, 0,0, 0,255,0,127)); + } + + function test_hsla() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = "hsla(120, 100%, 50%, 0.499)"; + ctx.fillRect(0, 0, 1, 1); + verify(Helper.comparePixel(ctx,0,0,0,255,0,127)); + } + + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillrect.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillrect.qml new file mode 100644 index 0000000000..2061647268 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_fillrect.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 +import QtTest 1.0 + +Canvas { + id:canvas; width:1;height:1; renderTarget:Canvas.Image + onPaint: { + context.fillStyle = "red"; + context.fillRect(0, 0, canvas.width, canvas.height); + } + TestCase { + name: "FillRect"; when: windowShown + function test_fillRect() { + var ctx = canvas.getContext('2d'); + var imageData = ctx.getImageData(0, 0, 1, 1); + var d = imageData.data; + verify(d.length == 4); + verify(d[0] == 255); + verify(d[1] == 0); + verify(d[2] == 0); + verify(d[3] == 255); + } + } +} \ No newline at end of file diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_gradient.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_gradient.qml new file mode 100644 index 0000000000..d454c2efe1 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_gradient.qml @@ -0,0 +1,981 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + name: "gradient"; when: windowShown + function test_basic() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 0, 50); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + } + + function test_interpolate() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#ff0'; + ctx.fillRect(0, 0, 100, 50); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(0,0,255, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3)); + //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3)); + //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3)); + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,255,3)); + //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,3)); + //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,255,3)); + + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, 'rgba(255,255,0, 0)'); + g.addColorStop(1, 'rgba(0,0,255, 1)'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 25,25, 191,191,63,63,3)); + //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,127,3)); + //verify(Helper.comparePixel(ctx, 75,25, 63,63,191,191,3)); + + ctx.reset(); + canvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.5, '#0ff'); + g.addColorStop(1, '#f0f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + //verify(Helper.comparePixel(ctx, 50,25, 127,255,127,255,3)); + //verify(Helper.comparePixel(ctx, 100,25, 0,255,255,255,3)); + //verify(Helper.comparePixel(ctx, 150,25, 127,127,255,255,3)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(25, 0, 75, 0); + g.addColorStop(0.4, '#0f0'); + g.addColorStop(0.6, '#0f0'); + + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 20,25, 0,255,0,255,2)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255,2)); + + + ctx.reset(); + ctx.canvas.width = 200; + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0, '#ff0'); + g.addColorStop(0.25, '#00f'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.25, '#ff0'); + g.addColorStop(0.5, '#00f'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.75, '#00f'); + g.addColorStop(0.75, '#f00'); + g.addColorStop(0.75, '#ff0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.5, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 200, 50); + //verify(Helper.comparePixel(ctx, 49,25, 0,0,255,255,16)); + //verify(Helper.comparePixel(ctx, 51,25, 255,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 99,25, 0,0,255,255,16)); + //verify(Helper.comparePixel(ctx, 101,25, 255,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 149,25, 0,0,255,255,16)); + //verify(Helper.comparePixel(ctx, 151,25, 255,255,0,255,16)); + ctx.canvas.width = 100; + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 100, 0); + var ps = [ 0, 1/10, 1/4, 1/3, 1/2, 3/4, 1 ]; + for (var p = 0; p < ps.length; ++p) + { + g.addColorStop(ps[p], '#0f0'); + for (var i = 0; i < 15; ++i) + g.addColorStop(ps[p], '#f00'); + g.addColorStop(ps[p], '#0f0'); + } + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 30,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 40,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 60,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 80,25, 0,255,0,255)); + + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 100, 0); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 0, 50); + g.addColorStop(0, '#ff0'); + g.addColorStop(1, '#00f'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,12, 191,191,63,255,10)); + //verify(Helper.comparePixel(ctx, 50,25, 127,127,127,255,5)); + //verify(Helper.comparePixel(ctx, 50,37, 63,63,191,255,10)); + + + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction) + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 40,20, 0,255,0,255,2)); + + + + } + function test_radial() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var g = ctx.createRadialGradient(0, 100, 40, 100, 100, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(210, 25, 100, 230, 25, 101); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(210, 25, 100, 230, 25, 100); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(311, 25, 10, 210, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(30+tol, 40); + ctx.lineTo(110, -20+tol); + ctx.lineTo(110, 100-tol); + ctx.fill(); + + g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(30+10*5/2, 40, 10*3/2, 30+10*15/4, 40, 10*9/4); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.moveTo(30-tol, 40); + ctx.lineTo(110, -20-tol); + ctx.lineTo(110, 100+tol); + ctx.fill(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(230, 25, 100, 100, 25, 101); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(50, 25, 20, 50, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(50, 25, 100, 50, 25, 200); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(50, 25, 200, 50, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(0.993, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + try { var err = false; + ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -0.1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: ctx.createRadialGradient(0, 0, -0.1, 0, 0, -0.1)"); } + + + ctx.reset(); + + + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(-Infinity, 0, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(NaN, 0, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, -Infinity, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, NaN, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, NaN, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, -Infinity, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, NaN, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, NaN, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, -Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, NaN, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, NaN, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, -Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, NaN, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, NaN, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, -Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, 0, NaN); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, 0, NaN)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, Infinity, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, Infinity, 1, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, Infinity, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(Infinity, 0, 1, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, Infinity, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, Infinity, 1, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, Infinity, 0, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, 1)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, Infinity, 0, Infinity)"); } + try { var err = false; + ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createRadialGradient(0, 0, 1, 0, Infinity, Infinity)"); } + + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(200, 25, 10, 200, 25, 20); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#0f0'); + ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(200, 25, 20, 200, 25, 10); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.001, '#f00'); + g.addColorStop(1, '#f00');ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(150, 25, 50, 200, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(-80, 25, 70, 0, 25, 150); + g.addColorStop(0, '#f00'); + g.addColorStop(0.01, '#0f0'); + g.addColorStop(0.99, '#0f0');g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + g = ctx.createRadialGradient(120, -15, 25, 140, -30, 50); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g;ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255));//verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(50, 25);ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + ctx.reset(); + ctx.translate(100, 0); + g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0');g.addColorStop(0.5, '#0f0'); + g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g;ctx.translate(-50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + + ctx.reset(); + g = ctx.createRadialGradient(0, 0, 0, 0, 0, 11.2); + g.addColorStop(0, '#0f0'); + g.addColorStop(0.5, '#0f0');g.addColorStop(0.51, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50);ctx.translate(50, 25); + ctx.scale(10, 10); + ctx.fillRect(-5, -2.5, 10, 5); + //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255));//verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + + } + function test_linear() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + try { var err = false; + ctx.createLinearGradient(Infinity, 0, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(-Infinity, 0, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(-Infinity, 0, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(NaN, 0, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(NaN, 0, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, Infinity, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, -Infinity, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, -Infinity, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, NaN, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, NaN, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, Infinity, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, -Infinity, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, -Infinity, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, NaN, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, NaN, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, 1, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, 1, -Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, -Infinity)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, 1, NaN); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, 1, NaN)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, Infinity, 1, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, 0)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, Infinity, Infinity, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, 0)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, Infinity, 1, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, Infinity, 1, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, 0, Infinity, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, 0)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, Infinity, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(Infinity, 0, 1, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(Infinity, 0, 1, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(0, Infinity, Infinity, 0); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, 0)"); } + try { var err = false; + ctx.createLinearGradient(0, Infinity, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, Infinity, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(0, Infinity, 1, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, Infinity, 1, Infinity)"); } + try { var err = false; + ctx.createLinearGradient(0, 0, Infinity, Infinity); + } catch (e) { if (e.code != DOMException.NOT_SUPPORTED_ERR) fail("Failed assertion: expected exception of type NOT_SUPPORTED_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type NOT_SUPPORTED_ERR: ctx.createLinearGradient(0, 0, Infinity, Infinity)"); } + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + ctx.reset(); + ctx.translate(100, 0); + g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.translate(-150, 0); + ctx.fillRect(50, 0, 100, 50); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + + ctx.reset(); + g = ctx.createLinearGradient(0, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(0.25, '#0f0'); + g.addColorStop(0.75, '#0f0'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + ctx.translate(-50, 0); + ctx.fillRect(50, 0, 100, 50); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + + } + function test_object() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + var g1 = ctx.createLinearGradient(0, 0, 100, 0); + var g2 = ctx.createLinearGradient(0, 0, 100, 0); + ctx.fillStyle = g1; + + + ctx.reset(); + var g = ctx.createLinearGradient(0, 0, 100, 0); + try { var err = false; + g.addColorStop(0, ""); + } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, \"\")"); } + try { var err = false; + g.addColorStop(0, 'undefined'); + } catch (e) { if (e.code != DOMException.SYNTAX_ERR) fail("Failed assertion: expected exception of type SYNTAX_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type SYNTAX_ERR: g.addColorStop(0, 'undefined')"); } + + + ctx.reset(); + g = ctx.createLinearGradient(0, 0, 100, 0); + try { var err = false; + g.addColorStop(-1, '#000'); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-1, '#000')"); } + try { var err = false; + g.addColorStop(2, '#000'); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(2, '#000')"); } + try { var err = false; + g.addColorStop(Infinity, '#000'); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(Infinity, '#000')"); } + try { var err = false; + g.addColorStop(-Infinity, '#000'); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(-Infinity, '#000')"); } + try { var err = false; + g.addColorStop(NaN, '#000'); + } catch (e) { if (e.code != DOMException.INDEX_SIZE_ERR) fail("Failed assertion: expected exception of type INDEX_SIZE_ERR, got: "+e.message); err = true; } finally { verify(err, "should throw exception of type INDEX_SIZE_ERR: g.addColorStop(NaN, '#000')"); } + + + ctx.reset(); + g = ctx.createLinearGradient(-100, 0, 200, 0); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + g.addColorStop(0.1, '#0f0'); + g.addColorStop(0.9, '#0f0'); + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255,2)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + g = ctx.createRadialGradient(120, 25, 10, 211, 25, 100); + g.addColorStop(0, '#f00'); + g.addColorStop(1, '#f00'); + ctx.fillStyle = g; + ctx.fillRect(0, 0, 100, 50); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,25, 0,255,0,255,16)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + + } + + function test_conical() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + var g = ctx.createConicalGradient(10, 10, 50); + //TODO + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_line.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_line.qml new file mode 100644 index 0000000000..baf9987ce3 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_line.qml @@ -0,0 +1,831 @@ +import QtQuick 2.0 +import QtTest 1.0 +import"testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50;renderTarget: Canvas.Image + TestCase { + name: "line"; when: windowShown + function test_default() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + compare(ctx.lineWidth, 1); + compare(ctx.lineCap, 'butt'); + compare(ctx.lineJoin, 'miter'); + compare(ctx.miterLimit, 10); + } + + function test_cross() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'bevel'; + + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(110, 50); + ctx.lineTo(110, 60); + ctx.lineTo(100, 60); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + } + + function test_join() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineJoin = 'bevel'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.lineTo(40-tol, 20); + ctx.lineTo(30, 10+tol); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.lineTo(90+tol, 20); + ctx.lineTo(80, 10-tol); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 34,16, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 34,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 35,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 36,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 84,16, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 84,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 85,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 86,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255)); + + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.closePath(); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + + ctx.reset(); + ctx.lineJoin = 'bevel' + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'invalid'; + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'ROUND'; + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round\\0'; + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'round '; + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = ""; + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'bevel'; + ctx.lineJoin = 'butt'; + compare(ctx.lineJoin, 'bevel'); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 30, 20); + ctx.fillRect(20, 10, 20, 30); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 30, 20); + ctx.fillRect(70, 10, 20, 30); + + verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 39,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 40,10, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 41,9, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 42,8, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 89,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 91,9, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 92,8, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'miter'; + ctx.lineWidth = 200; + + ctx.beginPath(); + ctx.moveTo(100, 50); + ctx.lineTo(100, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 50); + ctx.lineTo(100, 50); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 300; + ctx.lineJoin = 'round'; + ctx.beginPath(); + ctx.moveTo(-100, 25); + ctx.lineTo(0, 25); + ctx.lineTo(-100, 25); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineJoin = 'round'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.fillRect(10, 10, 20, 20); + ctx.fillRect(20, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(30, 20); + ctx.arc(30, 20, 10-tol, 0, 2*Math.PI, true); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(10, 20); + ctx.lineTo(30, 20); + ctx.lineTo(30, 40); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(60, 20); + ctx.lineTo(80, 20); + ctx.lineTo(80, 40); + ctx.stroke(); + + ctx.fillRect(60, 10, 20, 20); + ctx.fillRect(70, 20, 20, 20); + ctx.beginPath(); + ctx.moveTo(80, 20); + ctx.arc(80, 20, 10+tol, 0, 2*Math.PI, true); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 36,14, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 36,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 37,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 38,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 38,12, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 86,14, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 86,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 87,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 88,13, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 88,12, 0,255,0,255)); + + ctx.reset(); + ctx.lineJoin = 'bevel' + compare(ctx.lineJoin, 'bevel'); + + ctx.lineJoin = 'round'; + compare(ctx.lineJoin, 'round'); + + ctx.lineJoin = 'miter'; + compare(ctx.lineJoin, 'miter'); + + } + function test_miter() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 2.614; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 2.613; + ctx.beginPath(); + ctx.moveTo(100, 1000); + ctx.lineTo(100, 100); + ctx.lineTo(1000, 1000); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); // slightly non-right-angle to avoid being a special case + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.miterLimit = 1.5; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = 1.5; + ctx.miterLimit = 0; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = 1.5; + ctx.miterLimit = -1; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = 1.5; + ctx.miterLimit = Infinity; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = 1.5; + ctx.miterLimit = -Infinity; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = 1.5; + ctx.miterLimit = NaN; + compare(ctx.miterLimit, 1.5); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.strokeRect(100, 25, 200, 0); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 1600; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.083; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.082; + ctx.beginPath(); + ctx.moveTo(800, 10000); + ctx.lineTo(800, 300); + ctx.lineTo(10000, -8900); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#f00'; + ctx.miterLimit = 1.414; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 200); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + ctx.reset(); + ctx.miterLimit = 1.5; + compare(ctx.miterLimit, 1.5); + + ctx.miterLimit = "1e1"; + compare(ctx.miterLimit, 10); + + ctx.miterLimit = 1/1024; + compare(ctx.miterLimit, 1/1024); + + ctx.miterLimit = 1000; + compare(ctx.miterLimit, 1000); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + + ctx.strokeStyle = '#0f0'; + ctx.miterLimit = 1.416; + ctx.beginPath(); + ctx.moveTo(200, 1000); + ctx.lineTo(200, 200); + ctx.lineTo(1000, 201); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + + + } + function test_width() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 20; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + + verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255)); + + ctx.reset(); + ctx.lineWidth = 1.5; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = 1.5; + ctx.lineWidth = 0; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = 1.5; + ctx.lineWidth = -1; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = 1.5; + ctx.lineWidth = Infinity; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = 1.5; + ctx.lineWidth = -Infinity; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = 1.5; + ctx.lineWidth = NaN; + compare(ctx.lineWidth, 1.5); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(50, 50); + ctx.strokeStyle = '#0f0'; + ctx.moveTo(0, 0.5); + ctx.lineTo(2, 0.5); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,5, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,45, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 4; + // Draw a green line over a red box, to check the line is not too small + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.save(); + ctx.scale(5, 1); + ctx.beginPath(); + ctx.moveTo(5, 15); + ctx.lineTo(5, 35); + ctx.stroke(); + ctx.restore(); + + // Draw a green box over a red line, to check the line is not too large + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.save(); + ctx.scale(-5, 1); + ctx.beginPath(); + ctx.moveTo(-15, 15); + ctx.lineTo(-15, 35); + ctx.stroke(); + ctx.restore(); + ctx.fillRect(65, 15, 20, 20); + + verify(Helper.comparePixel(ctx, 14,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 15,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 16,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 34,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 35,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 36,25, 0,255,0,255)); + + //verify(Helper.comparePixel(ctx, 64,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 65,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 66,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 84,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 85,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 86,25, 0,255,0,255)); + + ctx.reset(); + ctx.lineWidth = 1.5; + compare(ctx.lineWidth, 1.5); + + ctx.lineWidth = "1e1"; + compare(ctx.lineWidth, 10); + + ctx.lineWidth = 1/1024; + compare(ctx.lineWidth, 1/1024); + + ctx.lineWidth = 1000; + compare(ctx.lineWidth, 1000); + + } + function test_cap() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineCap = 'butt'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 15, 20, 20); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 15, 20, 20); + + verify(Helper.comparePixel(ctx, 25,14, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,16, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,34, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,35, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,36, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 75,14, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,15, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,16, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,34, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,36, 0,255,0,255)); + + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.closePath(); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + ctx.reset(); + + ctx.lineCap = 'butt' + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = 'invalid'; + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = 'ROUND'; + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = 'round\\0'; + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = 'round '; + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = ""; + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'butt'; + ctx.lineCap = 'bevel'; + compare(ctx.lineCap, 'butt'); + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineJoin = 'bevel'; + ctx.lineCap = 'square'; + ctx.lineWidth = 400; + + ctx.beginPath(); + ctx.moveTo(200, 200); + ctx.lineTo(200, 1000); + ctx.lineTo(1000, 1000); + ctx.lineTo(1000, 200); + ctx.lineTo(200, 200); + ctx.stroke(); + + //FIXME:!!! + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 48,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + var tol = 1; // tolerance to avoid antialiasing artifacts + + ctx.lineCap = 'round'; + ctx.lineWidth = 20; + + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + + ctx.beginPath(); + ctx.moveTo(35-tol, 15); + ctx.arc(25, 15, 10-tol, 0, Math.PI, true); + ctx.arc(25, 35, 10-tol, Math.PI, 0, true); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(85+tol, 15); + ctx.arc(75, 15, 10+tol, 0, Math.PI, true); + ctx.arc(75, 35, 10+tol, Math.PI, 0, true); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 17,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 32,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 17,43, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,43, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 32,43, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 67,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 82,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 67,43, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,43, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 82,43, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineCap = 'square'; + ctx.lineWidth = 20; + + ctx.fillStyle = '#f00'; + ctx.strokeStyle = '#0f0'; + ctx.fillRect(15, 5, 20, 40); + ctx.beginPath(); + ctx.moveTo(25, 15); + ctx.lineTo(25, 35); + ctx.stroke(); + + ctx.fillStyle = '#0f0'; + ctx.strokeStyle = '#f00'; + ctx.beginPath(); + ctx.moveTo(75, 15); + ctx.lineTo(75, 35); + ctx.stroke(); + ctx.fillRect(65, 5, 20, 40); + + verify(Helper.comparePixel(ctx, 25,4, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,5, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,44, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,45, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,46, 0,255,0,255)); + + verify(Helper.comparePixel(ctx, 75,4, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,5, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,6, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,44, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,45, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,46, 0,255,0,255)); + + ctx.reset(); + ctx.lineCap = 'butt' + compare(ctx.lineCap, 'butt'); + + ctx.lineCap = 'round'; + compare(ctx.lineCap, 'round'); + + ctx.lineCap = 'square'; + compare(ctx.lineCap, 'square'); + + } + } +} \ No newline at end of file diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_path.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_path.qml new file mode 100644 index 0000000000..b04ccf5458 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_path.qml @@ -0,0 +1,1443 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper + +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + name: "path"; when: windowShown + + function test_basic() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 100, 50); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + canvas.width = 100; + ctx.rect(0, 0, 100, 50); + canvas.width = 100; + ctx.fillStyle = '#f00'; + ctx.fill(); + //verify(Helper.comparePixel(ctx, 20,20, 0,0,0,0)); + } + function test_beginPath() { + var ctx = canvas.getContext('2d'); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_closePath() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.closePath(); + ctx.fillStyle = '#f00'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.closePath(); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -1000); + ctx.closePath(); + ctx.lineTo(1000, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_isPointInPath() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.arc(50, 25, 10, 0, Math.PI, false); + verify(!ctx.isPointInPath(50, 10)); + verify(!ctx.isPointInPath(50, 20)); + //verify(!ctx.isPointInPath(50, 30)); + verify(!ctx.isPointInPath(50, 40)); + verify(!ctx.isPointInPath(30, 20)); + verify(!ctx.isPointInPath(70, 20)); + verify(!ctx.isPointInPath(30, 30)); + verify(!ctx.isPointInPath(70, 30)); + + ctx.reset(); + ctx.rect(0, 0, 20, 20); + verify(ctx.isPointInPath(10, 10)); + verify(!ctx.isPointInPath(30, 10)); + + ctx.reset(); + ctx.rect(20, 0, 20, 20); + //verify(ctx.isPointInPath(10, 10)); + verify(ctx.isPointInPath(30, 10)); + + ctx.reset(); + ctx.bezierCurveTo(50, -50, 50, 100, 75, 25); + verify(!ctx.isPointInPath(25, 20)); + verify(!ctx.isPointInPath(25, 30)); + //verify(ctx.isPointInPath(30, 20)); + verify(!ctx.isPointInPath(30, 30)); + //verify(!ctx.isPointInPath(40, 2)); + //verify(ctx.isPointInPath(40, 20)); + verify(!ctx.isPointInPath(40, 30)); + verify(!ctx.isPointInPath(40, 47)); + //verify(ctx.isPointInPath(45, 20)); + //verify(!ctx.isPointInPath(45, 30)); + //verify(!ctx.isPointInPath(55, 20)); + //verify(ctx.isPointInPath(55, 30)); + verify(!ctx.isPointInPath(60, 2)); + //verify(!ctx.isPointInPath(60, 20)); + verify(ctx.isPointInPath(60, 30)); + verify(!ctx.isPointInPath(60, 47)); + verify(!ctx.isPointInPath(70, 20)); + verify(ctx.isPointInPath(70, 30)); + verify(!ctx.isPointInPath(75, 20)); + verify(!ctx.isPointInPath(75, 30)); + + ctx.reset(); + ctx.arc(50, 25, 10, 0, 7, false); + verify(!ctx.isPointInPath(50, 10)); + //verify(ctx.isPointInPath(50, 20)); + //verify(ctx.isPointInPath(50, 30)); + verify(!ctx.isPointInPath(50, 40)); + verify(!ctx.isPointInPath(30, 20)); + verify(!ctx.isPointInPath(70, 20)); + verify(!ctx.isPointInPath(30, 30)); + //verify(!ctx.isPointInPath(70, 30)); + + ctx.reset(); + ctx.rect(0, 0, 20, 20); + verify(ctx.isPointInPath(0, 0)); + verify(ctx.isPointInPath(10, 0)); + //verify(ctx.isPointInPath(20, 0)); + //verify(ctx.isPointInPath(20, 10)); + //verify(ctx.isPointInPath(20, 20)); + //verify(ctx.isPointInPath(10, 20)); + //verify(ctx.isPointInPath(0, 20)); + verify(ctx.isPointInPath(0, 10)); + verify(!ctx.isPointInPath(10, -0.01)); + verify(!ctx.isPointInPath(10, 20.01)); + verify(!ctx.isPointInPath(-0.01, 10)); + //verify(!ctx.isPointInPath(20.01, 10)); + + ctx.reset(); + verify(!ctx.isPointInPath(0, 0)); + + + ctx.reset(); + ctx.rect(-100, -50, 200, 100); + //verify(ctx.isPointInPath(Infinity, 0)); + //verify(ctx.isPointInPath(-Infinity, 0)); + //verify(ctx.isPointInPath(NaN, 0)); + //verify(ctx.isPointInPath(0, Infinity)); + //verify(ctx.isPointInPath(0, -Infinity)); + //verify(ctx.isPointInPath(0, NaN)); + //verify(ctx.isPointInPath(NaN, NaN)); + + ctx.reset(); + ctx.rect(0, -100, 20, 20); + ctx.rect(20, -10, 20, 20); + verify(!ctx.isPointInPath(10, -110)); + verify(ctx.isPointInPath(10, -90)); + verify(!ctx.isPointInPath(10, -70)); + //verify(!ctx.isPointInPath(30, -20)); + //verify(ctx.isPointInPath(30, 0)); + //verify(!ctx.isPointInPath(30, 20)); + + ctx.reset(); + ctx.rect(0, 0, 20, 20); + ctx.beginPath(); + ctx.rect(20, 0, 20, 20); + ctx.closePath(); + ctx.rect(40, 0, 20, 20); + verify(!ctx.isPointInPath(10, 10)); + verify(ctx.isPointInPath(30, 10)); + verify(ctx.isPointInPath(50, 10)); + + ctx.reset(); + ctx.translate(50, 0); + ctx.rect(0, 0, 20, 20); + verify(!ctx.isPointInPath(-40, 10)); + verify(!ctx.isPointInPath(10, 10)); + //verify(!ctx.isPointInPath(49, 10)); + verify(ctx.isPointInPath(51, 10)); + verify(ctx.isPointInPath(69, 10)); + verify(!ctx.isPointInPath(71, 10)); + + ctx.reset(); + ctx.rect(50, 0, 20, 20); + ctx.translate(50, 0); + verify(!ctx.isPointInPath(-40, 10)); + verify(!ctx.isPointInPath(10, 10)); + //verify(!ctx.isPointInPath(49, 10)); + verify(ctx.isPointInPath(51, 10)); + verify(ctx.isPointInPath(69, 10)); + verify(!ctx.isPointInPath(71, 10)); + + ctx.reset(); + ctx.scale(-1, 1); + ctx.rect(-70, 0, 20, 20); + verify(!ctx.isPointInPath(-40, 10)); + verify(!ctx.isPointInPath(10, 10)); + //verify(!ctx.isPointInPath(49, 10)); + verify(ctx.isPointInPath(51, 10)); + verify(ctx.isPointInPath(69, 10)); + verify(!ctx.isPointInPath(71, 10)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(20, 0); + ctx.lineTo(20, 20); + ctx.lineTo(0, 20); + verify(ctx.isPointInPath(10, 10)); + //verify(!ctx.isPointInPath(30, 10)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(50, 0); + ctx.lineTo(50, 50); + ctx.lineTo(0, 50); + ctx.lineTo(0, 0); + ctx.lineTo(10, 10); + ctx.lineTo(10, 40); + ctx.lineTo(40, 40); + ctx.lineTo(40, 10); + ctx.lineTo(10, 10); + + verify(ctx.isPointInPath(5, 5)); + verify(ctx.isPointInPath(25, 5)); + verify(ctx.isPointInPath(45, 5)); + verify(ctx.isPointInPath(5, 25)); + verify(!ctx.isPointInPath(25, 25)); + verify(ctx.isPointInPath(45, 25)); + verify(ctx.isPointInPath(5, 45)); + verify(ctx.isPointInPath(25, 45)); + verify(ctx.isPointInPath(45, 45)); + } + + + function test_fill() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + ctx.reset(); + ctx.fillStyle = '#00f'; + ctx.fillRect(0, 0, 100, 50); + + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + //verify(Helper.comparePixel(ctx, 90,10, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 10,40, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.rect(0, 0, 100, 50); + ctx.closePath(); + ctx.rect(10, 10, 80, 30); + ctx.fill(); + + //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255, 1)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fill(); + + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(-20, -20); + ctx.lineTo(120, -20); + ctx.lineTo(120, 70); + ctx.lineTo(-20, 70); + ctx.lineTo(-20, -20); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + function test_stroke() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(40, 25); + ctx.moveTo(60, 25); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#000'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; + ctx.lineWidth = 50; + ctx.moveTo(0, 20); + ctx.lineTo(100, 20); + ctx.moveTo(0, 30); + ctx.lineTo(100, 30); + ctx.stroke(); + + //verify(Helper.comparePixel(ctx, 50,25, 0,127,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arcTo(50, 25, 150, 25, 10); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.arc(50, 25, 10, 0, 0, false); + ctx.stroke(); + + // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.closePath(); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 400; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.4; + + ctx.beginPath(); + ctx.moveTo(-1000, 200, 0, 0); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 200); + ctx.lineTo(-100, 1000); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.quadraticCurveTo(50, 25, 50, 25); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.moveTo(50, 25); + ctx.lineTo(50, 25); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.lineCap = 'round'; + ctx.lineJoin = 'round'; + + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + + ctx.strokeRect(50, 25, 0, 0); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.scale(50, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(25, 12.5, 50, 25); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.beginPath(); + ctx.rect(-25, -12.5, 150, 75); + ctx.save(); + ctx.rotate(Math.PI/2); + ctx.scale(25, 50); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.beginPath(); + ctx.moveTo(49, -50); + ctx.lineTo(201, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 283); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + ctx.save(); + ctx.beginPath(); + ctx.translate(-150, 0); + ctx.moveTo(49, -50); + ctx.lineTo(199, -50); + ctx.rotate(Math.PI/4); + ctx.scale(1, 142); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + ctx.restore(); + + //verify(Helper.comparePixel(ctx, 0,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,0, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 0,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 50,49, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 99,49, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-100, -100); + ctx.lineTo(200, -100); + ctx.lineTo(200, 25); + ctx.strokeStyle = '#f00'; + ctx.stroke(); + + ctx.closePath(); + ctx.strokeStyle = '#0f0'; + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 40; + ctx.moveTo(0, 10); + ctx.lineTo(100, 10); + ctx.moveTo(100, 40); + ctx.lineTo(0, 40); + ctx.stroke(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + function test_clip() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clip(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(-100, 0, 100, 50); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.rect(0, 0, 50, 50); + ctx.clip(); + ctx.beginPath(); + ctx.rect(50, 0, 50, 50) + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#0f0'; + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + + ctx.lineTo(0, 0); + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.lineTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.clip(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.beginPath(); + ctx.moveTo(-10, -10); + ctx.lineTo(110, -10); + ctx.lineTo(110, 60); + ctx.lineTo(-10, 60); + ctx.lineTo(-10, -10); + ctx.clip(); + + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.lineTo(0, 50); + ctx.lineTo(100, 50); + ctx.lineTo(100, 0); + ctx.lineTo(0, 0); + ctx.clip(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_moveTo() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.rect(0, 0, 10, 50); + ctx.moveTo(100, 0); + ctx.lineTo(10, 0); + ctx.lineTo(10, 50); + ctx.lineTo(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 90,25, 0,255,0,255)); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.moveTo(0, 25); + ctx.moveTo(100, 25); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.moveTo(0, 0); + ctx.moveTo(100, 0); + ctx.moveTo(100, 50); + ctx.moveTo(0, 50); + ctx.fillStyle = '#f00'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.moveTo(Infinity, 50); + ctx.moveTo(-Infinity, 50); + ctx.moveTo(NaN, 50); + ctx.moveTo(0, Infinity); + ctx.moveTo(0, -Infinity); + ctx.moveTo(0, NaN); + ctx.moveTo(Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_lineTo() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(100, 50); + ctx.stroke(); + // verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(-100, -100); + ctx.lineTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.lineTo(Infinity, 50); + ctx.lineTo(-Infinity, 50); + ctx.lineTo(NaN, 50); + ctx.lineTo(0, Infinity); + ctx.lineTo(0, -Infinity); + ctx.lineTo(0, NaN); + ctx.lineTo(Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); + + } + function test_bezierCurveTo() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.bezierCurveTo(100, 25, 100, 25, 100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(100, 50, 200, 50, 200, 50); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.bezierCurveTo(0, 25, 100, 25, 100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, 50); + ctx.bezierCurveTo(-Infinity, 50, 0, 50, 0, 50); + ctx.bezierCurveTo(NaN, 50, 0, 50, 0, 50); + ctx.bezierCurveTo(0, Infinity, 0, 50, 0, 50); + ctx.bezierCurveTo(0, -Infinity, 0, 50, 0, 50); + ctx.bezierCurveTo(0, NaN, 0, 50, 0, 50); + ctx.bezierCurveTo(0, 50, Infinity, 50, 0, 50); + ctx.bezierCurveTo(0, 50, -Infinity, 50, 0, 50); + ctx.bezierCurveTo(0, 50, NaN, 50, 0, 50); + ctx.bezierCurveTo(0, 50, 0, Infinity, 0, 50); + ctx.bezierCurveTo(0, 50, 0, -Infinity, 0, 50); + ctx.bezierCurveTo(0, 50, 0, NaN, 0, 50); + ctx.bezierCurveTo(0, 50, 0, 50, Infinity, 50); + ctx.bezierCurveTo(0, 50, 0, 50, -Infinity, 50); + ctx.bezierCurveTo(0, 50, 0, 50, NaN, 50); + ctx.bezierCurveTo(0, 50, 0, 50, 0, Infinity); + ctx.bezierCurveTo(0, 50, 0, 50, 0, -Infinity); + ctx.bezierCurveTo(0, 50, 0, 50, 0, NaN); + ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, 50); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, 50); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, Infinity, 50, 0, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, 0, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, Infinity, 0, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, Infinity, 0, 50, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, Infinity, 50, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, 50); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, Infinity, 0, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, 50); + ctx.bezierCurveTo(Infinity, 50, 0, 50, Infinity, Infinity); + ctx.bezierCurveTo(Infinity, 50, 0, 50, 0, Infinity); + ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, 50); + ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, 50); + ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, 50); + ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(0, Infinity, Infinity, Infinity, 0, Infinity); + ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, 50); + ctx.bezierCurveTo(0, Infinity, Infinity, 50, Infinity, Infinity); + ctx.bezierCurveTo(0, Infinity, Infinity, 50, 0, Infinity); + ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, 50); + ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, 50); + ctx.bezierCurveTo(0, Infinity, 0, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(0, Infinity, 0, Infinity, 0, Infinity); + ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, 50); + ctx.bezierCurveTo(0, Infinity, 0, 50, Infinity, Infinity); + ctx.bezierCurveTo(0, Infinity, 0, 50, 0, Infinity); + ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, 50); + ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, 50); + ctx.bezierCurveTo(0, 50, Infinity, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(0, 50, Infinity, Infinity, 0, Infinity); + ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, 50); + ctx.bezierCurveTo(0, 50, Infinity, 50, Infinity, Infinity); + ctx.bezierCurveTo(0, 50, Infinity, 50, 0, Infinity); + ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, 50); + ctx.bezierCurveTo(0, 50, 0, Infinity, Infinity, Infinity); + ctx.bezierCurveTo(0, 50, 0, Infinity, 0, Infinity); + ctx.bezierCurveTo(0, 50, 0, 50, Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-2, 3.1); + ctx.bezierCurveTo(-2, -1, 2.1, -1, 2.1, 3.1); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-2000, 3100); + ctx.bezierCurveTo(-2000, -1000, 2100, -1000, 2100, 3100); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + } + function test_quadraticCurveTo() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.moveTo(0, 25); + ctx.quadraticCurveTo(100, 25, 100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(100, 50, 200, 50); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 95,45, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.beginPath(); + ctx.quadraticCurveTo(0, 25, 100, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 5,45, 0,255,0,255)); + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.quadraticCurveTo(Infinity, 50, 0, 50); + ctx.quadraticCurveTo(-Infinity, 50, 0, 50); + ctx.quadraticCurveTo(NaN, 50, 0, 50); + ctx.quadraticCurveTo(0, Infinity, 0, 50); + ctx.quadraticCurveTo(0, -Infinity, 0, 50); + ctx.quadraticCurveTo(0, NaN, 0, 50); + ctx.quadraticCurveTo(0, 50, Infinity, 50); + ctx.quadraticCurveTo(0, 50, -Infinity, 50); + ctx.quadraticCurveTo(0, 50, NaN, 50); + ctx.quadraticCurveTo(0, 50, 0, Infinity); + ctx.quadraticCurveTo(0, 50, 0, -Infinity); + ctx.quadraticCurveTo(0, 50, 0, NaN); + ctx.quadraticCurveTo(Infinity, Infinity, 0, 50); + ctx.quadraticCurveTo(Infinity, Infinity, Infinity, 50); + ctx.quadraticCurveTo(Infinity, Infinity, Infinity, Infinity); + ctx.quadraticCurveTo(Infinity, Infinity, 0, Infinity); + ctx.quadraticCurveTo(Infinity, 50, Infinity, 50); + ctx.quadraticCurveTo(Infinity, 50, Infinity, Infinity); + ctx.quadraticCurveTo(Infinity, 50, 0, Infinity); + ctx.quadraticCurveTo(0, Infinity, Infinity, 50); + ctx.quadraticCurveTo(0, Infinity, Infinity, Infinity); + ctx.quadraticCurveTo(0, Infinity, 0, Infinity); + ctx.quadraticCurveTo(0, 50, Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.scale(1000, 1000); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 0.055; + ctx.beginPath(); + ctx.moveTo(-1, 1.05); + ctx.quadraticCurveTo(0, -1, 1.2, 1.05); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 55; + ctx.beginPath(); + ctx.moveTo(-1000, 1050); + ctx.quadraticCurveTo(0, -1000, 1200, 1050); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + } + function test_rect() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 100, 50); + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 200; + ctx.lineJoin = 'miter'; + ctx.rect(100, 50, 100, 100); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.rect(200, 100, 400, 1000); + ctx.lineTo(-2000, -1000); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 450; + ctx.lineCap = 'round'; + ctx.lineJoin = 'bevel'; + ctx.rect(150, 150, 2000, 2000); + ctx.lineTo(160, 160); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 1,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,1, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 1,48, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,48, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#0f0'; + ctx.rect(0, 0, 50, 25); + ctx.rect(100, 0, -50, 25); + ctx.rect(0, 50, 50, -25); + ctx.rect(100, 50, -50, -25); + ctx.fill(); + verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(-100, 25); + ctx.lineTo(-50, 25); + ctx.rect(200, 25, 1, 1); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + ctx.reset(); + ctx.moveTo(0, 0); + ctx.lineTo(100, 0); + ctx.rect(Infinity, 50, 1, 1); + ctx.rect(-Infinity, 50, 1, 1); + ctx.rect(NaN, 50, 1, 1); + ctx.rect(0, Infinity, 1, 1); + ctx.rect(0, -Infinity, 1, 1); + ctx.rect(0, NaN, 1, 1); + ctx.rect(0, 50, Infinity, 1); + ctx.rect(0, 50, -Infinity, 1); + ctx.rect(0, 50, NaN, 1); + ctx.rect(0, 50, 1, Infinity); + ctx.rect(0, 50, 1, -Infinity); + ctx.rect(0, 50, 1, NaN); + ctx.rect(Infinity, Infinity, 1, 1); + ctx.rect(Infinity, Infinity, Infinity, 1); + ctx.rect(Infinity, Infinity, Infinity, Infinity); + ctx.rect(Infinity, Infinity, 1, Infinity); + ctx.rect(Infinity, 50, Infinity, 1); + ctx.rect(Infinity, 50, Infinity, Infinity); + ctx.rect(Infinity, 50, 1, Infinity); + ctx.rect(0, Infinity, Infinity, 1); + ctx.rect(0, Infinity, Infinity, Infinity); + ctx.rect(0, Infinity, 1, Infinity); + ctx.rect(0, 50, Infinity, Infinity); + ctx.lineTo(100, 50); + ctx.lineTo(0, 50); + ctx.fillStyle = '#0f0'; + ctx.fill(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + //verify(Helper.comparePixel(ctx, 90,45, 0,255,0,255)); + + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 90; + ctx.beginPath(); + ctx.rect(45, 20, 10, 10); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.beginPath(); + ctx.fillStyle = '#f00'; + ctx.rect(0, 0, 50, 50); + ctx.rect(100, 50, -50, -50); + ctx.rect(0, 25, 100, -25); + ctx.rect(100, 25, -100, 25); + ctx.fill(); + verify(Helper.comparePixel(ctx, 25,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,12, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 25,37, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,37, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(0, 50, 100, 0); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, -100, 0, 250); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 100; + ctx.beginPath(); + ctx.rect(50, 25, 0, 0); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#0f0'; + ctx.lineWidth = 50; + ctx.rect(100, 25, 0, 0); + ctx.lineTo(0, 25); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.moveTo(0, 0); + ctx.rect(100, 25, 0, 0); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineJoin = 'miter'; + ctx.miterLimit = 1.5; + ctx.lineWidth = 200; + ctx.beginPath(); + ctx.rect(100, 25, 1000, 0); + ctx.stroke(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_clearRect() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.clearRect(0, 0, 16, 16); + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_fillRect() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + + function test_strokeRect() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.beginPath(); + ctx.rect(0, 0, 100, 50); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 5; + ctx.strokeRect(0, 0, 16, 16); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_transform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(-100, 0); + ctx.rect(100, 0, 100, 50); + ctx.translate(0, -100); + ctx.fillStyle = '#0f0'; + ctx.fill(); + + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#0f0'; + ctx.moveTo(0, 0); + ctx.translate(100, 0); + ctx.lineTo(0, 0); + ctx.translate(0, 50); + ctx.lineTo(0, 0); + ctx.translate(-100, 0); + ctx.lineTo(0, 0); + ctx.translate(1000, 1000); + ctx.rotate(Math.PI/2); + ctx.scale(0.1, 0.1); + ctx.fill(); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + ctx.reset(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.fillStyle = '#f00'; + ctx.translate(-100, 0); + ctx.rect(0, 0, 100, 50); + ctx.fill(); + ctx.translate(100, 0); + ctx.fill(); + + ctx.beginPath(); + ctx.strokeStyle = '#f00'; + ctx.lineWidth = 50; + ctx.translate(0, -50); + ctx.moveTo(0, 25); + ctx.lineTo(100, 25); + ctx.stroke(); + ctx.translate(0, 50); + ctx.stroke(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_pattern.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_pattern.qml new file mode 100644 index 0000000000..dd5b6628e8 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_pattern.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + //TODO + name: "pattern"; when: windowShown + function test_basic() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_animated() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_image() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_modified() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_paint() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_repeat() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_pixel.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_pixel.qml new file mode 100644 index 0000000000..1a3793d7a3 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_pixel.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + //TODO + name: "pixel"; when: windowShown + function test_createImageData() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_getImageData() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_object() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_putImageData() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_filters() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_shadow.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_shadow.qml new file mode 100644 index 0000000000..4405ca6c0e --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_shadow.qml @@ -0,0 +1,59 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + //TODO + + name: "shadow"; when: windowShown + function test_basic() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_blur() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + + function test_clip() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + + function test_composite() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + + function test_enable() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + + function test_gradient() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_image() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_offset() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_pattern() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_stroke() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_tranform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_state.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_state.qml new file mode 100644 index 0000000000..8042cf6a1d --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_state.qml @@ -0,0 +1,390 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + id:testCase + name: "state"; when: windowShown + function test_bitmap() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_clip() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 1, 1); + ctx.clip(); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + //verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + function test_fillStyle() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + // Test that restore() undoes any modifications + var old = ctx.fillStyle; + ctx.save(); + ctx.fillStyle = "#ff0000"; + ctx.restore(); + compare(ctx.fillStyle, old); + + // Also test that save() doesn't modify the values + ctx.fillStyle = "#ff0000"; + old = ctx.fillStyle; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "#ff0000" + ctx.save(); + compare(ctx.fillStyle, old); + ctx.restore(); + } + function test_font() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.font; + ctx.save(); + ctx.font = "25px serif"; + ctx.restore(); + compare(ctx.font, old); + + // Also test that save() doesn't modify the values + ctx.font = "25px serif"; + old = ctx.font; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "25px serif" + ctx.save(); + compare(ctx.font, old); + ctx.restore(); + } + function test_globalAlpha() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.globalAlpha; + ctx.save(); + ctx.globalAlpha = 0.5; + ctx.restore(); + compare(ctx.globalAlpha, old); + + // Also test that save() doesn't modify the values + ctx.globalAlpha = 0.5; + old = ctx.globalAlpha; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against 0.5 + ctx.save(); + compare(ctx.globalAlpha, old); + ctx.restore(); + } + function test_globalCompositeOperation() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.globalCompositeOperation; + ctx.save(); + ctx.globalCompositeOperation = "copy"; + ctx.restore(); + compare(ctx.globalCompositeOperation, old); + + // Also test that save() doesn't modify the values + ctx.globalCompositeOperation = "copy"; + old = ctx.globalCompositeOperation; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "copy" + ctx.save(); + compare(ctx.globalCompositeOperation, old); + ctx.restore(); + } + function test_lineCap() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.lineCap; + ctx.save(); + ctx.lineCap = "round"; + ctx.restore(); + compare(ctx.lineCap, old); + + // Also test that save() doesn't modify the values + ctx.lineCap = "round"; + old = ctx.lineCap; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "round" + ctx.save(); + compare(ctx.lineCap, old); + ctx.restore(); + } + function test_lineJoin() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.lineJoin; + ctx.save(); + ctx.lineJoin = "round"; + ctx.restore(); + compare(ctx.lineJoin, old); + + // Also test that save() doesn't modify the values + ctx.lineJoin = "round"; + old = ctx.lineJoin; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "round" + ctx.save(); + compare(ctx.lineJoin, old); + ctx.restore(); + } + function test_lineWidth() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.lineJoin; + ctx.save(); + ctx.lineJoin = "round"; + ctx.restore(); + compare(ctx.lineJoin, old, "ctx.lineJoin", "old"); + + // Also test that save() doesn't modify the values + ctx.lineJoin = "round"; + old = ctx.lineJoin; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "round" + ctx.save(); + compare(ctx.lineJoin, old); + ctx.restore(); + } + function test_miterLimit() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.miterLimit; + ctx.save(); + ctx.miterLimit = 0.5; + ctx.restore(); + compare(ctx.miterLimit, old); + + // Also test that save() doesn't modify the values + ctx.miterLimit = 0.5; + old = ctx.miterLimit; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against 0.5 + ctx.save(); + compare(ctx.miterLimit, old); + ctx.restore(); + } + function test_path() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.rect(0, 0, 100, 50); + ctx.restore(); + ctx.fillStyle = '#0f0'; + ctx.fill(); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_shadow() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.shadowBlur; + ctx.save(); + ctx.shadowBlur = 5; + ctx.restore(); + compare(ctx.shadowBlur, old); + + // Also test that save() doesn't modify the values + ctx.shadowBlur = 5; + old = ctx.shadowBlur; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against 5 + ctx.save(); + compare(ctx.shadowBlur, old); + ctx.restore(); + + // Test that restore() undoes any modifications + var old = ctx.shadowColor; + ctx.save(); + ctx.shadowColor = "#ff0000"; + ctx.restore(); + compare(ctx.shadowColor, old); + + // Also test that save() doesn't modify the values + ctx.shadowColor = "#ff0000"; + old = ctx.shadowColor; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "#ff0000" + ctx.save(); + compare(ctx.shadowColor, old); + ctx.restore(); + + // Test that restore() undoes any modifications + var old = ctx.shadowOffsetX; + ctx.save(); + ctx.shadowOffsetX = 5; + ctx.restore(); + compare(ctx.shadowOffsetX, old); + + // Also test that save() doesn't modify the values + ctx.shadowOffsetX = 5; + old = ctx.shadowOffsetX; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against 5 + ctx.save(); + compare(ctx.shadowOffsetX, old); + ctx.restore(); + + // Test that restore() undoes any modifications + var old = ctx.shadowOffsetY; + ctx.save(); + ctx.shadowOffsetY = 5; + ctx.restore(); + compare(ctx.shadowOffsetY, old); + + // Also test that save() doesn't modify the values + ctx.shadowOffsetY = 5; + old = ctx.shadowOffsetY; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against 5 + ctx.save(); + compare(ctx.shadowOffsetY, old); + ctx.restore(); + + } + function test_stack() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.lineWidth = 1; + ctx.save(); + ctx.lineWidth = 2; + ctx.save(); + ctx.lineWidth = 3; + compare(ctx.lineWidth, 3); + ctx.restore(); + compare(ctx.lineWidth, 2); + ctx.restore(); + compare(ctx.lineWidth, 1); + + var limit = 512; + for (var i = 1; i < limit; ++i) + { + ctx.save(); + ctx.lineWidth = i; + } + for (var i = limit-1; i > 0; --i) + { + testCase.compare(ctx.lineWidth, i); //strange javascript error here + ctx.restore(); + } + + for (var i = 0; i < 16; ++i) + ctx.restore(); + ctx.lineWidth = 0.5; + ctx.restore(); + compare(ctx.lineWidth, 0.5); + + } + function test_strokeStyle() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.strokeStyle; + ctx.save(); + ctx.strokeStyle = "#ff0000"; + ctx.restore(); + compare(ctx.strokeStyle, old); + + // Also test that save() doesn't modify the values + ctx.strokeStyle = "#ff0000"; + old = ctx.strokeStyle; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "#ff0000" + ctx.save(); + compare(ctx.strokeStyle, old); + ctx.restore(); + + + } + + function test_text() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + // Test that restore() undoes any modifications + var old = ctx.textAlign; + ctx.save(); + ctx.textAlign = "center"; + ctx.restore(); + compare(ctx.textAlign, old); + + // Also test that save() doesn't modify the values + ctx.textAlign = "center"; + old = ctx.textAlign; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "center" + ctx.save(); + compare(ctx.textAlign, old); + ctx.restore(); + + // Test that restore() undoes any modifications + var old = ctx.textBaseline; + ctx.save(); + ctx.textBaseline = "bottom"; + ctx.restore(); + compare(ctx.textBaseline, old); + + // Also test that save() doesn't modify the values + ctx.textBaseline = "bottom"; + old = ctx.textBaseline; + // we're not interested in failures caused by get(set(x)) != x (e.g. + // from rounding), so compare against 'old' instead of against "bottom" + ctx.save(); + compare(ctx.textBaseline, old); + ctx.restore(); + + + } + + function test_transform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.save(); + ctx.translate(200, 0); + ctx.restore(); + ctx.fillStyle = '#f00'; + ctx.fillRect(-200, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + } + + + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_strokeStyle.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_strokeStyle.qml new file mode 100644 index 0000000000..6b42f8a770 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_strokeStyle.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper + +Canvas { + id:canvas; width:100;height:50; renderTarget:Canvas.Image + TestCase { + name: "strokeStyle"; when: windowShown + function test_default() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + compare(ctx.strokeStyle, "#000000") + ctx.clearRect(0, 0, 1, 1); + compare(ctx.strokeStyle, "#000000") + } + function test_saverestore() { + var ctx = canvas.getContext('2d'); + var old = ctx.strokeStyle; + ctx.save(); + ctx.strokeStyle = "#ffaaff"; + ctx.restore(); + compare(ctx.strokeStyle, old); + + ctx.strokeStyle = "#ffcc88"; + old = ctx.strokeStyle; + ctx.save(); + compare(ctx.strokeStyle, old); + ctx.restore(); + } + function test_namedColor() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.strokeStyle = "red"; + ctx.strokeRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,255,0,0,255)); + + ctx.strokeStyle = "black"; + ctx.strokeRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,0,0,0,255)); + + ctx.strokeStyle = "white"; + ctx.strokeRect(0,0,1,1); + verify(Helper.comparePixel(ctx,0,0,255,255,255,255)); + } + + + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_text.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_text.qml new file mode 100644 index 0000000000..baeb17c9fb --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_text.qml @@ -0,0 +1,34 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + //TODO + name: "text"; when: windowShown + function test_baseLine() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_align() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_stroke() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_fill() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_font() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + function test_measure() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/tst_transform.qml b/tests/auto/qtquick2/qquickcanvasitem/data/tst_transform.qml new file mode 100644 index 0000000000..834a22f549 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/data/tst_transform.qml @@ -0,0 +1,487 @@ +import QtQuick 2.0 +import QtTest 1.0 +import "testhelper.js" as Helper +Canvas { + id:canvas; width:100;height:50; renderTarget: Canvas.Image + TestCase { + name: "transform"; when: windowShown + function test_order() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(2, 1); + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -50, 50, 50); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + } + function test_rotate() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI / 2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, -100, 50, 100); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + ctx.rotate(Infinity); + ctx.rotate(-Infinity); + ctx.rotate(NaN); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI); // should fail obviously if this is 3.1 degrees + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(Math.PI * (1 + 4096)); // == pi (mod 2*pi) + // We need about pi +/- 0.001 in order to get correct-looking results + // 32-bit floats can store pi*4097 with precision 2^-10, so that should + // be safe enough on reasonable implementations + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(-Math.PI * (1 + 4096)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,2, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 98,47, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.rotate(0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + } + function test_scale() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(2, 4); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 12.5); + verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(1e5, 1e5); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 1, 1); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.scale(Math.sqrt(2), Math.sqrt(2)); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.scale(-1, 1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-50, 0, 50, 50); + ctx.restore(); + + ctx.save(); + ctx.scale(1, -1); + ctx.fillStyle = '#0f0'; + ctx.fillRect(50, -50, 50, 50); + ctx.restore(); + verify(Helper.comparePixel(ctx, 25,25, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 75,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + ctx.scale(Infinity, 0.1); + ctx.scale(-Infinity, 0.1); + ctx.scale(NaN, 0.1); + ctx.scale(0.1, Infinity); + ctx.scale(0.1, -Infinity); + ctx.scale(0.1, NaN); + ctx.scale(Infinity, Infinity); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + + ctx.save(); + ctx.translate(50, 0); + ctx.scale(0, 1); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + + ctx.save(); + ctx.translate(0, 25); + ctx.scale(1, 0); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + ctx.restore(); + + // Firefox has a bug where it renders the canvas as empty and toDataURL throws an exception + canvas.toDataURL(); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + } + function test_setTransform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.setTransform(1/2,0, 0,1/2, 0,0); + ctx.setTransform(2,0, 0,2, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 50, 25); + verify(Helper.comparePixel(ctx, 75,35, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + ctx.setTransform(Infinity, 0, 0, 0, 0, 0); + ctx.setTransform(-Infinity, 0, 0, 0, 0, 0); + ctx.setTransform(NaN, 0, 0, 0, 0, 0); + ctx.setTransform(0, Infinity, 0, 0, 0, 0); + ctx.setTransform(0, -Infinity, 0, 0, 0, 0); + ctx.setTransform(0, NaN, 0, 0, 0, 0); + ctx.setTransform(0, 0, Infinity, 0, 0, 0); + ctx.setTransform(0, 0, -Infinity, 0, 0, 0); + ctx.setTransform(0, 0, NaN, 0, 0, 0); + ctx.setTransform(0, 0, 0, Infinity, 0, 0); + ctx.setTransform(0, 0, 0, -Infinity, 0, 0); + ctx.setTransform(0, 0, 0, NaN, 0, 0); + ctx.setTransform(0, 0, 0, 0, Infinity, 0); + ctx.setTransform(0, 0, 0, 0, -Infinity, 0); + ctx.setTransform(0, 0, 0, 0, NaN, 0); + ctx.setTransform(0, 0, 0, 0, 0, Infinity); + ctx.setTransform(0, 0, 0, 0, 0, -Infinity); + ctx.setTransform(0, 0, 0, 0, 0, NaN); + ctx.setTransform(Infinity, Infinity, 0, 0, 0, 0); + ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, 0); + ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, 0); + ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, 0); + ctx.setTransform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.setTransform(Infinity, Infinity, Infinity, Infinity, 0, Infinity); + ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, 0); + ctx.setTransform(Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.setTransform(Infinity, Infinity, Infinity, 0, 0, Infinity); + ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, 0); + ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, 0); + ctx.setTransform(Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.setTransform(Infinity, Infinity, 0, Infinity, 0, Infinity); + ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, 0); + ctx.setTransform(Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.setTransform(Infinity, Infinity, 0, 0, 0, Infinity); + ctx.setTransform(Infinity, 0, Infinity, 0, 0, 0); + ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, 0); + ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, 0); + ctx.setTransform(Infinity, 0, Infinity, Infinity, Infinity, Infinity); + ctx.setTransform(Infinity, 0, Infinity, Infinity, 0, Infinity); + ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, 0); + ctx.setTransform(Infinity, 0, Infinity, 0, Infinity, Infinity); + ctx.setTransform(Infinity, 0, Infinity, 0, 0, Infinity); + ctx.setTransform(Infinity, 0, 0, Infinity, 0, 0); + ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, 0); + ctx.setTransform(Infinity, 0, 0, Infinity, Infinity, Infinity); + ctx.setTransform(Infinity, 0, 0, Infinity, 0, Infinity); + ctx.setTransform(Infinity, 0, 0, 0, Infinity, 0); + ctx.setTransform(Infinity, 0, 0, 0, Infinity, Infinity); + ctx.setTransform(Infinity, 0, 0, 0, 0, Infinity); + ctx.setTransform(0, Infinity, Infinity, 0, 0, 0); + ctx.setTransform(0, Infinity, Infinity, Infinity, 0, 0); + ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, 0); + ctx.setTransform(0, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.setTransform(0, Infinity, Infinity, Infinity, 0, Infinity); + ctx.setTransform(0, Infinity, Infinity, 0, Infinity, 0); + ctx.setTransform(0, Infinity, Infinity, 0, Infinity, Infinity); + ctx.setTransform(0, Infinity, Infinity, 0, 0, Infinity); + ctx.setTransform(0, Infinity, 0, Infinity, 0, 0); + ctx.setTransform(0, Infinity, 0, Infinity, Infinity, 0); + ctx.setTransform(0, Infinity, 0, Infinity, Infinity, Infinity); + ctx.setTransform(0, Infinity, 0, Infinity, 0, Infinity); + ctx.setTransform(0, Infinity, 0, 0, Infinity, 0); + ctx.setTransform(0, Infinity, 0, 0, Infinity, Infinity); + ctx.setTransform(0, Infinity, 0, 0, 0, Infinity); + ctx.setTransform(0, 0, Infinity, Infinity, 0, 0); + ctx.setTransform(0, 0, Infinity, Infinity, Infinity, 0); + ctx.setTransform(0, 0, Infinity, Infinity, Infinity, Infinity); + ctx.setTransform(0, 0, Infinity, Infinity, 0, Infinity); + ctx.setTransform(0, 0, Infinity, 0, Infinity, 0); + ctx.setTransform(0, 0, Infinity, 0, Infinity, Infinity); + ctx.setTransform(0, 0, Infinity, 0, 0, Infinity); + ctx.setTransform(0, 0, 0, Infinity, Infinity, 0); + ctx.setTransform(0, 0, 0, Infinity, Infinity, Infinity); + ctx.setTransform(0, 0, 0, Infinity, 0, Infinity); + ctx.setTransform(0, 0, 0, 0, Infinity, Infinity); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.setTransform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + /* + //FIXME: + verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255)); + */ + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.transform(1,0, 0,1, 0,0); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + } + function test_transform() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.transform(1,2, 3,4, 5,6); + ctx.transform(-2,1, 3/2,-1/2, 1,-2); + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + ctx.transform(Infinity, 0, 0, 0, 0, 0); + ctx.transform(-Infinity, 0, 0, 0, 0, 0); + ctx.transform(NaN, 0, 0, 0, 0, 0); + ctx.transform(0, Infinity, 0, 0, 0, 0); + ctx.transform(0, -Infinity, 0, 0, 0, 0); + ctx.transform(0, NaN, 0, 0, 0, 0); + ctx.transform(0, 0, Infinity, 0, 0, 0); + ctx.transform(0, 0, -Infinity, 0, 0, 0); + ctx.transform(0, 0, NaN, 0, 0, 0); + ctx.transform(0, 0, 0, Infinity, 0, 0); + ctx.transform(0, 0, 0, -Infinity, 0, 0); + ctx.transform(0, 0, 0, NaN, 0, 0); + ctx.transform(0, 0, 0, 0, Infinity, 0); + ctx.transform(0, 0, 0, 0, -Infinity, 0); + ctx.transform(0, 0, 0, 0, NaN, 0); + ctx.transform(0, 0, 0, 0, 0, Infinity); + ctx.transform(0, 0, 0, 0, 0, -Infinity); + ctx.transform(0, 0, 0, 0, 0, NaN); + ctx.transform(Infinity, Infinity, 0, 0, 0, 0); + ctx.transform(Infinity, Infinity, Infinity, 0, 0, 0); + ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, 0); + ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, 0); + ctx.transform(Infinity, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.transform(Infinity, Infinity, Infinity, Infinity, 0, Infinity); + ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, 0); + ctx.transform(Infinity, Infinity, Infinity, 0, Infinity, Infinity); + ctx.transform(Infinity, Infinity, Infinity, 0, 0, Infinity); + ctx.transform(Infinity, Infinity, 0, Infinity, 0, 0); + ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, 0); + ctx.transform(Infinity, Infinity, 0, Infinity, Infinity, Infinity); + ctx.transform(Infinity, Infinity, 0, Infinity, 0, Infinity); + ctx.transform(Infinity, Infinity, 0, 0, Infinity, 0); + ctx.transform(Infinity, Infinity, 0, 0, Infinity, Infinity); + ctx.transform(Infinity, Infinity, 0, 0, 0, Infinity); + ctx.transform(Infinity, 0, Infinity, 0, 0, 0); + ctx.transform(Infinity, 0, Infinity, Infinity, 0, 0); + ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, 0); + ctx.transform(Infinity, 0, Infinity, Infinity, Infinity, Infinity); + ctx.transform(Infinity, 0, Infinity, Infinity, 0, Infinity); + ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0); + ctx.transform(Infinity, 0, Infinity, 0, Infinity, 0); + ctx.transform(Infinity, 0, Infinity, 0, Infinity, Infinity); + ctx.transform(Infinity, 0, Infinity, 0, 0, Infinity); + ctx.transform(Infinity, 0, 0, Infinity, 0, 0); + ctx.transform(Infinity, 0, 0, Infinity, Infinity, 0); + ctx.transform(Infinity, 0, 0, Infinity, Infinity, Infinity); + ctx.transform(Infinity, 0, 0, Infinity, 0, Infinity); + ctx.transform(Infinity, 0, 0, 0, Infinity, 0); + ctx.transform(Infinity, 0, 0, 0, Infinity, Infinity); + ctx.transform(Infinity, 0, 0, 0, 0, Infinity); + ctx.transform(0, Infinity, Infinity, 0, 0, 0); + ctx.transform(0, Infinity, Infinity, Infinity, 0, 0); + ctx.transform(0, Infinity, Infinity, Infinity, Infinity, 0); + ctx.transform(0, Infinity, Infinity, Infinity, Infinity, Infinity); + ctx.transform(0, Infinity, Infinity, Infinity, 0, Infinity); + ctx.transform(0, Infinity, Infinity, 0, Infinity, 0); + ctx.transform(0, Infinity, Infinity, 0, Infinity, Infinity); + ctx.transform(0, Infinity, Infinity, 0, 0, Infinity); + ctx.transform(0, Infinity, 0, Infinity, 0, 0); + ctx.transform(0, Infinity, 0, Infinity, Infinity, 0); + ctx.transform(0, Infinity, 0, Infinity, Infinity, Infinity); + ctx.transform(0, Infinity, 0, Infinity, 0, Infinity); + ctx.transform(0, Infinity, 0, 0, Infinity, 0); + ctx.transform(0, Infinity, 0, 0, Infinity, Infinity); + ctx.transform(0, Infinity, 0, 0, 0, Infinity); + ctx.transform(0, 0, Infinity, Infinity, 0, 0); + ctx.transform(0, 0, Infinity, Infinity, Infinity, 0); + ctx.transform(0, 0, Infinity, Infinity, Infinity, Infinity); + ctx.transform(0, 0, Infinity, Infinity, 0, Infinity); + ctx.transform(0, 0, Infinity, 0, Infinity, 0); + ctx.transform(0, 0, Infinity, 0, Infinity, Infinity); + ctx.transform(0, 0, Infinity, 0, 0, Infinity); + ctx.transform(0, 0, 0, Infinity, Infinity, 0); + ctx.transform(0, 0, 0, Infinity, Infinity, Infinity); + ctx.transform(0, 0, 0, Infinity, 0, Infinity); + ctx.transform(0, 0, 0, 0, Infinity, Infinity); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + ctx.reset(); + + // Create green with a red square ring inside it + ctx.fillStyle = '#0f0'; + ctx.fillRect(0, 0, 100, 50); + ctx.fillStyle = '#f00'; + ctx.fillRect(20, 10, 60, 30); + ctx.fillStyle = '#0f0'; + ctx.fillRect(40, 20, 20, 10); + + // Draw a skewed shape to fill that gap, to make sure it is aligned correctly + ctx.transform(1,4, 2,3, 5,6); + // Post-transform coordinates: + // [[20,10],[80,10],[80,40],[20,40],[20,10],[40,20],[40,30],[60,30],[60,20],[40,20],[20,10]]; + // Hence pre-transform coordinates: + var pts=[[-7.4,11.2],[-43.4,59.2],[-31.4,53.2],[4.6,5.2],[-7.4,11.2], + [-15.4,25.2],[-11.4,23.2],[-23.4,39.2],[-27.4,41.2],[-15.4,25.2], + [-7.4,11.2]]; + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var i = 0; i < pts.length; ++i) + ctx.lineTo(pts[i][0], pts[i][1]); + ctx.fill(); + /* + //FIXME: + verify(Helper.comparePixel(ctx, 21,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,11, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 21,39, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 79,39, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 39,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 61,19, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 39,31, 0,255,0,255)); + verify(Helper.comparePixel(ctx, 61,31, 0,255,0,255)); + */ + } + function test_translate() { + var ctx = canvas.getContext('2d'); + ctx.reset(); + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 50); + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -50, 100, 50); + verify(Helper.comparePixel(ctx, 90,40, 0,255,0,255)); + ctx.reset(); + + ctx.fillStyle = '#f00'; + ctx.fillRect(0, 0, 100, 50); + + ctx.translate(100, 10); + ctx.translate(Infinity, 0.1); + ctx.translate(-Infinity, 0.1); + ctx.translate(NaN, 0.1); + ctx.translate(0.1, Infinity); + ctx.translate(0.1, -Infinity); + ctx.translate(0.1, NaN); + ctx.translate(Infinity, Infinity); + + ctx.fillStyle = '#0f0'; + ctx.fillRect(-100, -10, 100, 50); + + verify(Helper.comparePixel(ctx, 50,25, 0,255,0,255)); + + + } + } +} diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/yellow.png b/tests/auto/qtquick2/qquickcanvasitem/data/yellow.png new file mode 100644 index 0000000000..51e8aaf38c Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/yellow.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/data/yellow75.png b/tests/auto/qtquick2/qquickcanvasitem/data/yellow75.png new file mode 100644 index 0000000000..2bb82c9834 Binary files /dev/null and b/tests/auto/qtquick2/qquickcanvasitem/data/yellow75.png differ diff --git a/tests/auto/qtquick2/qquickcanvasitem/qquickcanvasitem.pro b/tests/auto/qtquick2/qquickcanvasitem/qquickcanvasitem.pro new file mode 100644 index 0000000000..141e477416 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/qquickcanvasitem.pro @@ -0,0 +1,33 @@ +QT += core-private gui-private declarative-private widgets +TEMPLATE=app +TARGET=tst_qquickcanvasitem + +CONFIG += warn_on qmltestcase +SOURCES += tst_qquickcanvasitem.cpp + +importFiles.files = data +importFiles.path = . +DEPLOYMENT += importFiles + +OTHER_FILES += \ + data/testhelper.js \ + data/tst_transform.qml \ + data/tst_text.qml \ + data/tst_strokeStyle.qml \ + data/tst_state.qml \ + data/tst_shadow.qml \ + data/tst_pattern.qml \ + data/tst_path.qml \ + data/tst_line.qml \ + data/tst_fillStyle.qml \ + data/tst_fillrect.qml \ + data/tst_drawimage.qml \ + data/tst_composite.qml \ + data/tst_canvas.qml \ + data/tst_pixel.qml \ + data/tst_gradient.qml \ + data/tst_arcto.qml \ + data/tst_arc.qml + + + diff --git a/tests/auto/qtquick2/qquickcanvasitem/tst_qquickcanvasitem.cpp b/tests/auto/qtquick2/qquickcanvasitem/tst_qquickcanvasitem.cpp new file mode 100644 index 0000000000..57195babb7 --- /dev/null +++ b/tests/auto/qtquick2/qquickcanvasitem/tst_qquickcanvasitem.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +QUICK_TEST_MAIN(qquickcanvasitem) diff --git a/tests/auto/qtquick2/qquickdrag/qquickdrag.pro b/tests/auto/qtquick2/qquickdrag/qquickdrag.pro new file mode 100644 index 0000000000..4fdfa7b355 --- /dev/null +++ b/tests/auto/qtquick2/qquickdrag/qquickdrag.pro @@ -0,0 +1,9 @@ +TARGET = tst_qquickdrag +CONFIG += testcase +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickdrag.cpp + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickdrag/tst_qquickdrag.cpp b/tests/auto/qtquick2/qquickdrag/tst_qquickdrag.cpp new file mode 100644 index 0000000000..9163df6c62 --- /dev/null +++ b/tests/auto/qtquick2/qquickdrag/tst_qquickdrag.cpp @@ -0,0 +1,827 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +template static T evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + QVariant result = expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result.value(); +} + +template <> void evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + +Q_DECLARE_METATYPE(Qt::DropActions) + +class TestDropTarget : public QQuickItem +{ + Q_OBJECT +public: + TestDropTarget(QQuickItem *parent = 0) + : QQuickItem(parent) + , enterEvents(0) + , moveEvents(0) + , leaveEvents(0) + , dropEvents(0) + , acceptAction(Qt::MoveAction) + , defaultAction(Qt::IgnoreAction) + , proposedAction(Qt::IgnoreAction) + , accept(true) + { + setFlags(ItemAcceptsDrops); + } + + void reset() + { + enterEvents = 0; + moveEvents = 0; + leaveEvents = 0; + dropEvents = 0; + defaultAction = Qt::IgnoreAction; + proposedAction = Qt::IgnoreAction; + supportedActions = Qt::IgnoreAction; + } + + void dragEnterEvent(QDragEnterEvent *event) + { + ++enterEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setAccepted(accept); + } + + void dragMoveEvent(QDragMoveEvent *event) + { + ++moveEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setAccepted(accept); + } + + void dragLeaveEvent(QDragLeaveEvent *event) + { + ++leaveEvents; + event->setAccepted(accept); + } + + void dropEvent(QDropEvent *event) + { + ++dropEvents; + position = event->pos(); + defaultAction = event->dropAction(); + proposedAction = event->proposedAction(); + supportedActions = event->possibleActions(); + event->setDropAction(acceptAction); + event->setAccepted(accept); + } + + int enterEvents; + int moveEvents; + int leaveEvents; + int dropEvents; + Qt::DropAction acceptAction; + Qt::DropAction defaultAction; + Qt::DropAction proposedAction; + Qt::DropActions supportedActions; + QPointF position; + bool accept; +}; + +class tst_QQuickDrag: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + + void active(); + void drop(); + void move(); + void hotSpot(); + void supportedActions(); + void proposedAction(); + void keys(); + void source(); + +private: + QDeclarativeEngine engine; +}; + +void tst_QQuickDrag::initTestCase() +{ + +} + +void tst_QQuickDrag::cleanupTestCase() +{ + +} + +void tst_QQuickDrag::active() +{ + QQuickCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate(item, "Drag.active = false"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + dropTarget.reset(); + evaluate(item, "Drag.cancel()"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate(item, "Drag.start()"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + // Start while a drag is active, cancels the previous drag and starts a new one. + dropTarget.reset(); + evaluate(item, "Drag.start()"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 1); + + dropTarget.reset(); + evaluate(item, "Drag.cancel()"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + // Enter events aren't sent to items without the QQuickItem::ItemAcceptsDrops flag. + dropTarget.setFlags(QQuickItem::Flags()); + + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate(item, "Drag.active = false"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.setFlags(QQuickItem::ItemAcceptsDrops); + + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.setFlags(QQuickItem::Flags()); + + dropTarget.reset(); + evaluate(item, "Drag.active = false"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + // Follow up events aren't sent to items if the enter event isn't accepted. + dropTarget.setFlags(QQuickItem::ItemAcceptsDrops); + dropTarget.accept = false; + + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.reset(); + evaluate(item, "Drag.active = false"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.accept = true; + + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&dropTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&dropTarget)); + QCOMPARE(dropTarget.enterEvents, 1); QCOMPARE(dropTarget.leaveEvents, 0); + + dropTarget.accept = false; + + dropTarget.reset(); + evaluate(item, "Drag.active = false"); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 1); + + // Events are sent to hidden or disabled items. + dropTarget.accept = true; + dropTarget.setVisible(false); + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + evaluate(item, "Drag.active = false"); + dropTarget.setVisible(true); + + dropTarget.setOpacity(0.0); + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); + + evaluate(item, "Drag.active = false"); + dropTarget.setOpacity(1.0); + + dropTarget.setEnabled(false); + dropTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(dropTarget.enterEvents, 0); QCOMPARE(dropTarget.leaveEvents, 0); +} + +void tst_QQuickDrag::drop() +{ + QQuickCanvas canvas; + TestDropTarget outerTarget(canvas.rootItem()); + outerTarget.setSize(QSizeF(100, 100)); + outerTarget.acceptAction = Qt::CopyAction; + TestDropTarget innerTarget(&outerTarget); + innerTarget.setSize(QSizeF(100, 100)); + innerTarget.acceptAction = Qt::MoveAction; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&outerTarget); + + innerTarget.reset(); outerTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate(item, "Drag.drop() == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); + + innerTarget.reset(); outerTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&innerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&innerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 1); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + // Inner target declines the drop so it is propagated to the outer target. + innerTarget.accept = false; + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate(item, "Drag.drop() == Qt.CopyAction"), true); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 1); + + + // Inner target doesn't accept enter so drop goes directly to outer. + innerTarget.accept = true; + innerTarget.setFlags(QQuickItem::Flags()); + + innerTarget.reset(); outerTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate(item, "Drag.drop() == Qt.CopyAction"), true); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + // Neither target accepts drop so Qt::IgnoreAction is returned. + innerTarget.reset(); outerTarget.reset(); + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + outerTarget.accept = false; + + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate(item, "Drag.drop() == Qt.IgnoreAction"), true); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 1); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); + + // drop doesn't send an event and returns Qt.IgnoreAction if not active. + innerTarget.accept = true; + outerTarget.accept = true; + innerTarget.reset(); outerTarget.reset(); + QCOMPARE(evaluate(item, "Drag.drop() == Qt.IgnoreAction"), true); + QCOMPARE(evaluate(item, "Drag.active"), false); + QCOMPARE(evaluate(item, "dragActive"), false); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.dropEvents, 0); + QCOMPARE(innerTarget.enterEvents, 0); QCOMPARE(innerTarget.leaveEvents, 0); QCOMPARE(innerTarget.dropEvents, 0); +} + +void tst_QQuickDrag::move() +{ + QQuickCanvas canvas; + TestDropTarget outerTarget(canvas.rootItem()); + outerTarget.setSize(QSizeF(100, 100)); + TestDropTarget leftTarget(&outerTarget); + leftTarget.setPos(QPointF(0, 35)); + leftTarget.setSize(QSizeF(30, 30)); + TestDropTarget rightTarget(&outerTarget); + rightTarget.setPos(QPointF(70, 35)); + rightTarget.setSize(QSizeF(30, 30)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property bool dragActive: Drag.active\n" + "property Item dragTarget: Drag.target\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&outerTarget); + + evaluate(item, "Drag.active = true"); + QCOMPARE(evaluate(item, "Drag.active"), true); + QCOMPARE(evaluate(item, "dragActive"), true); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(50)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Move within the outer target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(60, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Move into the right target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(75, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&rightTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&rightTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(75)); QCOMPARE(outerTarget.position.y(), qreal(50)); + QCOMPARE(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15)); + + // Move into the left target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&leftTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&leftTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 1); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 1); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); + QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(15)); + + // Move within the left target. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 40)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&leftTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&leftTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 1); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(40)); + QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5)); + + // Move out of all targets. + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(110, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(0)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(0)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 1); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + + // Stop the right target accepting drag events and move into it. + rightTarget.accept = false; + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(80, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 1); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 1); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(80)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Stop the outer target accepting drag events after it has accepted an enter event. + outerTarget.accept = false; + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(60, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Clear the QQuickItem::ItemAcceptsDrops flag from the outer target after it accepted an enter event. + outerTarget.setFlags(QQuickItem::Flags()); + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(40, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(40)); QCOMPARE(outerTarget.position.y(), qreal(50)); + + // Clear the QQuickItem::ItemAcceptsDrops flag from the left target before it accepts an enter event. + leftTarget.setFlags(QQuickItem::Flags()); + + outerTarget.reset(); leftTarget.reset(); rightTarget.reset(); + item->setPos(QPointF(25, 50)); + QCOMPARE(evaluate(item, "Drag.target"), static_cast(&outerTarget)); + QCOMPARE(evaluate(item, "dragTarget"), static_cast(&outerTarget)); + QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1); + QCOMPARE(leftTarget .enterEvents, 0); QCOMPARE(leftTarget .leaveEvents, 0); QCOMPARE(leftTarget .moveEvents, 0); + QCOMPARE(rightTarget.enterEvents, 0); QCOMPARE(rightTarget.leaveEvents, 0); QCOMPARE(rightTarget.moveEvents, 0); + QCOMPARE(outerTarget.position.x(), qreal(25)); QCOMPARE(outerTarget.position.y(), qreal(50)); +} + + +void tst_QQuickDrag::hotSpot() +{ + QQuickCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property real hotSpotX: Drag.hotSpot.x\n" + "property real hotSpotY: Drag.hotSpot.y\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(0)); + QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(0)); + QCOMPARE(evaluate(item, "hotSpotX"), qreal(0)); + QCOMPARE(evaluate(item, "hotSpotY"), qreal(0)); + + evaluate(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.position.x(), qreal(50)); + QCOMPARE(dropTarget.position.y(), qreal(50)); + + evaluate(item, "{ Drag.hotSpot.x = 5, Drag.hotSpot.y = 5 }"); + QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(5)); + QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(5)); + QCOMPARE(evaluate(item, "hotSpotX"), qreal(5)); + QCOMPARE(evaluate(item, "hotSpotY"), qreal(5)); + + evaluate(item, "Drag.start()"); + QCOMPARE(dropTarget.position.x(), qreal(55)); + QCOMPARE(dropTarget.position.y(), qreal(55)); + + item->setPos(QPointF(30, 20)); + QCOMPARE(dropTarget.position.x(), qreal(35)); + QCOMPARE(dropTarget.position.y(), qreal(25)); + + evaluate(item, "{ Drag.hotSpot.x = 10; Drag.hotSpot.y = 10 }"); + QCOMPARE(evaluate(item, "Drag.hotSpot.x"), qreal(10)); + QCOMPARE(evaluate(item, "Drag.hotSpot.y"), qreal(10)); + QCOMPARE(evaluate(item, "hotSpotX"), qreal(10)); + QCOMPARE(evaluate(item, "hotSpotY"), qreal(10)); + // Changing the hotSpot won't generate a move event so the position is unchanged. Should it? + QCOMPARE(dropTarget.position.x(), qreal(35)); + QCOMPARE(dropTarget.position.y(), qreal(25)); + + item->setPos(QPointF(10, 20)); + QCOMPARE(dropTarget.position.x(), qreal(20)); + QCOMPARE(dropTarget.position.y(), qreal(30)); +} + +void tst_QQuickDrag::supportedActions() +{ + QQuickCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property int supportedActions: Drag.supportedActions\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); + QCOMPARE(evaluate(item, "supportedActions == Qt.CopyAction | Qt.MoveAction | Qt.LinkAction"), true); + evaluate(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction | Qt::LinkAction); + + evaluate(item, "Drag.supportedActions = Qt.CopyAction | Qt.MoveAction"); + QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.CopyAction | Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "supportedActions == Qt.CopyAction | Qt.MoveAction"), true); + evaluate(item, "Drag.start()"); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); + + // Once a drag is started the proposed actions are locked in for future events. + evaluate(item, "Drag.supportedActions = Qt.MoveAction"); + QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); + item->setPos(QPointF(60, 60)); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction | Qt::MoveAction); + + // Calling start with proposed actions will override the current actions for the next sequence. + evaluate(item, "Drag.start(Qt.CopyAction)"); + QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); + QCOMPARE(dropTarget.supportedActions, Qt::CopyAction); + + evaluate(item, "Drag.start()"); + QCOMPARE(evaluate(item, "Drag.supportedActions == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "supportedActions == Qt.MoveAction"), true); + QCOMPARE(dropTarget.supportedActions, Qt::MoveAction); +} + +void tst_QQuickDrag::proposedAction() +{ + QQuickCanvas canvas; + TestDropTarget dropTarget(canvas.rootItem()); + dropTarget.setSize(QSizeF(100, 100)); + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property int proposedAction: Drag.proposedAction\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + item->setParentItem(&dropTarget); + + + QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "proposedAction == Qt.MoveAction"), true); + evaluate(item, "{ Drag.start(); Drag.cancel() }"); + QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); + QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); + + evaluate(item, "Drag.proposedAction = Qt.CopyAction"); + QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.CopyAction"), true); + QCOMPARE(evaluate(item, "proposedAction == Qt.CopyAction"), true); + evaluate(item, "Drag.start()"); + QCOMPARE(dropTarget.defaultAction, Qt::CopyAction); + QCOMPARE(dropTarget.proposedAction, Qt::CopyAction); + + // The proposed action can change during a drag. + evaluate(item, "Drag.proposedAction = Qt.MoveAction"); + QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.MoveAction"), true); + QCOMPARE(evaluate(item, "proposedAction == Qt.MoveAction"), true); + item->setPos(QPointF(60, 60)); + QCOMPARE(dropTarget.defaultAction, Qt::MoveAction); + QCOMPARE(dropTarget.proposedAction, Qt::MoveAction); + + evaluate(item, "Drag.proposedAction = Qt.LinkAction"); + QCOMPARE(evaluate(item, "Drag.proposedAction == Qt.LinkAction"), true); + QCOMPARE(evaluate(item, "proposedAction == Qt.LinkAction"), true); + evaluate(item, "Drag.drop()"); + QCOMPARE(dropTarget.defaultAction, Qt::LinkAction); + QCOMPARE(dropTarget.proposedAction, Qt::LinkAction); +} + +void tst_QQuickDrag::keys() +{ + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property variant keys: Drag.keys\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + +// QCOMPARE(evaluate(item, "Drag.keys"), QStringList()); +// QCOMPARE(evaluate(item, "keys"), QStringList()); + QCOMPARE(item->property("keys").toStringList(), QStringList()); + + evaluate(item, "Drag.keys = [\"red\", \"blue\"]"); +// QCOMPARE(evaluate(item, "Drag.keys"), QStringList() << "red" << "blue"); +// QCOMPARE(evaluate(item, "keys"), QStringList() << "red" << "blue"); + QCOMPARE(item->property("keys").toStringList(), QStringList() << "red" << "blue"); +} + +void tst_QQuickDrag::source() +{ + + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "Item {\n" + "property Item source: Drag.source\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Item { id: proxySource; objectName: \"proxySource\" }\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *item = qobject_cast(object.data()); + QVERIFY(item); + + QCOMPARE(evaluate(item, "Drag.source"), static_cast(item)); + QCOMPARE(evaluate(item, "source"), static_cast(item)); + + QQuickItem *proxySource = item->findChild("proxySource"); + QVERIFY(proxySource); + + evaluate(item, "Drag.source = proxySource"); + QCOMPARE(evaluate(item, "Drag.source"), static_cast(proxySource)); + QCOMPARE(evaluate(item, "source"), static_cast(proxySource)); + + evaluate(item, "Drag.source = undefined"); + QCOMPARE(evaluate(item, "Drag.source"), static_cast(item)); + QCOMPARE(evaluate(item, "source"), static_cast(item)); +} + +QTEST_MAIN(tst_QQuickDrag) + +#include "tst_qquickdrag.moc" diff --git a/tests/auto/qtquick2/qquickdroparea/qquickdroparea.pro b/tests/auto/qtquick2/qquickdroparea/qquickdroparea.pro new file mode 100644 index 0000000000..46fe08c145 --- /dev/null +++ b/tests/auto/qtquick2/qquickdroparea/qquickdroparea.pro @@ -0,0 +1,9 @@ +TARGET = tst_qquickdroparea +CONFIG += testcase +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickdroparea.cpp + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/qtquick2/qquickdroparea/tst_qquickdroparea.cpp new file mode 100644 index 0000000000..f8a081ff21 --- /dev/null +++ b/tests/auto/qtquick2/qquickdroparea/tst_qquickdroparea.cpp @@ -0,0 +1,1117 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +template static T evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + QVariant result = expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result.value(); +} + +template <> void evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + +class tst_QQuickDropArea: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + + void containsDrag_internal(); + void containsDrag_external(); + void keys_internal(); + void keys_external(); + void source_internal(); +// void source_external(); + void position_internal(); + void position_external(); + void drop_internal(); +// void drop_external(); + void simultaneousDrags(); + +private: + QDeclarativeEngine engine; +}; + +void tst_QQuickDropArea::initTestCase() +{ + +} + +void tst_QQuickDropArea::cleanupTestCase() +{ + +} + +void tst_QQuickDropArea::containsDrag_internal() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool hasDrag: containsDrag\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QQuickItem *dragItem = dropArea->findChild("dragItem"); + QVERIFY(dragItem); + + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "hasDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem, "Drag.active = false"); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 1); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + dragItem->setPos(QPointF(150, 50)); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + dragItem->setPos(QPointF(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "hasDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + dragItem->setPos(QPointF(150, 50)); + + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 1); + + evaluate(dragItem, "Drag.active = false"); +} + +void tst_QQuickDropArea::containsDrag_external() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool hasDrag: containsDrag\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + QQuickCanvas alternateCanvas; + + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "hasDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 1); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "hasDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "exitEvents"), 0); + + evaluate(dropArea, "{ enterEvents = 0; exitEvents = 0 }"); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(150, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "hasDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "exitEvents"), 1); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(150, 50)); +} + +void tst_QQuickDropArea::keys_internal() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property variant dragKeys\n" + "property variant dropKeys: keys\n" + "property int enterEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; dragKeys = drag.keys }\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]\n" + "}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QQuickItem *dragItem = dropArea->findChild("dragItem"); + QVERIFY(dragItem); + + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = \"blue\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "blue"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "blue"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = \"red\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = \"green\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "green"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = [\"red\", \"green\"]"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "red" << "green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "red" << "green"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dragItem, "Drag.keys = []"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = []"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dropArea, "keys = []"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); + + evaluate(dragItem, "Drag.active = false"); + evaluate(dragItem, "Drag.keys = [\"red\", \"blue\"]"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "red" << "blue"); +} + +void tst_QQuickDropArea::keys_external() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property variant dragKeys\n" + "property variant dropKeys: keys\n" + "property int enterEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; dragKeys = drag.keys }\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + QQuickCanvas alternateCanvas; + + data.setData("text/x-red", "red"); + data.setData("text/x-blue", "blue"); + + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate(dropArea, "keys = \"text/x-blue\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-blue"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-blue"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate(dropArea, "keys = \"text/x-red\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate(dropArea, "keys = \"text/x-green\""); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-green"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate(dropArea, "keys = [\"text/x-red\", \"text/x-green\"]"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList() << "text/x-red" << "text/x-green"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + data.removeFormat("text/x-red"); + data.removeFormat("text/x-blue"); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), false); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + evaluate(dropArea, "keys = []"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList()); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + data.setData("text/x-red", "red"); + data.setData("text/x-blue", "blue"); + QCOMPARE(dropArea->property("keys").toStringList(), QStringList()); + QCOMPARE(dropArea->property("dropKeys").toStringList(), QStringList()); + evaluate(dropArea, "{ enterEvents = 0; dragKeys = undefined }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "containsDrag"), true); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(dropArea->property("dragKeys").toStringList(), QStringList() << "text/x-red" << "text/x-blue"); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(50, 50)); +} + +void tst_QQuickDropArea::source_internal() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property Item source: drag.source\n" + "property Item eventSource\n" + "width: 100; height: 100\n" + "onEntered: {eventSource = drag.source}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "Item { id: dragSource; objectName: \"dragSource\" }\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QQuickItem *dragItem = dropArea->findChild("dragItem"); + QVERIFY(dragItem); + + QQuickItem *dragSource = dropArea->findChild("dragSource"); + QVERIFY(dragSource); + + QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); + QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "source"), static_cast(dragItem)); + QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(dragItem)); + QCOMPARE(evaluate(dropArea, "eventSource"), static_cast(dragItem)); + + evaluate(dragItem, "Drag.active = false"); + QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); + QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); + + + evaluate(dropArea, "{ eventSource = null }"); + evaluate(dragItem, "Drag.source = dragSource"); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "source"), static_cast(dragSource)); + QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(dragSource)); + QCOMPARE(evaluate(dropArea, "eventSource"), static_cast(dragSource)); + + evaluate(dragItem, "Drag.active = false"); + QCOMPARE(evaluate(dropArea, "source"), static_cast(0)); + QCOMPARE(evaluate(dropArea, "drag.source"), static_cast(0)); +} + +// Setting a source can't be emulated using the QWindowSystemInterface API. + +//void tst_QQuickDropArea::source_external() +//{ +//} + +void tst_QQuickDropArea::position_internal() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property real dragX: drag.x\n" + "property real dragY: drag.y\n" + "property real eventX\n" + "property real eventY\n" + "property int enterEvents: 0\n" + "property int moveEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" + "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QQuickItem *dragItem = dropArea->findChild("dragItem"); + QVERIFY(dragItem); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "moveEvents"), 0); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(50)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); + + evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + dragItem->setPos(QPointF(40, 50)); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(40)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(40)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(40)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); + + evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + dragItem->setPos(QPointF(75, 25)); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(75)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(25)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(75)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(25)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(75)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(25)); + + evaluate(dragItem, "Drag.active = false"); +} + +void tst_QQuickDropArea::position_external() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property real dragX: drag.x\n" + "property real dragY: drag.y\n" + "property real eventX\n" + "property real eventY\n" + "property int enterEvents: 0\n" + "property int moveEvents: 0\n" + "width: 100; height: 100\n" + "onEntered: {++enterEvents; eventX = drag.x; eventY = drag.y}\n" + "onPositionChanged: {++moveEvents; eventX = drag.x; eventY = drag.y}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QMimeData data; + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(50)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); + + evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(40, 50)); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(40)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(50)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(40)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(50)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(40)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(50)); + + evaluate(dropArea, "{ enterEvents = 0; moveEvents = 0; eventX = -1; eventY = -1 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(75, 25)); + QCOMPARE(evaluate(dropArea, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea, "moveEvents"), 1); + QCOMPARE(evaluate(dropArea, "drag.x"), qreal(75)); + QCOMPARE(evaluate(dropArea, "drag.y"), qreal(25)); + QCOMPARE(evaluate(dropArea, "dragX"), qreal(75)); + QCOMPARE(evaluate(dropArea, "dragY"), qreal(25)); + QCOMPARE(evaluate(dropArea, "eventX"), qreal(75)); + QCOMPARE(evaluate(dropArea, "eventY"), qreal(25)); + + QWindowSystemInterface::handleDrop(&canvas, &data, QPoint(75, 25)); +} + +void tst_QQuickDropArea::drop_internal() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property bool accept: false\n" + "property bool setAccepted: false\n" + "property bool acceptDropAction: false\n" + "property bool setDropAction: false\n" + "property int dropAction: Qt.IgnoreAction\n" + "property int proposedAction: Qt.IgnoreAction\n" + "property int supportedActions: Qt.IgnoreAction\n" + "property int dropEvents: 0\n" + "width: 100; height: 100\n" + "onDropped: {\n" + "++dropEvents\n" + "supportedActions = drop.supportedActions\n" + "proposedAction = drop.action\n" + "if (setDropAction)\n" + "drop.action = dropAction\n" + "if (acceptDropAction)\n" + "drop.accept(dropAction)\n" + "else if (setAccepted)\n" + "drop.accepted = accept\n" + "else if (accept)\n" + "drop.accept()\n" + "}\n" + "Item {\n" + "objectName: \"dragItem\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "}\n" + "}", QUrl()); + QScopedPointer object(component.create()); + QQuickItem *dropArea = qobject_cast(object.data()); + QVERIFY(dropArea); + dropArea->setParentItem(canvas.rootItem()); + + QQuickItem *dragItem = dropArea->findChild("dragItem"); + QVERIFY(dragItem); + + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ accept = true; setDropAction = true; dropAction = Qt.LinkAction }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = true; }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ accept = false; setAccepted = true; }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::IgnoreAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = false; setDropAction = false; acceptDropAction = true; }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ acceptDropAction = false; dropAction = Qt.IgnoreAction; accept = true }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = true }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = false }"); + evaluate(dragItem, "Drag.supportedActions = Qt.LinkAction"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = true }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::MoveAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::MoveAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = false }"); + evaluate(dragItem, "Drag.proposedAction = Qt.LinkAction"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::LinkAction)); + + evaluate(dropArea, "{ dropEvents = 0; proposedAction = Qt.IgnoreAction; supportedActions = Qt.IgnoreAction }"); + evaluate(dropArea, "{ setAccepted = true }"); + evaluate(dragItem, "Drag.active = true"); + QCOMPARE(evaluate(dragItem, "Drag.drop()"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "dropEvents"), 1); + QCOMPARE(evaluate(dropArea, "supportedActions"), int(Qt::LinkAction)); + QCOMPARE(evaluate(dropArea, "proposedAction"), int(Qt::LinkAction)); +} + +// Setting the supportedActions can't be emulated using the QWindowSystemInterface API. + +//void tst_QQuickDropArea::drop_external() +//{ +//} + +void tst_QQuickDropArea::simultaneousDrags() +{ + QQuickCanvas canvas; + QDeclarativeComponent component(&engine); + component.setData( + "import QtQuick 2.0\n" + "DropArea {\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "keys: [\"red\", \"text/x-red\"]\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "DropArea {\n" + "objectName: \"dropArea2\"\n" + "property int enterEvents: 0\n" + "property int exitEvents: 0\n" + "width: 100; height: 100\n" + "keys: [\"blue\", \"text/x-blue\"]\n" + "onEntered: {++enterEvents}\n" + "onExited: {++exitEvents}\n" + "}\n" + "Item {\n" + "objectName: \"dragItem1\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]" + "}\n" + "Item {\n" + "objectName: \"dragItem2\"\n" + "x: 50; y: 50\n" + "width: 10; height: 10\n" + "Drag.keys: [\"red\", \"blue\"]" + "}\n" + "}", QUrl()); + + QScopedPointer object(component.create()); + QQuickItem *dropArea1 = qobject_cast(object.data()); + QVERIFY(dropArea1); + dropArea1->setParentItem(canvas.rootItem()); + + QQuickItem *dropArea2 = dropArea1->findChild("dropArea2"); + QVERIFY(dropArea2); + + QQuickItem *dragItem1 = dropArea1->findChild("dragItem1"); + QVERIFY(dragItem1); + + QQuickItem *dragItem2 = dropArea1->findChild("dragItem2"); + QVERIFY(dragItem2); + + QMimeData data; + data.setData("text/x-red", "red"); + data.setData("text/x-blue", "blue"); + + QQuickCanvas alternateCanvas; + + // Mixed internal drags. + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + // internal then external. + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + // external then internal. + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + // Different acceptance + evaluate(dragItem1, "Drag.keys = \"red\""); + evaluate(dragItem2, "Drag.keys = \"blue\""); + data.removeFormat("text/x-red"); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem2, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + // internal then external + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = true"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&canvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), true); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 1); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dragItem1, "Drag.active = false"); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 1); + QCOMPARE(evaluate(dropArea2, "containsDrag"), true); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 0); + + evaluate(dropArea1, "{ enterEvents = 0; exitEvents = 0 }"); + evaluate(dropArea2, "{ enterEvents = 0; exitEvents = 0 }"); + QWindowSystemInterface::handleDrag(&alternateCanvas, &data, QPoint(50, 50)); + QCOMPARE(evaluate(dropArea1, "containsDrag"), false); + QCOMPARE(evaluate(dropArea1, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea1, "exitEvents"), 0); + QCOMPARE(evaluate(dropArea2, "containsDrag"), false); + QCOMPARE(evaluate(dropArea2, "enterEvents"), 0); + QCOMPARE(evaluate(dropArea2, "exitEvents"), 1); + + QWindowSystemInterface::handleDrop(&alternateCanvas, &data, QPoint(50, 50)); +} + +QTEST_MAIN(tst_QQuickDropArea) + +#include "tst_qquickdroparea.moc" diff --git a/tests/auto/qtquick2/qquickflickable/data/disabled.qml b/tests/auto/qtquick2/qquickflickable/data/disabled.qml new file mode 100644 index 0000000000..9b679827c7 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/disabled.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 100; height: 100 + property bool clicked: false + + Flickable { + objectName: "flickable" + width: 100; height: 100 + contentWidth: column.width; contentHeight: column.height + enabled: false + + Column { + id: column + Repeater { + model: 4 + Rectangle { + width: 200; height: 300; color: "blue" + MouseArea { anchors.fill: parent; onClicked: { } } + } + } + } + } + + MouseArea { + width: 100; height: 30 + onClicked: root.clicked = true + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/flickable01.qml b/tests/auto/qtquick2/qquickflickable/data/flickable01.qml new file mode 100644 index 0000000000..cbec44bb4f --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/flickable01.qml @@ -0,0 +1,4 @@ +import QtQuick 2.0 + +Flickable { +} diff --git a/tests/auto/qtquick2/qquickflickable/data/flickable02.qml b/tests/auto/qtquick2/qquickflickable/data/flickable02.qml new file mode 100644 index 0000000000..80caa32da5 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/flickable02.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Flickable { + width: 100; height: 100 + contentWidth: row.width; contentHeight: row.height + + Row { + id: row + Repeater { + model: 4 + Rectangle { width: 200; height: 300; color: "blue" } + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/flickable03.qml b/tests/auto/qtquick2/qquickflickable/data/flickable03.qml new file mode 100644 index 0000000000..ebc49ba90a --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/flickable03.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Flickable { + width: 100; height: 200 + contentWidth: column.width; contentHeight: column.height + + Column { + id: column + Repeater { + model: 4 + Rectangle { width: 200; height: 300; color: "blue" } + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/flickable04.qml b/tests/auto/qtquick2/qquickflickable/data/flickable04.qml new file mode 100644 index 0000000000..b2f30b84ec --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/flickable04.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Flickable { + property bool ok: false + function check() { + if (column.parent == contentItem) + ok = true; + } + + width: 100; height: 100 + contentWidth: column.width; contentHeight: column.height + pressDelay: 200; boundsBehavior: Flickable.StopAtBounds; interactive: false + maximumFlickVelocity: 2000 + + Column { + id: column + Repeater { + model: 4 + Rectangle { width: 200; height: 300; color: "blue" } + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/flickableqgraphicswidget.qml b/tests/auto/qtquick2/qquickflickable/data/flickableqgraphicswidget.qml new file mode 100644 index 0000000000..bb8f1eefc6 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/flickableqgraphicswidget.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Flickable { + width: 100; height: 100 + + QGraphicsWidget { objectName: "widget1"; width: 200; height: 300 } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/margins.qml b/tests/auto/qtquick2/qquickflickable/data/margins.qml new file mode 100644 index 0000000000..4866bd8301 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/margins.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Flickable { + width: 200; height: 200 + contentWidth: row.width; contentHeight: row.height + + topMargin: 20 + bottomMargin: 30 + leftMargin: 40 + rightMargin: 50 + + Row { + id: row + Repeater { + model: 4 + Rectangle { width: 400; height: 600; color: "blue" } + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/nestedPressDelay.qml b/tests/auto/qtquick2/qquickflickable/data/nestedPressDelay.qml new file mode 100644 index 0000000000..60dadcc73c --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/nestedPressDelay.qml @@ -0,0 +1,33 @@ +import QtQuick 2.0 + +Flickable { + property bool pressed: ma.pressed + width: 240 + height: 320 + contentWidth: 480 + contentHeight: 320 + flickableDirection: Flickable.HorizontalFlick + pressDelay: 50 + Flickable { + objectName: "innerFlickable" + flickableDirection: Flickable.VerticalFlick + width: 480 + height: 320 + contentWidth: 480 + contentHeight: 400 + pressDelay: 10000 + Rectangle { + y: 100 + anchors.horizontalCenter: parent.horizontalCenter + width: 240 + height: 100 + color: ma.pressed ? 'blue' : 'green' + MouseArea { + id: ma + objectName: "mouseArea" + anchors.fill: parent + } + } + } +} + diff --git a/tests/auto/qtquick2/qquickflickable/data/resize.qml b/tests/auto/qtquick2/qquickflickable/data/resize.qml new file mode 100644 index 0000000000..1a9ef54107 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/resize.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + function resizeContent() { + flick.resizeContent(600, 600, Qt.point(100, 100)) + } + function returnToBounds() { + flick.returnToBounds() + } + width: 400 + height: 360 + color: "gray" + + Flickable { + id: flick + objectName: "flick" + anchors.fill: parent + contentWidth: 300 + contentHeight: 300 + + Rectangle { + width: flick.contentWidth + height: flick.contentHeight + color: "red" + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/data/wheel.qml b/tests/auto/qtquick2/qquickflickable/data/wheel.qml new file mode 100644 index 0000000000..2928bbcd72 --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/data/wheel.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + color: "gray" + + Flickable { + id: flick + objectName: "flick" + anchors.fill: parent + contentWidth: 800 + contentHeight: 800 + + Rectangle { + width: flick.contentWidth + height: flick.contentHeight + color: "red" + Rectangle { + width: 50; height: 50; color: "blue" + anchors.centerIn: parent + } + } + } +} diff --git a/tests/auto/qtquick2/qquickflickable/qquickflickable.pro b/tests/auto/qtquick2/qquickflickable/qquickflickable.pro new file mode 100644 index 0000000000..7376f593fd --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/qquickflickable.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickflickable +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickflickable.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickflickable/tst_qquickflickable.cpp b/tests/auto/qtquick2/qquickflickable/tst_qquickflickable.cpp new file mode 100644 index 0000000000..1827e0af1c --- /dev/null +++ b/tests/auto/qtquick2/qquickflickable/tst_qquickflickable.cpp @@ -0,0 +1,662 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include + +class tst_qquickflickable : public QObject +{ + Q_OBJECT +public: + tst_qquickflickable(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void create(); + void horizontalViewportSize(); + void verticalViewportSize(); + void properties(); + void boundsBehavior(); + void maximumFlickVelocity(); + void flickDeceleration(); + void pressDelay(); + void nestedPressDelay(); + void flickableDirection(); + void resizeContent(); + void returnToBounds(); + void wheel(); + void movingAndDragging(); + void disabled(); + void flickVelocity(); + void margins(); + +private: + QDeclarativeEngine engine; + + void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); + template + T *findItem(QQuickItem *parent, const QString &objectName); +}; + +tst_qquickflickable::tst_qquickflickable() +{ +} + +void tst_qquickflickable::initTestCase() +{ + +} + +void tst_qquickflickable::cleanupTestCase() +{ + +} + +void tst_qquickflickable::create() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable01.qml"))); + QQuickFlickable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QCOMPARE(obj->isAtXBeginning(), true); + QCOMPARE(obj->isAtXEnd(), false); + QCOMPARE(obj->isAtYBeginning(), true); + QCOMPARE(obj->isAtYEnd(), false); + QCOMPARE(obj->contentX(), 0.); + QCOMPARE(obj->contentY(), 0.); + + QCOMPARE(obj->horizontalVelocity(), 0.); + QCOMPARE(obj->verticalVelocity(), 0.); + + QCOMPARE(obj->isInteractive(), true); + QCOMPARE(obj->boundsBehavior(), QQuickFlickable::DragAndOvershootBounds); + QCOMPARE(obj->pressDelay(), 0); + QCOMPARE(obj->maximumFlickVelocity(), 2500.); + + delete obj; +} + +void tst_qquickflickable::horizontalViewportSize() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable02.qml"))); + QQuickFlickable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentWidth(), 800.); + QCOMPARE(obj->contentHeight(), 300.); + QCOMPARE(obj->isAtXBeginning(), true); + QCOMPARE(obj->isAtXEnd(), false); + QCOMPARE(obj->isAtYBeginning(), true); + QCOMPARE(obj->isAtYEnd(), false); + + delete obj; +} + +void tst_qquickflickable::verticalViewportSize() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); + QQuickFlickable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentWidth(), 200.); + QCOMPARE(obj->contentHeight(), 1200.); + QCOMPARE(obj->isAtXBeginning(), true); + QCOMPARE(obj->isAtXEnd(), false); + QCOMPARE(obj->isAtYBeginning(), true); + QCOMPARE(obj->isAtYEnd(), false); + + delete obj; +} + +void tst_qquickflickable::properties() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("flickable04.qml"))); + QQuickFlickable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QCOMPARE(obj->isInteractive(), false); + QCOMPARE(obj->boundsBehavior(), QQuickFlickable::StopAtBounds); + QCOMPARE(obj->pressDelay(), 200); + QCOMPARE(obj->maximumFlickVelocity(), 2000.); + + QVERIFY(obj->property("ok").toBool() == false); + QMetaObject::invokeMethod(obj, "check"); + QVERIFY(obj->property("ok").toBool() == true); + + delete obj; +} + +void tst_qquickflickable::boundsBehavior() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Flickable { boundsBehavior: Flickable.StopAtBounds }", QUrl::fromLocalFile("")); + QQuickFlickable *flickable = qobject_cast(component.create()); + QSignalSpy spy(flickable, SIGNAL(boundsBehaviorChanged())); + + QVERIFY(flickable); + QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); + + flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); + QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragAndOvershootBounds); + QCOMPARE(spy.count(),1); + flickable->setBoundsBehavior(QQuickFlickable::DragAndOvershootBounds); + QCOMPARE(spy.count(),1); + + flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); + QVERIFY(flickable->boundsBehavior() == QQuickFlickable::DragOverBounds); + QCOMPARE(spy.count(),2); + flickable->setBoundsBehavior(QQuickFlickable::DragOverBounds); + QCOMPARE(spy.count(),2); + + flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); + QVERIFY(flickable->boundsBehavior() == QQuickFlickable::StopAtBounds); + QCOMPARE(spy.count(),3); + flickable->setBoundsBehavior(QQuickFlickable::StopAtBounds); + QCOMPARE(spy.count(),3); +} + +void tst_qquickflickable::maximumFlickVelocity() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Flickable { maximumFlickVelocity: 1.0; }", QUrl::fromLocalFile("")); + QQuickFlickable *flickable = qobject_cast(component.create()); + QSignalSpy spy(flickable, SIGNAL(maximumFlickVelocityChanged())); + + QVERIFY(flickable); + QCOMPARE(flickable->maximumFlickVelocity(), 1.0); + + flickable->setMaximumFlickVelocity(2.0); + QCOMPARE(flickable->maximumFlickVelocity(), 2.0); + QCOMPARE(spy.count(),1); + flickable->setMaximumFlickVelocity(2.0); + QCOMPARE(spy.count(),1); +} + +void tst_qquickflickable::flickDeceleration() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Flickable { flickDeceleration: 1.0; }", QUrl::fromLocalFile("")); + QQuickFlickable *flickable = qobject_cast(component.create()); + QSignalSpy spy(flickable, SIGNAL(flickDecelerationChanged())); + + QVERIFY(flickable); + QCOMPARE(flickable->flickDeceleration(), 1.0); + + flickable->setFlickDeceleration(2.0); + QCOMPARE(flickable->flickDeceleration(), 2.0); + QCOMPARE(spy.count(),1); + flickable->setFlickDeceleration(2.0); + QCOMPARE(spy.count(),1); +} + +void tst_qquickflickable::pressDelay() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Flickable { pressDelay: 100; }", QUrl::fromLocalFile("")); + QQuickFlickable *flickable = qobject_cast(component.create()); + QSignalSpy spy(flickable, SIGNAL(pressDelayChanged())); + + QVERIFY(flickable); + QCOMPARE(flickable->pressDelay(), 100); + + flickable->setPressDelay(200); + QCOMPARE(flickable->pressDelay(), 200); + QCOMPARE(spy.count(),1); + flickable->setPressDelay(200); + QCOMPARE(spy.count(),1); +} + +// QTBUG-17361 +void tst_qquickflickable::nestedPressDelay() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("nestedPressDelay.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *outer = qobject_cast(canvas->rootObject()); + QVERIFY(outer != 0); + + QQuickFlickable *inner = canvas->rootObject()->findChild("innerFlickable"); + QVERIFY(inner != 0); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(150, 150)); + // the MouseArea is not pressed immediately + QVERIFY(outer->property("pressed").toBool() == false); + + // The outer pressDelay will prevail (50ms, vs. 10sec) + // QTRY_VERIFY() has 5sec timeout, so will timeout well within 10sec. + QTRY_VERIFY(outer->property("pressed").toBool() == true); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(150, 150)); + + delete canvas; +} + +void tst_qquickflickable::flickableDirection() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Flickable { flickableDirection: Flickable.VerticalFlick; }", QUrl::fromLocalFile("")); + QQuickFlickable *flickable = qobject_cast(component.create()); + QSignalSpy spy(flickable, SIGNAL(flickableDirectionChanged())); + + QVERIFY(flickable); + QCOMPARE(flickable->flickableDirection(), QQuickFlickable::VerticalFlick); + + flickable->setFlickableDirection(QQuickFlickable::HorizontalAndVerticalFlick); + QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalAndVerticalFlick); + QCOMPARE(spy.count(),1); + + flickable->setFlickableDirection(QQuickFlickable::AutoFlickDirection); + QCOMPARE(flickable->flickableDirection(), QQuickFlickable::AutoFlickDirection); + QCOMPARE(spy.count(),2); + + flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick); + QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick); + QCOMPARE(spy.count(),3); + + flickable->setFlickableDirection(QQuickFlickable::HorizontalFlick); + QCOMPARE(flickable->flickableDirection(), QQuickFlickable::HorizontalFlick); + QCOMPARE(spy.count(),3); +} + +// QtQuick 1.1 +void tst_qquickflickable::resizeContent() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml"))); + QQuickItem *root = qobject_cast(c.create()); + QQuickFlickable *obj = findItem(root, "flick"); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentX(), 0.); + QCOMPARE(obj->contentY(), 0.); + QCOMPARE(obj->contentWidth(), 300.); + QCOMPARE(obj->contentHeight(), 300.); + + QMetaObject::invokeMethod(root, "resizeContent"); + + QCOMPARE(obj->contentX(), 100.); + QCOMPARE(obj->contentY(), 100.); + QCOMPARE(obj->contentWidth(), 600.); + QCOMPARE(obj->contentHeight(), 600.); + + delete root; +} + +// QtQuick 1.1 +void tst_qquickflickable::returnToBounds() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("resize.qml"))); + QQuickItem *root = qobject_cast(c.create()); + QQuickFlickable *obj = findItem(root, "flick"); + + QVERIFY(obj != 0); + QCOMPARE(obj->contentX(), 0.); + QCOMPARE(obj->contentY(), 0.); + QCOMPARE(obj->contentWidth(), 300.); + QCOMPARE(obj->contentHeight(), 300.); + + obj->setContentX(100); + obj->setContentY(400); + QTRY_COMPARE(obj->contentX(), 100.); + QTRY_COMPARE(obj->contentY(), 400.); + + QMetaObject::invokeMethod(root, "returnToBounds"); + + QTRY_COMPARE(obj->contentX(), 0.); + QTRY_COMPARE(obj->contentY(), 0.); + + delete root; +} + +void tst_qquickflickable::wheel() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("wheel.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flick = canvas->rootObject()->findChild("flick"); + QVERIFY(flick != 0); + + { + QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical); + event.setAccepted(false); + QApplication::sendEvent(canvas, &event); + } + + QTRY_VERIFY(flick->contentY() > 0); + QVERIFY(flick->contentX() == 0); + + flick->setContentY(0); + QVERIFY(flick->contentY() == 0); + + { + QWheelEvent event(QPoint(200, 200), -120, Qt::NoButton, Qt::NoModifier, Qt::Horizontal); + event.setAccepted(false); + QApplication::sendEvent(canvas, &event); + } + + QTRY_VERIFY(flick->contentX() > 0); + QVERIFY(flick->contentY() == 0); + + delete canvas; +} + +void tst_qquickflickable::movingAndDragging() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QSignalSpy vDragSpy(flickable, SIGNAL(draggingVerticallyChanged())); + QSignalSpy hDragSpy(flickable, SIGNAL(draggingHorizontallyChanged())); + QSignalSpy dragSpy(flickable, SIGNAL(draggingChanged())); + QSignalSpy vMoveSpy(flickable, SIGNAL(movingVerticallyChanged())); + QSignalSpy hMoveSpy(flickable, SIGNAL(movingHorizontallyChanged())); + QSignalSpy moveSpy(flickable, SIGNAL(movingChanged())); + QSignalSpy dragStartSpy(flickable, SIGNAL(dragStarted())); + QSignalSpy dragEndSpy(flickable, SIGNAL(dragEnded())); + + //Vertical + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90)); + + QTest::mouseMove(canvas, QPoint(50, 80)); + QTest::mouseMove(canvas, QPoint(50, 70)); + QTest::mouseMove(canvas, QPoint(50, 60)); + + QMouseEvent moveEvent(QEvent::MouseMove, QPoint(50, 80), Qt::LeftButton, Qt::LeftButton, 0); + + QVERIFY(!flickable->isDraggingHorizontally()); + QVERIFY(flickable->isDraggingVertically()); + QVERIFY(flickable->isDragging()); + QCOMPARE(vDragSpy.count(), 1); + QCOMPARE(dragSpy.count(), 1); + QCOMPARE(hDragSpy.count(), 0); + QCOMPARE(dragStartSpy.count(), 1); + QCOMPARE(dragEndSpy.count(), 0); + + QVERIFY(!flickable->isMovingHorizontally()); + QVERIFY(flickable->isMovingVertically()); + QVERIFY(flickable->isMoving()); + QCOMPARE(vMoveSpy.count(), 1); + QCOMPARE(moveSpy.count(), 1); + QCOMPARE(hMoveSpy.count(), 0); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60)); + + QTRY_VERIFY(!flickable->isDraggingVertically()); + QVERIFY(!flickable->isDragging()); + QCOMPARE(vDragSpy.count(), 2); + QCOMPARE(dragSpy.count(), 2); + QCOMPARE(hDragSpy.count(), 0); + QCOMPARE(dragStartSpy.count(), 1); + QCOMPARE(dragEndSpy.count(), 1); + + // wait for any motion to end + QTRY_VERIFY(flickable->isMoving() == false); + + //Horizontal + vDragSpy.clear(); + hDragSpy.clear(); + dragSpy.clear(); + vMoveSpy.clear(); + hMoveSpy.clear(); + moveSpy.clear(); + dragStartSpy.clear(); + dragEndSpy.clear(); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(90, 50)); + + QTest::mouseMove(canvas, QPoint(80, 50)); + QTest::mouseMove(canvas, QPoint(70, 50)); + QTest::mouseMove(canvas, QPoint(60, 50)); + + QVERIFY(flickable->isDraggingHorizontally()); + QVERIFY(flickable->isDragging()); + QCOMPARE(vDragSpy.count(), 0); + QCOMPARE(dragSpy.count(), 1); + QCOMPARE(hDragSpy.count(), 1); + QCOMPARE(dragStartSpy.count(), 1); + QCOMPARE(dragEndSpy.count(), 0); + + QVERIFY(!flickable->isMovingVertically()); + QVERIFY(flickable->isMovingHorizontally()); + QVERIFY(flickable->isMoving()); + QCOMPARE(vMoveSpy.count(), 0); + QCOMPARE(moveSpy.count(), 1); + QCOMPARE(hMoveSpy.count(), 1); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(60, 50)); + + QTRY_VERIFY(!flickable->isDraggingHorizontally()); + QVERIFY(!flickable->isDragging()); + QCOMPARE(vDragSpy.count(), 0); + QCOMPARE(dragSpy.count(), 2); + QCOMPARE(hDragSpy.count(), 2); + QCOMPARE(dragStartSpy.count(), 1); + QCOMPARE(dragEndSpy.count(), 1); + + // Don't test moving because a flick could occur + + delete canvas; +} + +void tst_qquickflickable::disabled() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("disabled.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flick = canvas->rootObject()->findChild("flickable"); + QVERIFY(flick != 0); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 90)); + + QTest::mouseMove(canvas, QPoint(50, 80)); + QTest::mouseMove(canvas, QPoint(50, 70)); + QTest::mouseMove(canvas, QPoint(50, 60)); + + QVERIFY(flick->isMoving() == false); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 60)); + + // verify that mouse clicks on other elements still work (QTBUG-20584) + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50, 10)); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 10)); + + QTRY_VERIFY(canvas->rootObject()->property("clicked").toBool() == true); +} + +void tst_qquickflickable::flickVelocity() +{ +#ifdef Q_OS_MAC + QSKIP("Producing flicks on Mac CI impossible due to timing problems"); +#endif + + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("flickable03.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + // flick up + flick(canvas, QPoint(20,190), QPoint(20, 50), 200); + QVERIFY(flickable->verticalVelocity() > 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + // flick down + flick(canvas, QPoint(20,10), QPoint(20, 140), 200); + QVERIFY(flickable->verticalVelocity() < 0.0); + QTRY_VERIFY(flickable->verticalVelocity() == 0.0); + + delete canvas; +} + +void tst_qquickflickable::margins() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("margins.qml"))); + QQuickItem *root = qobject_cast(c.create()); + QQuickFlickable *obj = qobject_cast(root); + QVERIFY(obj != 0); + + // starting state + QCOMPARE(obj->contentX(), -40.); + QCOMPARE(obj->contentY(), -20.); + QCOMPARE(obj->contentWidth(), 1600.); + QCOMPARE(obj->contentHeight(), 600.); + QCOMPARE(obj->xOrigin(), 0.); + QCOMPARE(obj->yOrigin(), 0.); + + // Reduce left margin + obj->setLeftMargin(30); + QTRY_COMPARE(obj->contentX(), -30.); + + // Reduce top margin + obj->setTopMargin(20); + QTRY_COMPARE(obj->contentY(), -20.); + + // position to the far right, including margin + obj->setContentX(1600 + 50 - obj->width()); + obj->returnToBounds(); + QTest::qWait(200); + QCOMPARE(obj->contentX(), 1600. + 50. - obj->width()); + + // position beyond the far right, including margin + obj->setContentX(1600 + 50 - obj->width() + 1.); + obj->returnToBounds(); + QTRY_COMPARE(obj->contentX(), 1600. + 50. - obj->width()); + + // Reduce right margin + obj->setRightMargin(40); + QTRY_COMPARE(obj->contentX(), 1600. + 40. - obj->width()); + QCOMPARE(obj->contentWidth(), 1600.); + + // position to the far bottom, including margin + obj->setContentY(600 + 30 - obj->height()); + obj->returnToBounds(); + QTest::qWait(200); + QCOMPARE(obj->contentY(), 600. + 30. - obj->height()); + + // position beyond the far bottom, including margin + obj->setContentY(600 + 30 - obj->height() + 1.); + obj->returnToBounds(); + QTRY_COMPARE(obj->contentY(), 600. + 30. - obj->height()); + + // Reduce bottom margin + obj->setBottomMargin(20); + QTRY_COMPARE(obj->contentY(), 600. + 20. - obj->height()); + QCOMPARE(obj->contentHeight(), 600.); + + delete root; +} + +void tst_qquickflickable::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas, Qt::LeftButton, 0, from); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); + } + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); +} + +template +T *tst_qquickflickable::findItem(QQuickItem *parent, const QString &objectName) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + return static_cast(item); + } + item = findItem(item, objectName); + if (item) + return static_cast(item); + } + + return 0; +} + +QTEST_MAIN(tst_qquickflickable) + +#include "tst_qquickflickable.moc" diff --git a/tests/auto/qtquick2/qquickflipable/data/crash.qml b/tests/auto/qtquick2/qquickflipable/data/crash.qml new file mode 100644 index 0000000000..a0327918cb --- /dev/null +++ b/tests/auto/qtquick2/qquickflipable/data/crash.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Flipable { + transform: Rotation { + axis.y: 1 + axis.z: 0 + angle: 180 + } +} diff --git a/tests/auto/qtquick2/qquickflipable/data/flipable-abort.qml b/tests/auto/qtquick2/qquickflipable/data/flipable-abort.qml new file mode 100644 index 0000000000..90fc03a5f9 --- /dev/null +++ b/tests/auto/qtquick2/qquickflipable/data/flipable-abort.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Rectangle { + Flipable { + id: flipable + } + Rectangle { + visible: flipable.side == Flipable.Front + } +} diff --git a/tests/auto/qtquick2/qquickflipable/data/test-flipable.qml b/tests/auto/qtquick2/qquickflipable/data/test-flipable.qml new file mode 100644 index 0000000000..dff6d3fe39 --- /dev/null +++ b/tests/auto/qtquick2/qquickflipable/data/test-flipable.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Flipable { + id: flipable + width: 640; height: 480 + + front: Rectangle { anchors.fill: flipable } + back: Rectangle { anchors.fill: flipable } +} diff --git a/tests/auto/qtquick2/qquickflipable/qquickflipable.pro b/tests/auto/qtquick2/qquickflipable/qquickflipable.pro new file mode 100644 index 0000000000..532c42f79b --- /dev/null +++ b/tests/auto/qtquick2/qquickflipable/qquickflipable.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickflipable +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickflipable.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickflipable/tst_qquickflipable.cpp b/tests/auto/qtquick2/qquickflipable/tst_qquickflipable.cpp new file mode 100644 index 0000000000..a217e26714 --- /dev/null +++ b/tests/auto/qtquick2/qquickflipable/tst_qquickflipable.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qquickflipable : public QObject +{ + Q_OBJECT +public: + tst_qquickflipable(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void create(); + void checkFrontAndBack(); + void setFrontAndBack(); + + // below here task issues + void QTBUG_9161_crash(); + void QTBUG_8474_qgv_abort(); + +private: + QDeclarativeEngine engine; +}; + +tst_qquickflipable::tst_qquickflipable() +{ +} +void tst_qquickflipable::initTestCase() +{ +} + +void tst_qquickflipable::cleanupTestCase() +{ + +} + +void tst_qquickflipable::create() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); + QQuickFlipable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + delete obj; +} + +void tst_qquickflipable::checkFrontAndBack() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); + QQuickFlipable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QVERIFY(obj->front() != 0); + QVERIFY(obj->back() != 0); + delete obj; +} + +void tst_qquickflipable::setFrontAndBack() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("test-flipable.qml"))); + QQuickFlipable *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QVERIFY(obj->front() != 0); + QVERIFY(obj->back() != 0); + + QString message = c.url().toString() + ":3:1: QML Flipable: front is a write-once property"; + QTest::ignoreMessage(QtWarningMsg, qPrintable(message)); + obj->setFront(new QQuickRectangle()); + + message = c.url().toString() + ":3:1: QML Flipable: back is a write-once property"; + QTest::ignoreMessage(QtWarningMsg, qPrintable(message)); + obj->setBack(new QQuickRectangle()); + delete obj; +} + +void tst_qquickflipable::QTBUG_9161_crash() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("crash.qml"))); + QQuickItem *root = canvas->rootObject(); + QVERIFY(root != 0); + canvas->show(); + delete canvas; +} + +void tst_qquickflipable::QTBUG_8474_qgv_abort() +{ + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("flipable-abort.qml"))); + QQuickItem *root = canvas->rootObject(); + QVERIFY(root != 0); + canvas->show(); + delete canvas; +} + +QTEST_MAIN(tst_qquickflipable) + +#include "tst_qquickflipable.moc" diff --git a/tests/auto/qtquick2/qquickfocusscope/data/canvasFocus.qml b/tests/auto/qtquick2/qquickfocusscope/data/canvasFocus.qml new file mode 100644 index 0000000000..7d8dac5a22 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/canvasFocus.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Column { + FocusScope { + objectName: "scope1" + width: 20 ;height: 20 + focus: true + Rectangle { + objectName: "item1" + anchors.fill: parent + focus: true + } + } + FocusScope { + objectName: "scope2" + width: 20 ;height: 20 + Rectangle { + objectName: "item2" + anchors.fill: parent + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/chain.qml b/tests/auto/qtquick2/qquickfocusscope/data/chain.qml new file mode 100644 index 0000000000..4b96662318 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/chain.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width:300; height:400 + + property bool focus1: root.activeFocus + property bool focus2: item1.activeFocus + property bool focus3: fs1.activeFocus + property bool focus4: fs2.activeFocus + property bool focus5: theItem.activeFocus + + Item { + id: item1 + FocusScope { + id: fs1 + focus: true + FocusScope { + id: fs2 + focus: true + Item { + id: theItem + focus: true + } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/forceActiveFocus.qml b/tests/auto/qtquick2/qquickfocusscope/data/forceActiveFocus.qml new file mode 100644 index 0000000000..74d2106888 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/forceActiveFocus.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + objectName: "root" + FocusScope { + objectName: "scope" + Item { + objectName: "item-a1" + FocusScope { + objectName: "scope-a" + Item { + objectName: "item-a2" + } + } + } + Item { + objectName: "item-b1" + FocusScope { + objectName: "scope-b" + Item { + objectName: "item-b2" + } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/forcefocus.qml b/tests/auto/qtquick2/qquickfocusscope/data/forcefocus.qml new file mode 100644 index 0000000000..f41582a951 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/forcefocus.qml @@ -0,0 +1,81 @@ +import QtQuick 2.0 + +Rectangle { + width: 800; height: 600 + + FocusScope { + focus: true + + FocusScope { + id: firstScope + objectName: "item0" + focus: true + + Rectangle { + height: 120; width: 420 + + color: "transparent" + border.width: 5; border.color: firstScope.activeFocus?"blue":"black" + + Rectangle { + id: item1; objectName: "item1" + x: 10; y: 10; width: 100; height: 100; color: "green" + border.width: 5; border.color: activeFocus?"blue":"black" + focus: true + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10; width: 100; height: 100; color: "green" + border.width: 5; border.color: activeFocus?"blue":"black" + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + } + } + + FocusScope { + id: secondScope + objectName: "item3" + + Rectangle { + y: 160; height: 120; width: 420 + + color: "transparent" + border.width: 5; border.color: secondScope.activeFocus?"blue":"black" + + Rectangle { + id: item4; objectName: "item4" + x: 10; y: 10; width: 100; height: 100; color: "green" + border.width: 5; border.color: activeFocus?"blue":"black" + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + + Rectangle { + id: item5; objectName: "item5" + x: 310; y: 10; width: 100; height: 100; color: "green" + border.width: 5; border.color: activeFocus?"blue":"black" + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + } + } + } + Keys.onDigit4Pressed: item4.focus = true + Keys.onDigit5Pressed: item5.forceActiveFocus() +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/qtBug13380.qml b/tests/auto/qtquick2/qquickfocusscope/data/qtBug13380.qml new file mode 100644 index 0000000000..29de046b38 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/qtBug13380.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + property bool showRect: false + onShowRectChanged: if (showRect) rect.visible = true + property bool noFocus: !fs2.activeFocus + + FocusScope { + id: fs1 + focus: true + } + Rectangle { + id: rect + visible: false + FocusScope { + id: fs2 + Rectangle { + focus: true + } + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/signalEmission.qml b/tests/auto/qtquick2/qquickfocusscope/data/signalEmission.qml new file mode 100644 index 0000000000..999a40c5ad --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/signalEmission.qml @@ -0,0 +1,33 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + + FocusScope { + focus: true + Rectangle { + objectName: "item1" + color: "blue" + onFocusChanged: focus ? color = "red" : color = "blue" + } + Rectangle { + objectName: "item2" + color: "blue" + onFocusChanged: focus ? color = "red" : color = "blue" + } + } + + FocusScope { + Rectangle { + objectName: "item3" + color: "blue" + onFocusChanged: focus ? color = "red" : color = "blue" + } + Rectangle { + objectName: "item4" + color: "blue" + onFocusChanged: focus ? color = "red" : color = "blue" + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/test.qml b/tests/auto/qtquick2/qquickfocusscope/data/test.qml new file mode 100644 index 0000000000..67be29c3fb --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/test.qml @@ -0,0 +1,77 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onDigit9Pressed: console.log("Error - Root") + + FocusScope { + id: myScope + objectName: "item0" + focus: true + + Keys.onDigit9Pressed: console.log("Error - FocusScope") + + Rectangle { + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + border.color: myScope.activeFocus?"blue":"black" + + Rectangle { + id: item1; objectName: "item1" + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + Keys.onDigit9Pressed: console.debug("Top Left"); + KeyNavigation.right: item2 + focus: true + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onDigit9Pressed: console.log("Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" } + + Rectangle { + id: item3; objectName: "item3" + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + + Keys.onDigit9Pressed: console.log("Bottom Left"); + KeyNavigation.up: myScope + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/test2.qml b/tests/auto/qtquick2/qquickfocusscope/data/test2.qml new file mode 100644 index 0000000000..ad74f3e9f4 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/test2.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Text { text: "All five rectangles should be red" } + + FocusScope { + y: 100 + focus: true; objectName: "item1" + Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item2" + Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item3" + Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item4" + Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } + + FocusScope { + y: 100 + focus: true; objectName: "item5" + Rectangle { width: 50; height: 50; color: parent.activeFocus?"red":"blue" } + } + } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/test3.qml b/tests/auto/qtquick2/qquickfocusscope/data/test3.qml new file mode 100644 index 0000000000..537c30816e --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/test3.qml @@ -0,0 +1,52 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 800 + height: 600 + + ListModel { + id: model + ListElement { name: "1" } + ListElement { name: "2" } + ListElement { name: "3" } + ListElement { name: "4" } + ListElement { name: "5" } + ListElement { name: "6" } + ListElement { name: "7" } + ListElement { name: "8" } + ListElement { name: "9" } + } + + Component { + id: verticalDelegate + FocusScope { + id: root + width: 50; height: 50; + Keys.onDigit9Pressed: console.log("Error - " + name) + Rectangle { + focus: true + Keys.onDigit9Pressed: console.log(name) + width: 50; height: 50; + color: root.ListView.isCurrentItem?"red":"green" + Text { text: name; anchors.centerIn: parent } + } + } + } + + ListView { + width: 800; height: 50; orientation: "Horizontal" + focus: true + model: model + delegate: verticalDelegate + preferredHighlightBegin: 100 + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" + } + + + Text { + y: 100; x: 50 + text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left." + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/test4.qml b/tests/auto/qtquick2/qquickfocusscope/data/test4.qml new file mode 100644 index 0000000000..0eea649f5d --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/test4.qml @@ -0,0 +1,76 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onDigit9Pressed: console.log("Error - Root") + + FocusScope { + id: myScope + + Keys.onDigit9Pressed: console.log("Error - FocusScope") + + Rectangle { + objectName: "item0" + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + border.color: myScope.activeFocus?"blue":"black" + + Rectangle { + id: item1; objectName: "item1" + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + Keys.onDigit9Pressed: console.log("Error - Top Left"); + KeyNavigation.right: item2 + focus: true + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onDigit9Pressed: console.log("Error - Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "There should be no blue borders, or red squares.\nPressing \"9\" should do nothing.\nArrow keys should have no effect." } + + Rectangle { + id: item3; objectName: "item3" + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + + Keys.onDigit9Pressed: console.log("Error - Bottom Left"); + KeyNavigation.up: myScope + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + +} diff --git a/tests/auto/qtquick2/qquickfocusscope/data/test5.qml b/tests/auto/qtquick2/qquickfocusscope/data/test5.qml new file mode 100644 index 0000000000..9c37cd1303 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/data/test5.qml @@ -0,0 +1,84 @@ +import QtQuick 2.0 + +Rectangle { + color: "white" + width: 800 + height: 600 + + Keys.onReturnPressed: console.log("Error - Root") + + FocusScope { + id: myScope + objectName: "item0" + focus: true + + Keys.onReturnPressed: console.log("Error - FocusScope") + + Rectangle { + height: 120 + width: 420 + + color: "transparent" + border.width: 5 + border.color: myScope.activeFocus?"blue":"black" + + Rectangle { + x: 10; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: item1.activeFocus?"blue":"black" + } + + TextEdit { + id: item1; objectName: "item1" + x: 20; y: 20 + width: 90; height: 90 + color: "white" + font.pixelSize: 20 + Keys.onReturnPressed: console.log("Top Left"); + KeyNavigation.right: item2 + focus: true + wrapMode: TextEdit.WordWrap + text: "Box 1" + } + + Rectangle { + id: item2; objectName: "item2" + x: 310; y: 10 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: activeFocus?"blue":"black" + KeyNavigation.left: item1 + Keys.onReturnPressed: console.log("Top Right"); + + Rectangle { + width: 50; height: 50; anchors.centerIn: parent + color: parent.activeFocus?"red":"transparent" + } + } + } + KeyNavigation.down: item3 + } + + Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box or flashing cursor indicates active focus\nUse arrow keys to navigate\nPress Ctrl-Return to print currently focused item" } + + Rectangle { + x: 10; y: 300 + width: 100; height: 100; color: "green" + border.width: 5 + border.color: item3.activeFocus?"blue":"black" + } + + TextEdit { + id: item3; objectName: "item3" + x: 20; y: 310 + width: 90; height: 90 + color: "white" + font.pixelSize: 20 + text: "Box 3" + + Keys.onReturnPressed: console.log("Bottom Left"); + KeyNavigation.up: myScope + wrapMode: TextEdit.WordWrap + } +} diff --git a/tests/auto/qtquick2/qquickfocusscope/qquickfocusscope.pro b/tests/auto/qtquick2/qquickfocusscope/qquickfocusscope.pro new file mode 100644 index 0000000000..138750db3c --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/qquickfocusscope.pro @@ -0,0 +1,10 @@ +CONFIG += testcase +TARGET = tst_qquickfocusscope +SOURCES += tst_qquickfocusscope.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp new file mode 100644 index 0000000000..11cc7a15e0 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp @@ -0,0 +1,668 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qquickfocusscope : public QObject +{ + Q_OBJECT +public: + tst_qquickfocusscope() {} + + template + T *findItem(QQuickItem *parent, const QString &id); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void basic(); + void nested(); + void noFocus(); + void textEdit(); + void forceFocus(); + void noParentFocus(); + void signalEmission(); + void qtBug13380(); + void forceActiveFocus(); + void canvasFocus(); +}; +void tst_qquickfocusscope::initTestCase() +{ +} + +void tst_qquickfocusscope::cleanupTestCase() +{ + +} + +/* + Find an item with the specified id. +*/ +template +T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName) +{ + const QMetaObject &mo = T::staticMetaObject; + QList children = parent->childItems(); + for (int i = 0; i < children.count(); ++i) { + QQuickItem *item = children.at(i); + if (item) { + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + return static_cast(item); + } + item = findItem(item, objectName); + if (item) + return static_cast(item); + } + } + return 0; +} + +void tst_qquickfocusscope::basic() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml"))); + + QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(view->isTopLevel()); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QTest::qWait(50); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QTest::qWait(50); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::nested() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml"))); + + QQuickFocusScope *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickFocusScope *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickFocusScope *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QQuickFocusScope *item4 = findItem(view->rootObject(), QLatin1String("item4")); + QQuickFocusScope *item5 = findItem(view->rootObject(), QLatin1String("item5")); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + QVERIFY(item5 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(item4->hasActiveFocus() == true); + QVERIFY(item5->hasActiveFocus() == true); + delete view; +} + +void tst_qquickfocusscope::noFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml"))); + + QQuickRectangle *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + delete view; +} + +void tst_qquickfocusscope::textEdit() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml"))); + + QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QQuickTextEdit *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickTextEdit *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + + QTRY_VERIFY(view == qGuiApp->focusWindow()); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::forceFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml"))); + + QQuickFocusScope *item0 = findItem(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickFocusScope *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QQuickRectangle *item4 = findItem(view->rootObject(), QLatin1String("item4")); + QQuickRectangle *item5 = findItem(view->rootObject(), QLatin1String("item5")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + QVERIFY(item5 != 0); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_4); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_5); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::noParentFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml"))); + QVERIFY(view->rootObject()); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(view->rootObject()->property("focus1") == false); + QVERIFY(view->rootObject()->property("focus2") == false); + QVERIFY(view->rootObject()->property("focus3") == true); + QVERIFY(view->rootObject()->property("focus4") == true); + QVERIFY(view->rootObject()->property("focus5") == true); + + delete view; +} + +void tst_qquickfocusscope::signalEmission() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml"))); + + QQuickRectangle *item1 = findItem(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem(view->rootObject(), QLatin1String("item3")); + QQuickRectangle *item4 = findItem(view->rootObject(), QLatin1String("item4")); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVariant blue(QColor("blue")); + QVariant red(QColor("red")); + + item1->setFocus(true); + QCOMPARE(item1->property("color"), red); + QCOMPARE(item2->property("color"), blue); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + item2->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + item3->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), red); + QCOMPARE(item4->property("color"), blue); + + item4->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), red); + + item4->setFocus(false); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + delete view; +} + +void tst_qquickfocusscope::qtBug13380() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml"))); + + view->show(); + QVERIFY(view->rootObject()); + view->requestActivateWindow(); + qApp->processEvents(); + + QTest::qWaitForWindowShown(view); + + QTRY_VERIFY(view == qGuiApp->focusWindow()); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + view->rootObject()->setProperty("showRect", true); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + delete view; +} + +void tst_qquickfocusscope::forceActiveFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml"))); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QQuickItem *rootObject = view->rootObject(); + QVERIFY(rootObject); + + QQuickItem *scope = findItem(rootObject, QLatin1String("scope")); + QQuickItem *itemA1 = findItem(rootObject, QLatin1String("item-a1")); + QQuickItem *scopeA = findItem(rootObject, QLatin1String("scope-a")); + QQuickItem *itemA2 = findItem(rootObject, QLatin1String("item-a2")); + QQuickItem *itemB1 = findItem(rootObject, QLatin1String("item-b1")); + QQuickItem *scopeB = findItem(rootObject, QLatin1String("scope-b")); + QQuickItem *itemB2 = findItem(rootObject, QLatin1String("item-b2")); + + QVERIFY(scope); + QVERIFY(itemA1); + QVERIFY(scopeA); + QVERIFY(itemA2); + QVERIFY(itemB1); + QVERIFY(scopeB); + QVERIFY(itemB2); + + QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool))); + + // First, walk the focus from item-a1 down to item-a2 and back again + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QVERIFY(!rootObject->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 2); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + // Then jump back and forth between branch 'a' and 'b' + itemB1->forceActiveFocus(); + QVERIFY(itemB1->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 3); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeB->forceActiveFocus(); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeB->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 4); + QCOMPARE(scopeBSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!scopeB->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 5); + QCOMPARE(scopeBSpy.count(), 2); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemB2->forceActiveFocus(); + QVERIFY(!itemA2->hasActiveFocus()); + QVERIFY(itemB2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 6); + QCOMPARE(scopeBSpy.count(), 3); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + delete view; +} + +void tst_qquickfocusscope::canvasFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml"))); + + QQuickView alternateView; + + QQuickItem *rootObject = view->rootObject(); + QVERIFY(rootObject); + + QQuickItem *rootItem = view->rootItem(); + QQuickItem *scope1 = findItem(rootObject, QLatin1String("scope1")); + QQuickItem *item1 = findItem(rootObject, QLatin1String("item1")); + QQuickItem *scope2 = findItem(rootObject, QLatin1String("scope2")); + QQuickItem *item2 = findItem(rootObject, QLatin1String("item2")); + + QVERIFY(scope1); + QVERIFY(item1); + QVERIFY(scope2); + QVERIFY(item2); + + QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool))); + QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool))); + QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool))); + QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool))); + QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool))); + QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool))); + QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool))); + QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool))); + + QEXPECT_FAIL("", "QTBUG-22415", Abort); + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + QCOMPARE(scope2->hasFocus(), false); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), false); + QCOMPARE(item2->hasActiveFocus(), false); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + // Now the canvas has focus, active focus given to item1 + QCOMPARE(rootItem->hasFocus(), true); + QCOMPARE(rootItem->hasActiveFocus(), true); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), true); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), true); + QCOMPARE(scope2->hasFocus(), false); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), false); + QCOMPARE(item2->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 1); + QCOMPARE(rootActiveFocusSpy.count(), 1); + QCOMPARE(scope1FocusSpy.count(), 0); + QCOMPARE(scope1ActiveFocusSpy.count(), 1); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 1); + + + // view->hide(); // seemingly doesn't remove focus, so have an another view steal it. + alternateView.show(); + alternateView.requestActivateWindow(); + QTest::qWaitForWindowShown(&alternateView); + QTRY_VERIFY(QGuiApplication::focusWindow() == &alternateView); + + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 2); + QCOMPARE(rootActiveFocusSpy.count(), 2); + QCOMPARE(scope1FocusSpy.count(), 0); + QCOMPARE(scope1ActiveFocusSpy.count(), 2); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 2); + + + // canvas does not have focus, so item2 will not get active focus + item2->forceActiveFocus(); + + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), false); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + QCOMPARE(scope2->hasFocus(), true); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), true); + QCOMPARE(item2->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 2); + QCOMPARE(rootActiveFocusSpy.count(), 2); + QCOMPARE(scope1FocusSpy.count(), 1); + QCOMPARE(scope1ActiveFocusSpy.count(), 2); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 2); + QCOMPARE(scope2FocusSpy.count(), 1); + QCOMPARE(scope2ActiveFocusSpy.count(), 0); + QCOMPARE(item2FocusSpy.count(), 1); + QCOMPARE(item2ActiveFocusSpy.count(), 0); + + // give the canvas focus, and item2 will get active focus + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(QGuiApplication::focusWindow() == view); + + QCOMPARE(rootItem->hasFocus(), true); + QCOMPARE(rootItem->hasActiveFocus(), true); + QCOMPARE(scope2->hasFocus(), true); + QCOMPARE(scope2->hasActiveFocus(), true); + QCOMPARE(item2->hasFocus(), true); + QCOMPARE(item2->hasActiveFocus(), true); + QCOMPARE(rootFocusSpy.count(), 3); + QCOMPARE(rootActiveFocusSpy.count(), 3); + QCOMPARE(scope2FocusSpy.count(), 1); + QCOMPARE(scope2ActiveFocusSpy.count(), 1); + QCOMPARE(item2FocusSpy.count(), 1); + QCOMPARE(item2ActiveFocusSpy.count(), 1); + + delete view; +} + +QTEST_MAIN(tst_qquickfocusscope) + +#include "tst_qquickfocusscope.moc" diff --git a/tests/auto/qtquick2/qquickgridview/data/ComponentView.qml b/tests/auto/qtquick2/qquickgridview/data/ComponentView.qml new file mode 100644 index 0000000000..12ab6c92d1 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/ComponentView.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +GridView { + id: view + + property string title + + width: 100; height: 100; + + model: 1 + delegate: Text { objectName: "listItem"; text: view.title } + header: Text { objectName: "header"; text: view.title } + footer: Text { objectName: "footer"; text: view.title } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/asyncloader.qml b/tests/auto/qtquick2/qquickgridview/data/asyncloader.qml new file mode 100644 index 0000000000..ab66f20a1e --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/asyncloader.qml @@ -0,0 +1,36 @@ + +import QtQuick 2.0 + +Rectangle { + id: root + width: 300; height: 400 + color: "#2200FF00" + + Loader { + asynchronous: true + sourceComponent: viewComp + anchors.fill: parent + } + + Component { + id: viewComp + GridView { + objectName: "view" + width: 300; height: 400 + model: 40 + delegate: aDelegate + + highlight: Rectangle { color: "lightsteelblue" } + } + } + // The delegate for each list + Component { + id: aDelegate + Item { + objectName: "wrapper" + width: 100 + height: 100 + Text { text: 'Index: ' + index } + } + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/attachedSignals.qml b/tests/auto/qtquick2/qquickgridview/data/attachedSignals.qml new file mode 100644 index 0000000000..73c10d8caf --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/attachedSignals.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +GridView { + id: view + width: 240; height: 320 + + property variant addedDelegates: [] + property int removedDelegateCount + + model: testModel + + cellWidth: delegateWidth; cellHeight: delegateHeight + + delegate: Rectangle { + width: delegateWidth; height: delegateHeight + border.width: 1 + GridView.onAdd: { + var obj = GridView.view.addedDelegates + obj.push(model.name) + GridView.view.addedDelegates = obj + } + GridView.onRemove: { + view.removedDelegateCount += 1 + } + } +} + diff --git a/tests/auto/qtquick2/qquickgridview/data/creationContext.qml b/tests/auto/qtquick2/qquickgridview/data/creationContext.qml new file mode 100644 index 0000000000..79a682788b --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/creationContext.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +ComponentView { + title: "Hello!" +} diff --git a/tests/auto/qtquick2/qquickgridview/data/displaygrid.qml b/tests/auto/qtquick2/qquickgridview/data/displaygrid.qml new file mode 100644 index 0000000000..1da4fe50ac --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/displaygrid.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + Text { + y: 20 + id: displayText + objectName: "displayText" + text: display + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: myDelegate + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/footer.qml b/tests/auto/qtquick2/qquickgridview/data/footer.qml new file mode 100644 index 0000000000..9083f9f57c --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/footer.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Rectangle { + property bool showHeader: false + + function changeFooter() { + grid.footer = footer2 + } + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + Component { + id: headerComponent + Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } + } + + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: myDelegate + header: parent.showHeader ? headerComponent : null + footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 } + } + + Component { + id: footer2 + Text { objectName: "footer2"; text: "Footer 2" + x + "," + y; width: 50; height: 20 } + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview-enforcerange.qml b/tests/auto/qtquick2/qquickgridview/data/gridview-enforcerange.qml new file mode 100644 index 0000000000..2bfe7da78e --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview-enforcerange.qml @@ -0,0 +1,58 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Item { + id: wrapper + objectName: "wrapper" + height: 100 + width: 100 + Text { + text: index + } + Text { + y: 25 + id: textName + objectName: "textName" + text: name + } + Text { + y: 50 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + y: 75 + text: wrapper.y + } + } + } + + Component { + id: myHighlight + Rectangle { + color: "lightsteelblue" + } + } + + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + model: testModel + delegate: myDelegate + highlight: myHighlight + flow: (testTopToBottom == true) ? GridView.TopToBottom : GridView.LeftToRight + layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight + preferredHighlightBegin: 100 + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" + focus: true + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview-initCurrent.qml b/tests/auto/qtquick2/qquickgridview/data/gridview-initCurrent.qml new file mode 100644 index 0000000000..624f639962 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview-initCurrent.qml @@ -0,0 +1,66 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + property int current: grid.currentIndex + property bool showHeader: false + property bool showFooter: false + + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + + Component { + id: headerFooter + Rectangle { height: 30; width: 240; color: "blue" } + } + + GridView { + id: grid + objectName: "grid" + focus: true + width: 240 + height: 320 + currentIndex: 35 + cellWidth: 80 + cellHeight: 60 + delegate: myDelegate + highlightMoveDuration: 400 + model: testModel + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview-noCurrent.qml b/tests/auto/qtquick2/qquickgridview/data/gridview-noCurrent.qml new file mode 100644 index 0000000000..600716e2d4 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview-noCurrent.qml @@ -0,0 +1,52 @@ +import QtQuick 2.0 + +Rectangle { + property int current: grid.currentIndex + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + GridView { + id: grid + objectName: "grid" + focus: true + width: 240 + height: 320 + currentIndex: -1 + cellWidth: 80 + cellHeight: 60 + delegate: myDelegate + model: testModel + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview1.qml b/tests/auto/qtquick2/qquickgridview/data/gridview1.qml new file mode 100644 index 0000000000..4bf6f0b952 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview1.qml @@ -0,0 +1,69 @@ +import QtQuick 2.0 + +Rectangle { + id: root + property int count: grid.count + property bool showHeader: false + property bool showFooter: false + property real cacheBuffer: 0 + property int added: -1 + property variant removed + + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + property string name: model.name + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + GridView.onAdd: root.added = index + GridView.onRemove: root.removed = name + } + }, + Component { + id: headerFooter + Rectangle { width: 30; height: 320; color: "blue" } + } + ] + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 80 + cellHeight: 60 + flow: (testTopToBottom == false) ? GridView.LeftToRight : GridView.TopToBottom + layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight + model: testModel + delegate: myDelegate + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + cacheBuffer: root.cacheBuffer + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview2.qml b/tests/auto/qtquick2/qquickgridview/data/gridview2.qml new file mode 100644 index 0000000000..5fb45a1613 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview2.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +GridView { + anchors.fill: parent + width: 320; height: 200 + cellWidth: 100; cellHeight: 100; cacheBuffer: 200; focus: true + keyNavigationWraps: true; highlightFollowsCurrentItem: false + + model: ListModel { + id: appModel + ListElement { lColor: "red" } + ListElement { lColor: "yellow" } + ListElement { lColor: "green" } + ListElement { lColor: "blue" } + } + + delegate: Item { + width: 100; height: 100 + Rectangle { + color: lColor; x: 4; y: 4 + width: 92; height: 92 + } + } + + highlight: Rectangle { width: 100; height: 100; color: "black" } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview3.qml b/tests/auto/qtquick2/qquickgridview/data/gridview3.qml new file mode 100644 index 0000000000..a8c1c5a0f7 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview3.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +GridView { + anchors.fill: parent + width: 320; height: 200 +} diff --git a/tests/auto/qtquick2/qquickgridview/data/gridview4.qml b/tests/auto/qtquick2/qquickgridview/data/gridview4.qml new file mode 100644 index 0000000000..eed3a2bdb1 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/gridview4.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +GridView { + width: 405 + height: 200 + cellWidth: width/9 + cellHeight: height/2 + + model: 18 + delegate: Rectangle { objectName: "delegate"; width: 10; height: 10; color: "green" } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/header.qml b/tests/auto/qtquick2/qquickgridview/data/header.qml new file mode 100644 index 0000000000..648e2a2298 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/header.qml @@ -0,0 +1,40 @@ +import QtQuick 2.0 + +Rectangle { + function changeHeader() { + grid.header = header2 + } + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 80 + height: 60 + border.color: "blue" + Text { + text: index + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + GridView { + id: grid + objectName: "grid" + width: initialViewWidth + height: initialViewHeight + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: myDelegate + header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } + } + + Component { + id: header2 + Text { objectName: "header2"; text: "Header 2 " + x + "," + y; width: 50; height: 20 } + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/manual-highlight.qml b/tests/auto/qtquick2/qquickgridview/data/manual-highlight.qml new file mode 100644 index 0000000000..c2f1d20fb1 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/manual-highlight.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Item { + + ListModel { + id: model + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + ListElement { + name: "Bob Brown" + number: "555 5845" + } + } + + Component { + id: highlight + Rectangle { + objectName: "highlight" + width: 80; height: 80 + color: "lightsteelblue"; radius: 5 + y: grid.currentItem.y+5 + x: grid.currentItem.x+5 + } + } + + GridView { + id: grid + objectName: "grid" + anchors.fill: parent + model: model + delegate: Text { objectName: "wrapper"; text: name; width: 80; height: 80 } + + highlight: highlight + highlightFollowsCurrentItem: false + focus: true + } + +} diff --git a/tests/auto/qtquick2/qquickgridview/data/margins.qml b/tests/auto/qtquick2/qquickgridview/data/margins.qml new file mode 100644 index 0000000000..d369658a91 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/margins.qml @@ -0,0 +1,55 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + width: 100 + height: 80 + border.color: "blue" + property string name: model.name + Text { + text: index + } + Text { + x: 40 + text: wrapper.x + ", " + wrapper.y + } + Text { + y: 20 + id: textName + objectName: "textName" + text: name + } + Text { + y: 40 + id: textNumber + objectName: "textNumber" + text: number + } + color: GridView.isCurrentItem ? "lightsteelblue" : "white" + } + } + GridView { + id: grid + objectName: "grid" + width: 240 + height: 320 + cellWidth: 100 + cellHeight: 80 + leftMargin: 30 + rightMargin: 50 + flow: GridView.TopToBottom + layoutDirection: (testRightToLeft == true) ? Qt.RightToLeft : Qt.LeftToRight + model: testModel + delegate: myDelegate + } + Text { anchors.bottom: parent.bottom; text: grid.contentX } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/mirroring.qml b/tests/auto/qtquick2/qquickgridview/data/mirroring.qml new file mode 100644 index 0000000000..b9aff501c1 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/mirroring.qml @@ -0,0 +1,43 @@ +// This example demonstrates how item positioning +// changes in right-to-left layout direction + +import QtQuick 2.0 + +Rectangle { + color: "lightgray" + width: 340 + height: 370 + + VisualItemModel { + id: itemModel + objectName: "itemModel" + Rectangle { + objectName: "item1" + height: 110; width: 120; color: "#FFFEF0" + Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item2" + height: 130; width: 150; color: "#F0FFF7" + Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item3" + height: 170; width: 190; color: "#F4F0FF" + Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + GridView { + id: view + objectName: "view" + cellWidth: 190 + cellHeight: 170 + anchors.fill: parent + anchors.bottomMargin: 30 + model: itemModel + highlightRangeMode: "StrictlyEnforceRange" + flow: GridView.TopToBottom + flickDeceleration: 2000 + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/propertychangestest.qml b/tests/auto/qtquick2/qquickgridview/data/propertychangestest.qml new file mode 100644 index 0000000000..97efbe78f5 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/propertychangestest.qml @@ -0,0 +1,69 @@ +import QtQuick 2.0 + +Rectangle { + width: 360; height: 120; color: "white" + Component { + id: delegate + Item { + id: wrapper + width: 180; height: 40; + Column { + x: 5; y: 5 + Text { text: 'Name: ' + name } + Text { text: 'Number: ' + number } + } + } + } + Component { + id: highlightRed + Rectangle { + color: "red" + radius: 10 + opacity: 0.5 + } + } + GridView { + cellWidth:180 + cellHeight:40 + objectName: "gridView" + anchors.fill: parent + model: listModel + delegate: delegate + highlight: highlightRed + focus: true + keyNavigationWraps: true + cacheBuffer: 10 + flow: GridView.LeftToRight + } + + data:[ + ListModel { + id: listModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + }, + ListModel { + objectName: "alternateModel" + ListElement { + name: "Jack" + number: "555 8426" + } + ListElement { + name: "Mary" + number: "555 3264" + } + } + ] +} + + diff --git a/tests/auto/qtquick2/qquickgridview/data/resizeview.qml b/tests/auto/qtquick2/qquickgridview/data/resizeview.qml new file mode 100644 index 0000000000..1f730a4a8a --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/resizeview.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + property real initialHeight + + GridView { + id: grid + objectName: "grid" + width: 240 + height: initialHeight + cellWidth: 80 + cellHeight: 60 + model: testModel + delegate: Rectangle { + objectName: "wrapper" + width: 80 + height: 60 + border.width: 1 + } + } +} + diff --git a/tests/auto/qtquick2/qquickgridview/data/setindex.qml b/tests/auto/qtquick2/qquickgridview/data/setindex.qml new file mode 100644 index 0000000000..ef80f3a2fb --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/setindex.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 200 + Component { + id: appDelegate + + Item { + id : wrapper + function startupFunction() { + if (index == 5) view.currentIndex = index; + } + Component.onCompleted: startupFunction(); + width: 30; height: 30 + Text { text: index } + } + } + + GridView { + id: view + objectName: "grid" + anchors.fill: parent + cellWidth: 30; cellHeight: 30 + model: 35 + delegate: appDelegate + focus: true + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/snapToRow.qml b/tests/auto/qtquick2/qquickgridview/data/snapToRow.qml new file mode 100644 index 0000000000..f079a048f0 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/snapToRow.qml @@ -0,0 +1,49 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 240 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 80 + width: 80 + Column { + Text { + text: index + } + Text { + text: wrapper.x + ", " + wrapper.y + } + } + color: GridView.isCurrentItem ? "lightsteelblue" : "transparent" + } + } + GridView { + id: grid + objectName: "grid" + anchors.fill: parent + cellWidth: 80 + cellHeight: 80 + preferredHighlightBegin: 20 + preferredHighlightEnd: 100 + snapMode: GridView.SnapToRow + layoutDirection: Qt.RightToLeft + flow: GridView.TopToBottom + highlightRangeMode: GridView.StrictlyEnforceRange + highlight: Rectangle { width: 80; height: 80; color: "yellow" } + model: 54 + delegate: myDelegate + } + + Text { + anchors.right: parent.right + anchors.bottom: parent.bottom + text: grid.contentX + ", " + grid.contentY + } +} diff --git a/tests/auto/qtquick2/qquickgridview/data/unaligned.qml b/tests/auto/qtquick2/qquickgridview/data/unaligned.qml new file mode 100644 index 0000000000..445400e8b4 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/data/unaligned.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +GridView { + width: 400 + height: 200 + cellWidth: width/9 + cellHeight: height/2 + + model: testModel + delegate: Rectangle { + objectName: "wrapper"; width: 10; height: 10; color: "green" + Text { text: index } + } +} + diff --git a/tests/auto/qtquick2/qquickgridview/qquickgridview.pro b/tests/auto/qtquick2/qquickgridview/qquickgridview.pro new file mode 100644 index 0000000000..b43e720162 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/qquickgridview.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickgridview +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickgridview.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +CONFIG += insignificant_test #QTBUG-22807 +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib widgets diff --git a/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp new file mode 100644 index 0000000000..cc0f7b7225 --- /dev/null +++ b/tests/auto/qtquick2/qquickgridview/tst_qquickgridview.cpp @@ -0,0 +1,3705 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include + +Q_DECLARE_METATYPE(Qt::LayoutDirection) +Q_DECLARE_METATYPE(QQuickGridView::Flow) + +class tst_QQuickGridView : public QObject +{ + Q_OBJECT +public: + tst_QQuickGridView(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void items(); + void changed(); + void inserted(); + void inserted_more(); + void inserted_more_data(); + void insertBeforeVisible(); + void insertBeforeVisible_data(); + void removed(); + void addOrRemoveBeforeVisible(); + void addOrRemoveBeforeVisible_data(); + void clear(); + void moved(); + void moved_data(); + void multipleChanges(); + void multipleChanges_data(); + void swapWithFirstItem(); + void changeFlow(); + void currentIndex(); + void noCurrentIndex(); + void defaultValues(); + void properties(); + void propertyChanges(); + void componentChanges(); + void modelChanges(); + void positionViewAtIndex(); + void positionViewAtIndex_rightToLeft(); + void mirroring(); + void snapping(); + void resetModel(); + void enforceRange(); + void enforceRange_rightToLeft(); + void QTBUG_8456(); + void manualHighlight(); + void footer(); + void footer_data(); + void header(); + void header_data(); + void resizeViewAndRepaint(); + void indexAt(); + void onAdd(); + void onAdd_data(); + void onRemove(); + void onRemove_data(); + void columnCount(); + void margins(); + void creationContext(); + void snapToRow_data(); + void snapToRow(); + void unaligned(); + void cacheBuffer(); + void asynchronous(); + +private: + QQuickView *createView(); + void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); + template + T *findItem(QQuickItem *parent, const QString &id, int index=-1); + template + QList findItems(QQuickItem *parent, const QString &objectName); + void dumpTree(QQuickItem *parent, int depth = 0); +}; + +template +void tst_qquickgridview_move(int from, int to, int n, T *items) +{ + if (n == 1) { + items->move(from, to); + } else { + T replaced; + int i=0; + typename T::ConstIterator it=items->begin(); it += from+n; + for (; ibegin(); it += from; + for (; ibegin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +void tst_QQuickGridView::initTestCase() +{ +} + +void tst_QQuickGridView::cleanupTestCase() +{ + +} + + +class TestModel : public QAbstractListModel +{ +public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + TestModel(QObject *parent=0) : QAbstractListModel(parent) { + QHash roles; + roles[Name] = "name"; + roles[Number] = "number"; + setRoleNames(roles); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; + } + + int count() const { return rowCount(); } + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + void addItem(const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair(name, number)); + emit endInsertRows(); + } + + void addItems(const QList > &items) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); + for (int i=0; i(items[i].first, items[i].second)); + emit endInsertRows(); + } + + void insertItem(int index, const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair(name, number)); + emit endInsertRows(); + } + + void insertItems(int index, const QList > &items) { + emit beginInsertRows(QModelIndex(), index, index + items.count() - 1); + for (int i=0; i(items[i].first, items[i].second)); + emit endInsertRows(); + } + + void removeItem(int index) { + emit beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + emit endRemoveRows(); + } + + void removeItems(int index, int count) { + emit beginRemoveRows(QModelIndex(), index, index+count-1); + while (count--) + list.removeAt(index); + emit endRemoveRows(); + } + + void moveItem(int from, int to) { + emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); + list.move(from, to); + emit endMoveRows(); + } + + void moveItems(int from, int to, int count) { + emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); + tst_qquickgridview_move(from, to, count, &list); + emit endMoveRows(); + } + + void modifyItem(int idx, const QString &name, const QString &number) { + list[idx] = QPair(name, number); + emit dataChanged(index(idx,0), index(idx,0)); + } + + void clear() { + int count = list.count(); + emit beginRemoveRows(QModelIndex(), 0, count-1); + list.clear(); + emit endRemoveRows(); + } + + +private: + QList > list; +}; + +tst_QQuickGridView::tst_QQuickGridView() +{ +} + +void tst_QQuickGridView::items() +{ + QQuickView *canvas = createView(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Billy", "22345"); + model.addItem("Sam", "2945"); + model.addItem("Ben", "04321"); + model.addItem("Jim", "0780"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(gridview->count(), model.count()); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + for (int i = 0; i < model.count(); ++i) { + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + // set an empty model and confirm that items are destroyed + TestModel model2; + ctxt->setContextProperty("testModel", &model2); + + int itemCount = findItems(contentItem, "wrapper").count(); + QTRY_VERIFY(itemCount == 0); + + delete canvas; +} + +void tst_QQuickGridView::changed() +{ + QQuickView *canvas = createView(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Billy", "22345"); + model.addItem("Sam", "2945"); + model.addItem("Ben", "04321"); + model.addItem("Jim", "0780"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickFlickable *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.modifyItem(1, "Will", "9876"); + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + delete canvas; +} + +void tst_QQuickGridView::inserted() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.insertItem(1, "Will", "9876"); + + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + // Checks that onAdd is called + int added = canvas->rootObject()->property("added").toInt(); + QTRY_COMPARE(added, 1); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), (i/3)*60.0); + } + + model.insertItem(0, "Foo", "1111"); // zero index, and current item + + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + QTRY_COMPARE(gridview->currentIndex(), 1); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + for (int i = model.count(); i < 30; ++i) + model.insertItem(i, "Hello", QString::number(i)); + + gridview->setContentY(120); + + // Insert item outside visible area + model.insertItem(1, "Hello", "1324"); + + QTRY_VERIFY(gridview->contentY() == 120); + + delete canvas; +} + +void tst_QQuickGridView::inserted_more() +{ + QFETCH(qreal, contentY); + QFETCH(int, insertIndex); + QFETCH(int, insertCount); + QFETCH(qreal, itemsOffsetAfterMove); + + QQuickText *name; + QQuickText *number; + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + gridview->setContentY(contentY); + + QList > newData; + for (int i=0; iproperty("count").toInt(), model.count()); + + // check visibleItems.first() is in correct position + QQuickItem *item0 = findItem(contentItem, "wrapper", 0); + QVERIFY(item0); + QCOMPARE(item0->y(), itemsOffsetAfterMove); + + QList items = findItems(contentItem, "wrapper"); + int firstVisibleIndex = -1; + for (int i=0; iy() >= contentY) { + QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); + firstVisibleIndex = e.evaluate().toInt(); + break; + } + } + QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + + QCOMPARE(item->x(), (i%3)*80.0); + QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); + + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::inserted_more_data() +{ + QTest::addColumn("contentY"); + QTest::addColumn("insertIndex"); + QTest::addColumn("insertCount"); + QTest::addColumn("itemsOffsetAfterMove"); + + QTest::newRow("add 1, before visible items") + << 120.0 // show 6-23 + << 5 << 1 + << 0.0; // insert 1 above first visible, grid is rearranged; first visible moves forward within its row + // new 1st visible item is at 0 + + QTest::newRow("add 2, before visible items") + << 120.0 // show 6-23 + << 5 << 2 + << 0.0; // insert 2 above first visible, grid is rearranged; first visible moves forward within its row + + QTest::newRow("add 3, before visible items") + << 120.0 // show 6-23 + << 5 << 3 + << -60.0; // insert 3 (1 row) above first visible in negative pos, first visible does not move + + QTest::newRow("add 5, before visible items") + << 120.0 // show 6-23 + << 5 << 5 + << -60.0; // insert 1 row + 2 items above first visible, 1 row added at negative pos, + // grid is rearranged and first visible moves forward within its row + + QTest::newRow("add 6, before visible items") + << 120.0 // show 6-23 + << 5 << 6 + << -60.0 * 2; // insert 2 rows above first visible in negative pos, first visible does not move + + + + QTest::newRow("add 1, at start of visible, content at start") + << 0.0 + << 0 << 1 + << 0.0; + + QTest::newRow("add multiple, at start of visible, content at start") + << 0.0 + << 0 << 3 + << 0.0; + + QTest::newRow("add 1, at start of visible, content not at start") + << 120.0 // show 6-23 + << 6 << 1 + << 0.0; + + QTest::newRow("add multiple, at start of visible, content not at start") + << 120.0 // show 6-23 + << 6 << 3 + << 0.0; + + + QTest::newRow("add 1, at end of visible, content at start") + << 0.0 + << 17 << 1 + << 0.0; + + QTest::newRow("add 1, at end of visible, content at start") + << 0.0 + << 17 << 3 + << 0.0; + + QTest::newRow("add 1, at end of visible, content not at start") + << 120.0 // show 6-23 + << 23 << 1 + << 0.0; + + QTest::newRow("add multiple, at end of visible, content not at start") + << 120.0 // show 6-23 + << 23 << 3 + << 0.0; + + + QTest::newRow("add 1, after visible, content at start") + << 0.0 + << 20 << 1 + << 0.0; + + QTest::newRow("add 1, after visible, content at start") + << 0.0 + << 20 << 3 + << 0.0; + + QTest::newRow("add 1, after visible, content not at start") + << 120.0 // show 6-23 + << 24 << 1 + << 0.0; + + QTest::newRow("add multiple, after visible, content not at start") + << 120.0 // show 6-23 + << 24 << 3 + << 0.0; +} + +void tst_QQuickGridView::insertBeforeVisible() +{ + QFETCH(int, insertIndex); + QFETCH(int, insertCount); + QFETCH(int, cacheBuffer); + + QQuickText *name; + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + gridview->setCacheBuffer(cacheBuffer); + + // trigger a refill (not just setting contentY) so that the visibleItems grid is updated + int firstVisibleIndex = 20; // move to an index where the top item is not visible + gridview->setContentY(firstVisibleIndex * 20.0); + gridview->setCurrentIndex(firstVisibleIndex); + qApp->processEvents(); + QTRY_COMPARE(gridview->currentIndex(), firstVisibleIndex); + QQuickItem *item = findItem(contentItem, "wrapper", firstVisibleIndex); + QVERIFY(item); + QCOMPARE(item->y(), gridview->contentY()); + + QList > newData; + for (int i=0; iproperty("count").toInt(), model.count()); + + // now, moving to the top of the view should position the inserted items correctly + int itemsOffsetAfterMove = (insertCount / 3) * -60.0; + gridview->setCurrentIndex(0); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentY(), 0.0 + itemsOffsetAfterMove); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QCOMPARE(item->x(), (i%3)*80.0); + QCOMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::insertBeforeVisible_data() +{ + QTest::addColumn("insertIndex"); + QTest::addColumn("insertCount"); + QTest::addColumn("cacheBuffer"); + + QTest::newRow("insert 1 at 0, 0 buffer") << 0 << 1 << 0; + QTest::newRow("insert 1 at 0, 100 buffer") << 0 << 1 << 100; + QTest::newRow("insert 1 at 0, 500 buffer") << 0 << 1 << 500; + + QTest::newRow("insert 1 at 1, 0 buffer") << 1 << 1 << 0; + QTest::newRow("insert 1 at 1, 100 buffer") << 1 << 1 << 100; + QTest::newRow("insert 1 at 1, 500 buffer") << 1 << 1 << 500; + + QTest::newRow("insert multiple at 0, 0 buffer") << 0 << 6 << 0; + QTest::newRow("insert multiple at 0, 100 buffer") << 0 << 6 << 100; + QTest::newRow("insert multiple at 0, 500 buffer") << 0 << 6 << 500; + + QTest::newRow("insert multiple at 1, 0 buffer") << 1 << 6 << 0; + QTest::newRow("insert multiple at 1, 100 buffer") << 1 << 6 << 100; + QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 6 << 500; +} + +void tst_QQuickGridView::removed() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.removeItem(1); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + + // Checks that onRemove is called + QString removed = canvas->rootObject()->property("removed").toString(); + QTRY_COMPARE(removed, QString("Item1")); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + // Remove first item (which is the current item); + model.removeItem(0); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + // Remove items not visible + model.removeItem(25); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + // Remove items before visible + gridview->setContentY(120); + gridview->setCurrentIndex(10); + + // Setting currentIndex above shouldn't cause view to scroll + QTRY_COMPARE(gridview->contentY(), 120.0); + + model.removeItem(1); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + // Confirm items positioned correctly + for (int i = 6; i < 18; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + // Remove currentIndex + QQuickItem *oldCurrent = gridview->currentItem(); + model.removeItem(9); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + QTRY_COMPARE(gridview->currentIndex(), 9); + QTRY_VERIFY(gridview->currentItem() != oldCurrent); + + gridview->setContentY(0); + // let transitions settle. + QTest::qWait(300); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60); + } + + // remove item outside current view. + gridview->setCurrentIndex(32); + gridview->setContentY(240); + + model.removeItem(30); + QTRY_VERIFY(gridview->currentIndex() == 31); + + // remove current item beyond visible items. + gridview->setCurrentIndex(20); + gridview->setContentY(0); + model.removeItem(20); + + QTRY_COMPARE(gridview->currentIndex(), 20); + QTRY_VERIFY(gridview->currentItem() != 0); + + // remove item before current, but visible + gridview->setCurrentIndex(8); + gridview->setContentY(240); + oldCurrent = gridview->currentItem(); + model.removeItem(6); + + QTRY_COMPARE(gridview->currentIndex(), 7); + QTRY_VERIFY(gridview->currentItem() == oldCurrent); + + delete canvas; +} + +void tst_QQuickGridView::addOrRemoveBeforeVisible() +{ + // QTBUG-21588: ensure re-layout is done on grid after adding or removing + // items from before the visible area + + QFETCH(bool, doAdd); + QFETCH(qreal, newTopContentY); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "textName", 0); + QTRY_COMPARE(name->text(), QString("Item0")); + + gridview->setCurrentIndex(0); + qApp->processEvents(); + + // scroll down until item 0 is no longer drawn + // (bug not triggered if we just move using content y, since that doesn't + // refill and change the visible items) + gridview->setCurrentIndex(24); + qApp->processEvents(); + + QTRY_COMPARE(gridview->currentIndex(), 24); + QTRY_COMPARE(gridview->contentY(), 220.0); + + QTest::qWait(100); // wait for refill to complete + QTRY_VERIFY(!findItem(contentItem, "wrapper", 0)); // 0 shouldn't be visible + + if (doAdd) { + model.insertItem(0, "New Item", "New Item number"); + QTRY_COMPARE(gridview->count(), 31); + } else { + model.removeItem(0); + QTRY_COMPARE(gridview->count(), 29); + } + + // scroll back up and item 0 should be gone + gridview->setCurrentIndex(0); + qApp->processEvents(); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentY(), newTopContentY); + + name = findItem(contentItem, "textName", 0); + if (doAdd) + QCOMPARE(name->text(), QString("New Item")); + else + QCOMPARE(name->text(), QString("Item1")); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QTRY_VERIFY(findItem(contentItem, "wrapper", i)); + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_VERIFY(item->x() == (i%3)*80); + QTRY_VERIFY(item->y() == (i/3)*60 + newTopContentY); + } + + delete canvas; +} + +void tst_QQuickGridView::addOrRemoveBeforeVisible_data() +{ + QTest::addColumn("doAdd"); + QTest::addColumn("newTopContentY"); + + QTest::newRow("add") << true << -60.0; + QTest::newRow("remove") << false << 0.0; +} + +void tst_QQuickGridView::clear() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + model.clear(); + + QVERIFY(gridview->count() == 0); + QVERIFY(gridview->currentItem() == 0); + QVERIFY(gridview->contentY() == 0); + QVERIFY(gridview->currentIndex() == -1); + + // confirm sanity when adding an item to cleared list + model.addItem("New", "1"); + QTRY_COMPARE(gridview->count(), 1); + QVERIFY(gridview->currentItem() != 0); + QVERIFY(gridview->currentIndex() == 0); + + delete canvas; +} + +void tst_QQuickGridView::moved() +{ + QFETCH(qreal, contentY); + QFETCH(int, from); + QFETCH(int, to); + QFETCH(int, count); + QFETCH(qreal, itemsOffsetAfterMove); + + QQuickText *name; + QQuickText *number; + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickItem *currentItem = gridview->currentItem(); + QTRY_VERIFY(currentItem != 0); + + gridview->setContentY(contentY); + model.moveItems(from, to, count); + + // wait for items to move + QTest::qWait(300); + + // Confirm items positioned correctly and indexes correct + int firstVisibleIndex = qCeil(contentY / 60.0) * 3; + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + if (i >= firstVisibleIndex + 18) // index has moved out of view + continue; + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), (i/3)*60.0 + itemsOffsetAfterMove); + + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + + // current index should have been updated + if (item == currentItem) + QTRY_COMPARE(gridview->currentIndex(), i); + } + + delete canvas; +} + +void tst_QQuickGridView::moved_data() +{ + QTest::addColumn("contentY"); + QTest::addColumn("from"); + QTest::addColumn("to"); + QTest::addColumn("count"); + QTest::addColumn("itemsOffsetAfterMove"); + + // model starts with 30 items, each 80x60, in area 240x320 + // 18 items should be visible at a time + + QTest::newRow("move 1 forwards, within visible items") + << 0.0 + << 1 << 8 << 1 + << 0.0; + + QTest::newRow("move 1 forwards, from non-visible -> visible") + << 120.0 // show 6-23 + << 1 << 23 << 1 + << 0.0; // only 1 item was removed from the 1st row, so it doesn't move down + + QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") + << 120.0 // // show 6-23 + << 0 << 6 << 1 + << 0.0; // only 1 item was removed from the 1st row, so it doesn't move down + + QTest::newRow("move 1 forwards, from visible -> non-visible") + << 0.0 + << 1 << 20 << 1 + << 0.0; + + QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)") + << 0.0 + << 0 << 20 << 1 + << 0.0; + + + QTest::newRow("move 1 backwards, within visible items") + << 0.0 + << 10 << 5 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, within visible items (to first index)") + << 0.0 + << 10 << 0 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from non-visible -> visible") + << 0.0 + << 28 << 8 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)") + << 0.0 + << 29 << 14 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from visible -> non-visible") + << 120.0 // show 6-23 + << 7 << 1 << 1 + << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move + + QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)") + << 120.0 // show 6-23 + << 7 << 0 << 1 + << 0.0; // only 1 item moved back, so items shift accordingly and first row doesn't move + + + QTest::newRow("move multiple forwards, within visible items") + << 0.0 + << 0 << 5 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, within visible items (move first item)") + << 0.0 + << 10 << 0 << 3 + << 0.0; + + QTest::newRow("move multiple forwards, before visible items") + << 120.0 // show 6-23 + << 3 << 4 << 3 // 3, 4, 5 move to after 6 + << 60.0; // row of 3,4,5 has moved down + + QTest::newRow("move multiple forwards, from non-visible -> visible") + << 120.0 // show 6-23 + << 1 << 6 << 3 + << 60.0; // 1st row (it's above visible area) disappears, 0 drops down 1 row, first visible item (6) stays where it is + + QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)") + << 120.0 // show 6-23 + << 0 << 6 << 3 + << 60.0; // top row moved and shifted to below 3rd row, all items should shift down by 1 row + + QTest::newRow("move multiple forwards, from visible -> non-visible") + << 0.0 + << 1 << 16 << 3 + << 0.0; + + QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)") + << 0.0 + << 0 << 16 << 3 + << 0.0; + + + QTest::newRow("move multiple backwards, within visible items") + << 0.0 + << 4 << 1 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from non-visible -> visible") + << 0.0 + << 20 << 4 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)") + << 0.0 + << 27 << 10 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from visible -> non-visible") + << 120.0 // show 6-23 + << 16 << 1 << 3 + << -60.0; // to minimize movement, items are added above visible area, all items move up by 1 row + + QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)") + << 120.0 // show 6-23 + << 16 << 0 << 3 + << -60.0; // 16,17,18 move to above item 0, all items move up by 1 row +} + +struct ListChange { + enum { Inserted, Removed, Moved, SetCurrent } type; + int index; + int count; + int to; // Move + + static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; } + static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; } + static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; } + static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; } +}; +Q_DECLARE_METATYPE(QList) + +void tst_QQuickGridView::multipleChanges() +{ + QFETCH(int, startCount); + QFETCH(QList, changes); + QFETCH(int, newCount); + QFETCH(int, newCurrentIndex); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < startCount; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + for (int i=0; i > items; + for (int j=changes[i].index; jsetCurrentIndex(changes[i].index); + break; + } + } + + QTRY_COMPARE(gridview->count(), newCount); + QCOMPARE(gridview->count(), model.count()); + QTRY_COMPARE(gridview->currentIndex(), newCurrentIndex); + + QQuickText *name; + QQuickText *number; + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i=0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::multipleChanges_data() +{ + QTest::addColumn("startCount"); + QTest::addColumn >("changes"); + QTest::addColumn("newCount"); + QTest::addColumn("newCurrentIndex"); + + QList changes; + + for (int i=1; i<30; i++) + changes << ListChange::remove(0); + QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0; + + changes << ListChange::remove(0); + QTest::newRow("remove all") << 30 << changes << 0 << -1; + + changes.clear(); + changes << ListChange::setCurrent(29); + for (int i=29; i>0; i--) + changes << ListChange::remove(i); + QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0; + + QTest::newRow("remove then insert at 0") << 10 << (QList() + << ListChange::remove(0, 1) + << ListChange::insert(0, 1) + ) << 10 << 1; + + QTest::newRow("remove then insert at non-zero index") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::remove(2, 1) + << ListChange::insert(2, 1) + ) << 10 << 3; + + QTest::newRow("remove current then insert below it") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::remove(1, 3) + << ListChange::insert(2, 2) + ) << 9 << 1; + + QTest::newRow("remove current index then move it down") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::remove(1, 3) + << ListChange::move(1, 5, 1) + ) << 7 << 5; + + QTest::newRow("remove current index then move it up") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::remove(4, 3) + << ListChange::move(4, 1, 1) + ) << 7 << 1; + + + QTest::newRow("insert multiple times") << 0 << (QList() + << ListChange::insert(0, 2) + << ListChange::insert(0, 4) + << ListChange::insert(0, 6) + ) << 12 << 10; + + QTest::newRow("insert multiple times with current index changes") << 0 << (QList() + << ListChange::insert(0, 2) + << ListChange::insert(0, 4) + << ListChange::insert(0, 6) + << ListChange::setCurrent(3) + << ListChange::insert(3, 2) + ) << 14 << 5; + + QTest::newRow("insert and remove all") << 0 << (QList() + << ListChange::insert(0, 30) + << ListChange::remove(0, 30) + ) << 0 << -1; + + QTest::newRow("insert and remove current") << 30 << (QList() + << ListChange::insert(1) + << ListChange::setCurrent(1) + << ListChange::remove(1) + ) << 30 << 1; + + QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList() + << ListChange::insert(0, 10) + << ListChange::remove(5, 10) + ) << 10 << 5; + + QTest::newRow("insert multiple, then move new items to end") << 10 << (QList() + << ListChange::insert(0, 3) + << ListChange::move(0, 10, 3) + ) << 13 << 0; + + QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList() + << ListChange::insert(0, 3) + << ListChange::move(0, 8, 5) + ) << 13 << 11; + + QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList() + << ListChange::setCurrent(9) + << ListChange::insert(10, 3) + << ListChange::move(8, 0, 5) + ) << 13 << 1; + + + QTest::newRow("move back and forth to same index") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::move(1, 2, 2) + << ListChange::move(2, 1, 2) + ) << 10 << 1; + + QTest::newRow("move forwards then back") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::move(1, 2, 3) + << ListChange::move(3, 0, 5) + ) << 10 << 0; + + QTest::newRow("move current, then remove it") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 0, 1) + << ListChange::remove(0) + ) << 9 << 0; + + QTest::newRow("move current, then insert before it") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 0, 1) + << ListChange::insert(0) + ) << 11 << 1; + + QTest::newRow("move multiple, then remove them") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::move(5, 1, 3) + << ListChange::remove(1, 3) + ) << 7 << 1; + + QTest::newRow("move multiple, then insert before them") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 1, 3) + << ListChange::insert(1, 5) + ) << 15 << 6; + + QTest::newRow("move multiple, then insert after them") << 10 << (QList() + << ListChange::setCurrent(3) + << ListChange::move(0, 1, 2) + << ListChange::insert(3, 5) + ) << 15 << 8; + + + QTest::newRow("clear current") << 0 << (QList() + << ListChange::insert(0, 5) + << ListChange::setCurrent(-1) + << ListChange::remove(0, 5) + << ListChange::insert(0, 5) + ) << 5 << -1; +} + + +void tst_QQuickGridView::swapWithFirstItem() +{ + // QTBUG_9697 + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + // ensure content position is stable + gridview->setContentY(0); + model.moveItem(10, 0); + QTRY_VERIFY(gridview->contentY() == 0); + + delete canvas; +} + +void tst_QQuickGridView::currentIndex() +{ + TestModel model; + for (int i = 0; i < 60; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + canvas->show(); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + QString filename(TESTDATA("gridview-initCurrent.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + QTRY_VERIFY(!QQuickItemPrivate::get(gridview)->polishScheduled); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + // current item should be third item + QCOMPARE(gridview->currentIndex(), 35); + QCOMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 35)); + QCOMPARE(gridview->currentItem()->y(), gridview->highlightItem()->y()); + QCOMPARE(gridview->contentY(), 400.0); + + gridview->moveCurrentIndexRight(); + QCOMPARE(gridview->currentIndex(), 36); + gridview->moveCurrentIndexDown(); + QCOMPARE(gridview->currentIndex(), 39); + gridview->moveCurrentIndexUp(); + QCOMPARE(gridview->currentIndex(), 36); + gridview->moveCurrentIndexLeft(); + QCOMPARE(gridview->currentIndex(), 35); + + // wait until motion stops + QTRY_VERIFY(gridview->verticalVelocity() == 0.0); + + // no wrap + gridview->setCurrentIndex(0); + QCOMPARE(gridview->currentIndex(), 0); + // confirm that the velocity is updated + QTRY_VERIFY(gridview->verticalVelocity() != 0.0); + + gridview->moveCurrentIndexUp(); + QCOMPARE(gridview->currentIndex(), 0); + + gridview->moveCurrentIndexLeft(); + QCOMPARE(gridview->currentIndex(), 0); + + gridview->setCurrentIndex(model.count()-1); + QCOMPARE(gridview->currentIndex(), model.count()-1); + + gridview->moveCurrentIndexRight(); + QCOMPARE(gridview->currentIndex(), model.count()-1); + + gridview->moveCurrentIndexDown(); + QCOMPARE(gridview->currentIndex(), model.count()-1); + + // with wrap + gridview->setWrapEnabled(true); + + gridview->setCurrentIndex(0); + QCOMPARE(gridview->currentIndex(), 0); + + gridview->moveCurrentIndexLeft(); + QCOMPARE(gridview->currentIndex(), model.count()-1); + + qApp->processEvents(); + QTRY_COMPARE(gridview->contentY(), 880.0); + + gridview->moveCurrentIndexRight(); + QCOMPARE(gridview->currentIndex(), 0); + + QTRY_COMPARE(gridview->contentY(), 0.0); + + + // footer should become visible if it is out of view, and then current index moves to the first row + canvas->rootObject()->setProperty("showFooter", true); + QTRY_VERIFY(gridview->footerItem()); + gridview->setCurrentIndex(model.count()-3); + QTRY_VERIFY(gridview->footerItem()->y() > gridview->contentY() + gridview->height()); + gridview->setCurrentIndex(model.count()-2); + QTRY_COMPARE(gridview->contentY() + gridview->height(), (60.0 * model.count()/3) + gridview->footerItem()->height()); + canvas->rootObject()->setProperty("showFooter", false); + + // header should become visible if it is out of view, and then current index moves to the last row + canvas->rootObject()->setProperty("showHeader", true); + QTRY_VERIFY(gridview->headerItem()); + gridview->setCurrentIndex(3); + QTRY_VERIFY(gridview->headerItem()->y() + gridview->headerItem()->height() < gridview->contentY()); + gridview->setCurrentIndex(1); + QTRY_COMPARE(gridview->contentY(), -gridview->headerItem()->height()); + canvas->rootObject()->setProperty("showHeader", false); + + + // Test keys + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(qGuiApp->focusWindow() == canvas); + + gridview->setCurrentIndex(0); + + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(gridview->currentIndex(), 3); + + QTest::keyClick(canvas, Qt::Key_Up); + QCOMPARE(gridview->currentIndex(), 0); + + // hold down Key_Down + for (int i=0; i<(model.count() / 3) - 1; i++) { + QTest::simulateEvent(canvas, true, Qt::Key_Down, Qt::NoModifier, "", true); + QTRY_COMPARE(gridview->currentIndex(), i*3 + 3); + } + QTest::keyRelease(canvas, Qt::Key_Down); + QTRY_COMPARE(gridview->currentIndex(), 57); + QTRY_COMPARE(gridview->contentY(), 880.0); + + // hold down Key_Up + for (int i=(model.count() / 3) - 1; i > 0; i--) { + QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); + QTRY_COMPARE(gridview->currentIndex(), i*3 - 3); + } + QTest::keyRelease(canvas, Qt::Key_Up); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentY(), 0.0); + + + gridview->setFlow(QQuickGridView::TopToBottom); + + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(qGuiApp->focusWindow() == canvas); + qApp->processEvents(); + + QTest::keyClick(canvas, Qt::Key_Right); + QCOMPARE(gridview->currentIndex(), 5); + + QTest::keyClick(canvas, Qt::Key_Left); + QCOMPARE(gridview->currentIndex(), 0); + + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(gridview->currentIndex(), 1); + + QTest::keyClick(canvas, Qt::Key_Up); + QCOMPARE(gridview->currentIndex(), 0); + + // hold down Key_Right + for (int i=0; i<(model.count() / 5) - 1; i++) { + QTest::simulateEvent(canvas, true, Qt::Key_Right, Qt::NoModifier, "", true); + QTRY_COMPARE(gridview->currentIndex(), i*5 + 5); + } + + QTest::keyRelease(canvas, Qt::Key_Right); + QTRY_COMPARE(gridview->currentIndex(), 55); + QTRY_COMPARE(gridview->contentX(), 720.0); + + // hold down Key_Left + for (int i=(model.count() / 5) - 1; i > 0; i--) { + QTest::simulateEvent(canvas, true, Qt::Key_Left, Qt::NoModifier, "", true); + QTRY_COMPARE(gridview->currentIndex(), i*5 - 5); + } + QTest::keyRelease(canvas, Qt::Key_Left); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->contentX(), 0.0); + + + // turn off auto highlight + gridview->setHighlightFollowsCurrentItem(false); + QVERIFY(gridview->highlightFollowsCurrentItem() == false); + QVERIFY(gridview->highlightItem()); + qreal hlPosX = gridview->highlightItem()->x(); + qreal hlPosY = gridview->highlightItem()->y(); + + gridview->setCurrentIndex(5); + QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX); + QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); + + // insert item before currentIndex + gridview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); + + // check removing highlight by setting currentIndex to -1; + gridview->setCurrentIndex(-1); + + QCOMPARE(gridview->currentIndex(), -1); + QVERIFY(!gridview->highlightItem()); + QVERIFY(!gridview->currentItem()); + + gridview->setHighlightFollowsCurrentItem(true); + + gridview->setFlow(QQuickGridView::LeftToRight); + gridview->setLayoutDirection(Qt::RightToLeft); + + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(qGuiApp->focusWindow() == canvas); + qApp->processEvents(); + + gridview->setCurrentIndex(35); + + QTest::keyClick(canvas, Qt::Key_Right); + QCOMPARE(gridview->currentIndex(), 34); + + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(gridview->currentIndex(), 37); + + QTest::keyClick(canvas, Qt::Key_Up); + QCOMPARE(gridview->currentIndex(), 34); + + QTest::keyClick(canvas, Qt::Key_Left); + QCOMPARE(gridview->currentIndex(), 35); + + + // turn off auto highlight + gridview->setHighlightFollowsCurrentItem(false); + QVERIFY(gridview->highlightFollowsCurrentItem() == false); + QVERIFY(gridview->highlightItem()); + hlPosX = gridview->highlightItem()->x(); + hlPosY = gridview->highlightItem()->y(); + + gridview->setCurrentIndex(5); + QTRY_COMPARE(gridview->highlightItem()->x(), hlPosX); + QTRY_COMPARE(gridview->highlightItem()->y(), hlPosY); + + // insert item before currentIndex + gridview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); + + // check removing highlight by setting currentIndex to -1; + gridview->setCurrentIndex(-1); + + QCOMPARE(gridview->currentIndex(), -1); + QVERIFY(!gridview->highlightItem()); + QVERIFY(!gridview->currentItem()); + + delete canvas; +} + +void tst_QQuickGridView::noCurrentIndex() +{ + TestModel model; + for (int i = 0; i < 60; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + QString filename(TESTDATA("gridview-noCurrent.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + // current index should be -1 + QCOMPARE(gridview->currentIndex(), -1); + QVERIFY(!gridview->currentItem()); + QVERIFY(!gridview->highlightItem()); + QCOMPARE(gridview->contentY(), 0.0); + + gridview->setCurrentIndex(5); + QCOMPARE(gridview->currentIndex(), 5); + QVERIFY(gridview->currentItem()); + QVERIFY(gridview->highlightItem()); + + delete canvas; +} + +void tst_QQuickGridView::changeFlow() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal((i%3)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + ctxt->setContextProperty("testTopToBottom", QVariant(true)); + + // Confirm items positioned correctly and indexes correct + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal((i/5)*80)); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + ctxt->setContextProperty("testRightToLeft", QVariant(true)); + + // Confirm items positioned correctly and indexes correct + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80 - item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + gridview->setContentX(100); + QTRY_COMPARE(gridview->contentX(), 100.); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + QTRY_COMPARE(gridview->contentX(), 0.); + + // Confirm items positioned correctly and indexes correct + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(240 - (i%3+1)*80)); + QTRY_COMPARE(item->y(), qreal((i/3)*60)); + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::defaultValues() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview3.qml"))); + QQuickGridView *obj = qobject_cast(c.create()); + + QTRY_VERIFY(obj != 0); + QTRY_VERIFY(obj->model() == QVariant()); + QTRY_VERIFY(obj->delegate() == 0); + QTRY_COMPARE(obj->currentIndex(), -1); + QTRY_VERIFY(obj->currentItem() == 0); + QTRY_COMPARE(obj->count(), 0); + QTRY_VERIFY(obj->highlight() == 0); + QTRY_VERIFY(obj->highlightItem() == 0); + QTRY_COMPARE(obj->highlightFollowsCurrentItem(), true); + QTRY_VERIFY(obj->flow() == 0); + QTRY_COMPARE(obj->isWrapEnabled(), false); + QTRY_COMPARE(obj->cacheBuffer(), 0); + QTRY_COMPARE(obj->cellWidth(), qreal(100)); //### Should 100 be the default? + QTRY_COMPARE(obj->cellHeight(), qreal(100)); + delete obj; +} + +void tst_QQuickGridView::properties() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("gridview2.qml"))); + QQuickGridView *obj = qobject_cast(c.create()); + + QTRY_VERIFY(obj != 0); + QTRY_VERIFY(obj->model() != QVariant()); + QTRY_VERIFY(obj->delegate() != 0); + QTRY_COMPARE(obj->currentIndex(), 0); + QTRY_VERIFY(obj->currentItem() != 0); + QTRY_COMPARE(obj->count(), 4); + QTRY_VERIFY(obj->highlight() != 0); + QTRY_VERIFY(obj->highlightItem() != 0); + QTRY_COMPARE(obj->highlightFollowsCurrentItem(), false); + QTRY_VERIFY(obj->flow() == 0); + QTRY_COMPARE(obj->isWrapEnabled(), true); + QTRY_COMPARE(obj->cacheBuffer(), 200); + QTRY_COMPARE(obj->cellWidth(), qreal(100)); + QTRY_COMPARE(obj->cellHeight(), qreal(100)); + delete obj; +} + +void tst_QQuickGridView::propertyChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); + QTRY_VERIFY(gridView); + + QSignalSpy keyNavigationWrapsSpy(gridView, SIGNAL(keyNavigationWrapsChanged())); + QSignalSpy cacheBufferSpy(gridView, SIGNAL(cacheBufferChanged())); + QSignalSpy layoutSpy(gridView, SIGNAL(layoutDirectionChanged())); + QSignalSpy flowSpy(gridView, SIGNAL(flowChanged())); + + QTRY_COMPARE(gridView->isWrapEnabled(), true); + QTRY_COMPARE(gridView->cacheBuffer(), 10); + QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); + + gridView->setWrapEnabled(false); + gridView->setCacheBuffer(3); + gridView->setFlow(QQuickGridView::TopToBottom); + + QTRY_COMPARE(gridView->isWrapEnabled(), false); + QTRY_COMPARE(gridView->cacheBuffer(), 3); + QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); + + QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); + QTRY_COMPARE(cacheBufferSpy.count(),1); + QTRY_COMPARE(flowSpy.count(),1); + + gridView->setWrapEnabled(false); + gridView->setCacheBuffer(3); + gridView->setFlow(QQuickGridView::TopToBottom); + + QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); + QTRY_COMPARE(cacheBufferSpy.count(),1); + QTRY_COMPARE(flowSpy.count(),1); + + gridView->setFlow(QQuickGridView::LeftToRight); + QTRY_COMPARE(gridView->flow(), QQuickGridView::LeftToRight); + + gridView->setWrapEnabled(true); + gridView->setCacheBuffer(5); + gridView->setLayoutDirection(Qt::RightToLeft); + + QTRY_COMPARE(gridView->isWrapEnabled(), true); + QTRY_COMPARE(gridView->cacheBuffer(), 5); + QTRY_COMPARE(gridView->layoutDirection(), Qt::RightToLeft); + + QTRY_COMPARE(keyNavigationWrapsSpy.count(),2); + QTRY_COMPARE(cacheBufferSpy.count(),2); + QTRY_COMPARE(layoutSpy.count(),1); + QTRY_COMPARE(flowSpy.count(),2); + + gridView->setWrapEnabled(true); + gridView->setCacheBuffer(5); + gridView->setLayoutDirection(Qt::RightToLeft); + + QTRY_COMPARE(keyNavigationWrapsSpy.count(),2); + QTRY_COMPARE(cacheBufferSpy.count(),2); + QTRY_COMPARE(layoutSpy.count(),1); + QTRY_COMPARE(flowSpy.count(),2); + + gridView->setFlow(QQuickGridView::TopToBottom); + QTRY_COMPARE(gridView->flow(), QQuickGridView::TopToBottom); + QTRY_COMPARE(flowSpy.count(),3); + + gridView->setFlow(QQuickGridView::TopToBottom); + QTRY_COMPARE(flowSpy.count(),3); + + delete canvas; +} + +void tst_QQuickGridView::componentChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); + QTRY_VERIFY(gridView); + + QDeclarativeComponent component(canvas->engine()); + component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); + + QDeclarativeComponent delegateComponent(canvas->engine()); + delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); + + QSignalSpy highlightSpy(gridView, SIGNAL(highlightChanged())); + QSignalSpy delegateSpy(gridView, SIGNAL(delegateChanged())); + QSignalSpy headerSpy(gridView, SIGNAL(headerChanged())); + QSignalSpy footerSpy(gridView, SIGNAL(footerChanged())); + + gridView->setHighlight(&component); + gridView->setDelegate(&delegateComponent); + gridView->setHeader(&component); + gridView->setFooter(&component); + + QTRY_COMPARE(gridView->highlight(), &component); + QTRY_COMPARE(gridView->delegate(), &delegateComponent); + QTRY_COMPARE(gridView->header(), &component); + QTRY_COMPARE(gridView->footer(), &component); + + QTRY_COMPARE(highlightSpy.count(),1); + QTRY_COMPARE(delegateSpy.count(),1); + QTRY_COMPARE(headerSpy.count(),1); + QTRY_COMPARE(footerSpy.count(),1); + + gridView->setHighlight(&component); + gridView->setDelegate(&delegateComponent); + gridView->setHeader(&component); + gridView->setFooter(&component); + + QTRY_COMPARE(highlightSpy.count(),1); + QTRY_COMPARE(delegateSpy.count(),1); + QTRY_COMPARE(headerSpy.count(),1); + QTRY_COMPARE(footerSpy.count(),1); + + delete canvas; +} + +void tst_QQuickGridView::modelChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickGridView *gridView = canvas->rootObject()->findChild("gridView"); + QTRY_VERIFY(gridView); + + QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); + QTRY_VERIFY(alternateModel); + QVariant modelVariant = QVariant::fromValue(alternateModel); + QSignalSpy modelSpy(gridView, SIGNAL(modelChanged())); + + gridView->setModel(modelVariant); + QTRY_COMPARE(gridView->model(), modelVariant); + QTRY_COMPARE(modelSpy.count(),1); + + gridView->setModel(modelVariant); + QTRY_COMPARE(modelSpy.count(),1); + + gridView->setModel(QVariant()); + QTRY_COMPARE(modelSpy.count(),2); + delete canvas; +} + +void tst_QQuickGridView::positionViewAtIndex() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.); + QTRY_COMPARE(item->y(), (i/3)*60.); + } + + // Position on a currently visible item + gridview->positionViewAtIndex(4, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(120, 90), 4); + QTRY_COMPARE(gridview->contentY(), 60.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.); + QTRY_COMPARE(item->y(), (i/3)*60.); + } + + // Position on an item beyond the visible items + gridview->positionViewAtIndex(21, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(40, 450), 21); + QTRY_COMPARE(gridview->contentY(), 420.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.); + QTRY_COMPARE(item->y(), (i/3)*60.); + } + + // Position on an item that would leave empty space if positioned at the top + gridview->positionViewAtIndex(31, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(120, 630), 31); + QTRY_COMPARE(gridview->contentY(), 520.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.); + QTRY_COMPARE(item->y(), (i/3)*60.); + } + + // Position at the beginning again + gridview->positionViewAtIndex(0, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->indexAt(0, 0), 0); + QTRY_COMPARE(gridview->indexAt(40, 30), 0); + QTRY_COMPARE(gridview->indexAt(80, 60), 4); + QTRY_COMPARE(gridview->contentY(), 0.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.); + QTRY_COMPARE(item->y(), (i/3)*60.); + } + + // Position at End + gridview->positionViewAtIndex(30, QQuickGridView::End); + QTRY_COMPARE(gridview->contentY(), 340.); + + // Position in Center + gridview->positionViewAtIndex(15, QQuickGridView::Center); + QTRY_COMPARE(gridview->contentY(), 170.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentY(), 170.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentY(), 302.); + + gridview->setContentY(360); + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentY(), 60.); + + gridview->setContentY(20); + gridview->positionViewAtIndex(20, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentY(), 100.); + + // Ensure completely visible + gridview->setContentY(120); + gridview->positionViewAtIndex(20, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentY(), 120.); + + gridview->setContentY(302); + gridview->positionViewAtIndex(15, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentY(), 300.); + + gridview->setContentY(60); + gridview->positionViewAtIndex(20, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentY(), 100.); + + // Test for Top To Bottom layout + ctxt->setContextProperty("testTopToBottom", QVariant(true)); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), (i/5)*80.); + QTRY_COMPARE(item->y(), (i%5)*60.); + } + + // Position at End + gridview->positionViewAtIndex(30, QQuickGridView::End); + QTRY_COMPARE(gridview->contentX(), 320.); + QTRY_COMPARE(gridview->contentY(), 0.); + + // Position in Center + gridview->positionViewAtIndex(15, QQuickGridView::Center); + QTRY_COMPARE(gridview->contentX(), 160.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 160.); + + gridview->setContentX(170); + gridview->positionViewAtIndex(25, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 170.); + + gridview->positionViewAtIndex(30, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), 320.); + + gridview->setContentX(170); + gridview->positionViewAtIndex(25, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentX(), 240.); + + // positionViewAtBeginning + gridview->positionViewAtBeginning(); + QTRY_COMPARE(gridview->contentX(), 0.); + + gridview->setContentX(80); + canvas->rootObject()->setProperty("showHeader", true); + gridview->positionViewAtBeginning(); + QTRY_COMPARE(gridview->contentX(), -30.); + + // positionViewAtEnd + gridview->positionViewAtEnd(); + QTRY_COMPARE(gridview->contentX(), 400.); // 8*80 - 240 (8 columns) + + gridview->setContentX(80); + canvas->rootObject()->setProperty("showFooter", true); + gridview->positionViewAtEnd(); + QTRY_COMPARE(gridview->contentX(), 430.); + + // set current item to outside visible view, position at beginning + // and ensure highlight moves to current item + gridview->setCurrentIndex(6); + gridview->positionViewAtBeginning(); + QTRY_COMPARE(gridview->contentX(), -30.); + QVERIFY(gridview->highlightItem()); + QCOMPARE(gridview->highlightItem()->x(), 80.); + + delete canvas; +} + +void tst_QQuickGridView::snapping() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + gridview->setHeight(220); + QCOMPARE(gridview->height(), 220.); + + gridview->positionViewAtIndex(12, QQuickGridView::Visible); + QCOMPARE(gridview->contentY(), 80.); + + gridview->setContentY(0); + QCOMPARE(gridview->contentY(), 0.); + + gridview->setSnapMode(QQuickGridView::SnapToRow); + QCOMPARE(gridview->snapMode(), QQuickGridView::SnapToRow); + + gridview->positionViewAtIndex(12, QQuickGridView::Visible); + QCOMPARE(gridview->contentY(), 60.); + + gridview->positionViewAtIndex(15, QQuickGridView::End); + QCOMPARE(gridview->contentY(), 120.); + + delete canvas; + +} + +void tst_QQuickGridView::mirroring() +{ + QQuickView *canvasA = createView(); + canvasA->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml"))); + QQuickGridView *gridviewA = findItem(canvasA->rootObject(), "view"); + QTRY_VERIFY(gridviewA != 0); + + QQuickView *canvasB = createView(); + canvasB->setSource(QUrl::fromLocalFile(TESTDATA("mirroring.qml"))); + QQuickGridView *gridviewB = findItem(canvasB->rootObject(), "view"); + QTRY_VERIFY(gridviewA != 0); + qApp->processEvents(); + + QList objectNames; + objectNames << "item1" << "item2"; // << "item3" + + gridviewA->setProperty("layoutDirection", Qt::LeftToRight); + gridviewB->setProperty("layoutDirection", Qt::RightToLeft); + QCOMPARE(gridviewA->layoutDirection(), gridviewA->effectiveLayoutDirection()); + + // LTR != RTL + foreach (const QString objectName, objectNames) + QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); + + gridviewA->setProperty("layoutDirection", Qt::LeftToRight); + gridviewB->setProperty("layoutDirection", Qt::LeftToRight); + + // LTR == LTR + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); + + QVERIFY(gridviewB->layoutDirection() == gridviewB->effectiveLayoutDirection()); + QQuickItemPrivate::get(gridviewB)->setLayoutMirror(true); + QVERIFY(gridviewB->layoutDirection() != gridviewB->effectiveLayoutDirection()); + + // LTR != LTR+mirror + foreach (const QString objectName, objectNames) + QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); + + gridviewA->setProperty("layoutDirection", Qt::RightToLeft); + + // RTL == LTR+mirror + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); + + gridviewB->setProperty("layoutDirection", Qt::RightToLeft); + + // RTL != RTL+mirror + foreach (const QString objectName, objectNames) + QVERIFY(findItem(gridviewA, objectName)->x() != findItem(gridviewB, objectName)->x()); + + gridviewA->setProperty("layoutDirection", Qt::LeftToRight); + + // LTR == RTL+mirror + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(gridviewA, objectName)->x(), findItem(gridviewB, objectName)->x()); + + delete canvasA; + delete canvasB; +} + +void tst_QQuickGridView::positionViewAtIndex_rightToLeft() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testTopToBottom", QVariant(true)); + ctxt->setContextProperty("testRightToLeft", QVariant(true)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + } + + // Position on a currently visible item + gridview->positionViewAtIndex(6, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->contentX(), -320.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + } + + // Position on an item beyond the visible items + gridview->positionViewAtIndex(21, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->contentX(), -560.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + } + + // Position on an item that would leave empty space if positioned at the top + gridview->positionViewAtIndex(31, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->contentX(), -640.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + } + + // Position at the beginning again + gridview->positionViewAtIndex(0, QQuickGridView::Beginning); + QTRY_COMPARE(gridview->contentX(), -240.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), qreal(-(i/5)*80-item->width())); + QTRY_COMPARE(item->y(), qreal((i%5)*60)); + } + + // Position at End + gridview->positionViewAtIndex(30, QQuickGridView::End); + QTRY_COMPARE(gridview->contentX(), -560.); + + // Position in Center + gridview->positionViewAtIndex(15, QQuickGridView::Center); + QTRY_COMPARE(gridview->contentX(), -400.); + + // Ensure at least partially visible + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), -400.); + + gridview->setContentX(-555.); + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), -555.); + + gridview->setContentX(-239); + gridview->positionViewAtIndex(15, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), -320.); + + gridview->setContentX(-239); + gridview->positionViewAtIndex(20, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), -400.); + + gridview->setContentX(-640); + gridview->positionViewAtIndex(20, QQuickGridView::Visible); + QTRY_COMPARE(gridview->contentX(), -560.); + + // Ensure completely visible + gridview->setContentX(-400); + gridview->positionViewAtIndex(20, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentX(), -400.); + + gridview->setContentX(-315); + gridview->positionViewAtIndex(15, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentX(), -320.); + + gridview->setContentX(-640); + gridview->positionViewAtIndex(20, QQuickGridView::Contain); + QTRY_COMPARE(gridview->contentX(), -560.); + + delete canvas; +} + +void tst_QQuickGridView::resetModel() +{ + QQuickView *canvas = createView(); + + QStringList strings; + strings << "one" << "two" << "three"; + QStringListModel model(strings); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaygrid.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(gridview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(contentItem, "displayText", i); + QTRY_VERIFY(display != 0); + QTRY_COMPARE(display->text(), strings.at(i)); + } + + strings.clear(); + strings << "four" << "five" << "six" << "seven"; + model.setStringList(strings); + + QTRY_COMPARE(gridview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(contentItem, "displayText", i); + QTRY_VERIFY(display != 0); + QTRY_COMPARE(display->text(), strings.at(i)); + } + + delete canvas; +} + +void tst_QQuickGridView::enforceRange() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml"))); + qApp->processEvents(); + QVERIFY(canvas->rootObject() != 0); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QTRY_COMPARE(gridview->preferredHighlightBegin(), 100.0); + QTRY_COMPARE(gridview->preferredHighlightEnd(), 100.0); + QTRY_COMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // view should be positioned at the top of the range. + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QTRY_VERIFY(item); + QTRY_COMPARE(gridview->contentY(), -100.0); + + QQuickText *name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + QQuickText *number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + // Check currentIndex is updated when contentItem moves + gridview->setContentY(0); + QTRY_COMPARE(gridview->currentIndex(), 2); + + gridview->setCurrentIndex(5); + QTRY_COMPARE(gridview->contentY(), 100.); + + TestModel model2; + for (int i = 0; i < 5; i++) + model2.addItem("Item" + QString::number(i), ""); + + ctxt->setContextProperty("testModel", &model2); + QCOMPARE(gridview->count(), 5); + + delete canvas; +} + +void tst_QQuickGridView::enforceRange_rightToLeft() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(true)); + ctxt->setContextProperty("testTopToBottom", QVariant(true)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview-enforcerange.qml"))); + qApp->processEvents(); + QVERIFY(canvas->rootObject() != 0); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QCOMPARE(gridview->preferredHighlightBegin(), 100.0); + QCOMPARE(gridview->preferredHighlightEnd(), 100.0); + QCOMPARE(gridview->highlightRangeMode(), QQuickGridView::StrictlyEnforceRange); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + // view should be positioned at the top of the range. + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QTRY_COMPARE(gridview->contentX(), -140.); + QTRY_COMPARE(gridview->contentY(), 0.0); + + QQuickText *name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + QQuickText *number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + // Check currentIndex is updated when contentItem moves + gridview->setContentX(-240); + QTRY_COMPARE(gridview->currentIndex(), 3); + + gridview->setCurrentIndex(7); + QTRY_COMPARE(gridview->contentX(), -340.); + QTRY_COMPARE(gridview->contentY(), 0.0); + + TestModel model2; + for (int i = 0; i < 5; i++) + model2.addItem("Item" + QString::number(i), ""); + + ctxt->setContextProperty("testModel", &model2); + QCOMPARE(gridview->count(), 5); + + delete canvas; +} + +void tst_QQuickGridView::QTBUG_8456() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("setindex.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QTRY_COMPARE(gridview->currentIndex(), 0); + + delete canvas; +} + +void tst_QQuickGridView::manualHighlight() +{ + QQuickView *canvas = createView(); + + QString filename(TESTDATA("manual-highlight.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 0)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + gridview->setCurrentIndex(2); + + QTRY_COMPARE(gridview->currentIndex(), 2); + QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + gridview->positionViewAtIndex(8, QQuickGridView::Contain); + + QTRY_COMPARE(gridview->currentIndex(), 2); + QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + gridview->setFlow(QQuickGridView::TopToBottom); + QTRY_COMPARE(gridview->flow(), QQuickGridView::TopToBottom); + + gridview->setCurrentIndex(0); + QTRY_COMPARE(gridview->currentIndex(), 0); + QTRY_COMPARE(gridview->currentItem(), findItem(contentItem, "wrapper", 0)); + QTRY_COMPARE(gridview->highlightItem()->y() - 5, gridview->currentItem()->y()); + QTRY_COMPARE(gridview->highlightItem()->x() - 5, gridview->currentItem()->x()); + + delete canvas; +} + + +void tst_QQuickGridView::footer() +{ + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QPointF, initialFooterPos); + QFETCH(QPointF, changedFooterPos); + QFETCH(QPointF, initialContentPos); + QFETCH(QPointF, changedContentPos); + QFETCH(QPointF, firstDelegatePos); + QFETCH(QPointF, resizeContentPos); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 7; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + + QVERIFY(footer == gridview->footerItem()); + + QCOMPARE(footer->pos(), initialFooterPos); + QCOMPARE(footer->width(), 100.); + QCOMPARE(footer->height(), 30.); + QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); + + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + if (flow == QQuickGridView::LeftToRight) { + // shrink by one row + model.removeItem(2); + QTRY_COMPARE(footer->y(), initialFooterPos.y() - gridview->cellHeight()); + } else { + // shrink by one column + model.removeItem(2); + model.removeItem(3); + if (layoutDirection == Qt::LeftToRight) + QTRY_COMPARE(footer->x(), initialFooterPos.x() - gridview->cellWidth()); + else + QTRY_COMPARE(footer->x(), initialFooterPos.x() + gridview->cellWidth()); + } + + // remove all items + model.clear(); + + QPointF posWhenNoItems(0, 0); + if (layoutDirection == Qt::RightToLeft) + posWhenNoItems.setX(flow == QQuickGridView::LeftToRight ? gridview->width() - footer->width() : -footer->width()); + QTRY_COMPARE(footer->pos(), posWhenNoItems); + + // if header is present, it's at a negative pos, so the footer should not move + canvas->rootObject()->setProperty("showHeader", true); + QVERIFY(findItem(contentItem, "header") != 0); + QTRY_COMPARE(footer->pos(), posWhenNoItems); + canvas->rootObject()->setProperty("showHeader", false); + + // add 30 items + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QSignalSpy footerItemSpy(gridview, SIGNAL(footerItemChanged())); + QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); + + QCOMPARE(footerItemSpy.count(), 1); + + footer = findItem(contentItem, "footer"); + QVERIFY(!footer); + footer = findItem(contentItem, "footer2"); + QVERIFY(footer); + + QVERIFY(footer == gridview->footerItem()); + + QCOMPARE(footer->pos(), changedFooterPos); + QCOMPARE(footer->width(), 50.); + QCOMPARE(footer->height(), 20.); + QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos); + + item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + gridview->positionViewAtEnd(); + footer->setHeight(10); + footer->setWidth(40); + QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos); + + delete canvas; +} + +void tst_QQuickGridView::footer_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("initialFooterPos"); + QTest::addColumn("changedFooterPos"); + QTest::addColumn("initialContentPos"); + QTest::addColumn("changedContentPos"); + QTest::addColumn("firstDelegatePos"); + QTest::addColumn("resizeContentPos"); + + // footer1 = 100 x 30 + // footer2 = 50 x 20 + // cells = 80 * 60 + // view width = 240 + // view height = 320 + + // footer below items, bottom left + QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight + << QPointF(0, 3 * 60) // 180 = height of 3 rows (cell height is 60) + << QPointF(0, 10 * 60) // 30 items = 10 rows + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 10 * 60 - 320 + 10); + + // footer below items, bottom right + QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft + << QPointF(240 - 100, 3 * 60) + << QPointF((240 - 100) + 50, 10 * 60) // 50 = width diff between old and new footers + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(240 - 80, 0) + << QPointF(0, 10 * 60 - 320 + 10); + + // footer to right of items + QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight + << QPointF(2 * 80, 0) // 2 columns, cell width 80 + << QPointF(6 * 80, 0) // 30 items = 6 columns + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(6 * 80 - 240 + 40, 0); + + // footer to left of items + QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft + << QPointF(-(2 * 80) - 100, 0) + << QPointF(-(6 * 80) - 50, 0) // 50 = new footer width + << QPointF(-240, 0) + << QPointF(-240, 0) // unchanged, footer change doesn't change content pos + << QPointF(-80, 0) + << QPointF(-(6 * 80) - 40, 0); +} + +void tst_QQuickGridView::header() +{ + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QPointF, initialHeaderPos); + QFETCH(QPointF, changedHeaderPos); + QFETCH(QPointF, initialContentPos); + QFETCH(QPointF, changedContentPos); + QFETCH(QPointF, firstDelegatePos); + QFETCH(QPointF, resizeContentPos); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QQuickView *canvas = createView(); + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->rootContext()->setContextProperty("initialViewWidth", 240); + canvas->rootContext()->setContextProperty("initialViewHeight", 320); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *header = findItem(contentItem, "header"); + QVERIFY(header); + + QVERIFY(header == gridview->headerItem()); + + QCOMPARE(header->pos(), initialHeaderPos); + QCOMPARE(header->width(), 100.); + QCOMPARE(header->height(), 30.); + QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); + + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + model.clear(); + QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is + + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QSignalSpy headerItemSpy(gridview, SIGNAL(headerItemChanged())); + QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); + + QCOMPARE(headerItemSpy.count(), 1); + + header = findItem(contentItem, "header"); + QVERIFY(!header); + header = findItem(contentItem, "header2"); + QVERIFY(header); + + QVERIFY(header == gridview->headerItem()); + + QCOMPARE(header->pos(), changedHeaderPos); + QCOMPARE(header->width(), 50.); + QCOMPARE(header->height(), 20.); + QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), changedContentPos); + + item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + header->setHeight(10); + header->setWidth(40); + QTRY_COMPARE(QPointF(gridview->contentX(), gridview->contentY()), resizeContentPos); + + delete canvas; + + + // QTBUG-21207 header should become visible if view resizes from initial empty size + + canvas = createView(); + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->rootContext()->setContextProperty("initialViewWidth", 240); + canvas->rootContext()->setContextProperty("initialViewHeight", 320); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); + + gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + + gridview->setWidth(240); + gridview->setHeight(320); + QTRY_COMPARE(gridview->headerItem()->pos(), initialHeaderPos); + QCOMPARE(QPointF(gridview->contentX(), gridview->contentY()), initialContentPos); + + delete canvas; +} + +void tst_QQuickGridView::header_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("initialHeaderPos"); + QTest::addColumn("changedHeaderPos"); + QTest::addColumn("initialContentPos"); + QTest::addColumn("changedContentPos"); + QTest::addColumn("firstDelegatePos"); + QTest::addColumn("resizeContentPos"); + + // header1 = 100 x 30 + // header2 = 50 x 20 + // cells = 80 x 60 + // view width = 240 + + // header above items, top left + QTest::newRow("flow left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, 0) + << QPointF(0, -10); + + // header above items, top right + QTest::newRow("flow left to right, layout right to left") << QQuickGridView::LeftToRight << Qt::RightToLeft + << QPointF(240 - 100, -30) + << QPointF((240 - 100) + 50, -20) // 50 = width diff between old and new headers + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(160, 0) + << QPointF(0, -10); + + // header to left of items + QTest::newRow("flow top to bottom, layout left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight + << QPointF(-100, 0) + << QPointF(-50, 0) + << QPointF(-100, 0) + << QPointF(-50, 0) + << QPointF(0, 0) + << QPointF(-40, 0); + + // header to right of items + QTest::newRow("flow top to bottom, layout right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(-(240 - 100), 0) + << QPointF(-(240 - 50), 0) + << QPointF(-80, 0) + << QPointF(-(240 - 40), 0); +} + +void tst_QQuickGridView::resizeViewAndRepaint() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("initialHeight", 100); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // item at index 10 should not be currently visible + QVERIFY(!findItem(contentItem, "wrapper", 10)); + + gridview->setHeight(320); + QTRY_VERIFY(findItem(contentItem, "wrapper", 10)); + + gridview->setHeight(100); + QTRY_VERIFY(!findItem(contentItem, "wrapper", 10)); + + delete canvas; +} + +void tst_QQuickGridView::indexAt() +{ + QQuickView *canvas = createView(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Billy", "22345"); + model.addItem("Sam", "2945"); + model.addItem("Ben", "04321"); + model.addItem("Jim", "0780"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(gridview->count(), model.count()); + + QCOMPARE(gridview->indexAt(0, 0), 0); + QCOMPARE(gridview->indexAt(79, 59), 0); + QCOMPARE(gridview->indexAt(80, 0), 1); + QCOMPARE(gridview->indexAt(0, 60), 3); + QCOMPARE(gridview->indexAt(240, 0), -1); + + delete canvas; +} + +void tst_QQuickGridView::onAdd() +{ + QFETCH(int, initialItemCount); + QFETCH(int, itemsToAdd); + + const int delegateWidth = 50; + const int delegateHeight = 100; + TestModel model; + QQuickView *canvas = createView(); + canvas->setGeometry(0,0,5 * delegateWidth, 5 * delegateHeight); // just ensure all items fit + + // these initial items should not trigger GridView.onAdd + for (int i=0; irootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("delegateWidth", delegateWidth); + ctxt->setContextProperty("delegateHeight", delegateHeight); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); + + QObject *object = canvas->rootObject(); + object->setProperty("width", canvas->width()); + object->setProperty("height", canvas->height()); + qApp->processEvents(); + + QList > items; + for (int i=0; i(canvas->rootObject())->count()); + qApp->processEvents(); + + QVariantList result = object->property("addedDelegates").toList(); + QTRY_COMPARE(result.count(), items.count()); + for (int i=0; i("initialItemCount"); + QTest::addColumn("itemsToAdd"); + + QTest::newRow("0, add 1") << 0 << 1; + QTest::newRow("0, add 2") << 0 << 2; + QTest::newRow("0, add 10") << 0 << 10; + + QTest::newRow("1, add 1") << 1 << 1; + QTest::newRow("1, add 2") << 1 << 2; + QTest::newRow("1, add 10") << 1 << 10; + + QTest::newRow("5, add 1") << 5 << 1; + QTest::newRow("5, add 2") << 5 << 2; + QTest::newRow("5, add 10") << 5 << 10; +} + +void tst_QQuickGridView::onRemove() +{ + QFETCH(int, initialItemCount); + QFETCH(int, indexToRemove); + QFETCH(int, removeCount); + + const int delegateWidth = 50; + const int delegateHeight = 100; + TestModel model; + for (int i=0; irootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("delegateWidth", delegateWidth); + ctxt->setContextProperty("delegateHeight", delegateHeight); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); + QObject *object = canvas->rootObject(); + + model.removeItems(indexToRemove, removeCount); + QTRY_COMPARE(model.count(), qobject_cast(canvas->rootObject())->count()); + QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + + delete canvas; +} + +void tst_QQuickGridView::onRemove_data() +{ + QTest::addColumn("initialItemCount"); + QTest::addColumn("indexToRemove"); + QTest::addColumn("removeCount"); + + QTest::newRow("remove first") << 1 << 0 << 1; + QTest::newRow("two items, remove first") << 2 << 0 << 1; + QTest::newRow("two items, remove last") << 2 << 1 << 1; + QTest::newRow("two items, remove all") << 2 << 0 << 2; + + QTest::newRow("four items, remove first") << 4 << 0 << 1; + QTest::newRow("four items, remove 0-2") << 4 << 0 << 2; + QTest::newRow("four items, remove 1-3") << 4 << 1 << 2; + QTest::newRow("four items, remove 2-4") << 4 << 2 << 2; + QTest::newRow("four items, remove last") << 4 << 3 << 1; + QTest::newRow("four items, remove all") << 4 << 0 << 4; + + QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8; + QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5; + QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6; +} + +void tst_QQuickGridView::columnCount() +{ + QQuickView canvas; + canvas.setSource(QUrl::fromLocalFile(TESTDATA("gridview4.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + QQuickGridView *view = qobject_cast(canvas.rootObject()); + + QCOMPARE(view->cellWidth(), qreal(405)/qreal(9)); + QCOMPARE(view->cellHeight(), qreal(100)); + + QList items = findItems(view, "delegate"); + QCOMPARE(items.size(), 18); + QCOMPARE(items.at(8)->y(), qreal(0)); + QCOMPARE(items.at(9)->y(), qreal(100)); +} + +void tst_QQuickGridView::margins() +{ + { + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QCOMPARE(gridview->contentX(), -30.); + QCOMPARE(gridview->xOrigin(), 0.); + + // check end bound + gridview->positionViewAtEnd(); + qreal pos = gridview->contentX(); + gridview->setContentX(pos + 80); + gridview->returnToBounds(); + QTRY_COMPARE(gridview->contentX(), pos + 50); + + // remove item before visible and check that left margin is maintained + // and xOrigin is updated + gridview->setContentX(200); + model.removeItems(0, 4); + QTest::qWait(100); + gridview->setContentX(-50); + gridview->returnToBounds(); + QCOMPARE(gridview->xOrigin(), 100.); + QTRY_COMPARE(gridview->contentX(), 70.); + + // reduce left margin + gridview->setLeftMargin(20); + QCOMPARE(gridview->xOrigin(), 100.); + QTRY_COMPARE(gridview->contentX(), 80.); + + // check end bound + gridview->positionViewAtEnd(); + QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin + pos = gridview->contentX(); + gridview->setContentX(pos + 80); + gridview->returnToBounds(); + QTRY_COMPARE(gridview->contentX(), pos + 50); + + // reduce right margin + pos = gridview->contentX(); + gridview->setRightMargin(40); + QCOMPARE(gridview->xOrigin(), 0.); + QTRY_COMPARE(gridview->contentX(), pos-10); + + delete canvas; + } + { + //RTL + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(true)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QCOMPARE(gridview->contentX(), -240+30.); + QCOMPARE(gridview->xOrigin(), 0.); + + // check end bound + gridview->positionViewAtEnd(); + qreal pos = gridview->contentX(); + gridview->setContentX(pos - 80); + gridview->returnToBounds(); + QTRY_COMPARE(gridview->contentX(), pos - 50); + + // remove item before visible and check that left margin is maintained + // and xOrigin is updated + gridview->setContentX(-400); + model.removeItems(0, 4); + QTest::qWait(100); + gridview->setContentX(-240+50); + gridview->returnToBounds(); + QCOMPARE(gridview->xOrigin(), -100.); + QTRY_COMPARE(gridview->contentX(), -240-70.); + + // reduce left margin (i.e. right side due to RTL) + pos = gridview->contentX(); + gridview->setLeftMargin(20); + QCOMPARE(gridview->xOrigin(), -100.); + QTRY_COMPARE(gridview->contentX(), -240-80.); + + // check end bound + gridview->positionViewAtEnd(); + QCOMPARE(gridview->xOrigin(), 0.); // positionViewAtEnd() resets origin + pos = gridview->contentX(); + gridview->setContentX(pos - 80); + gridview->returnToBounds(); + QTRY_COMPARE(gridview->contentX(), pos - 50); + + // reduce right margin (i.e. left side due to RTL) + pos = gridview->contentX(); + gridview->setRightMargin(40); + QCOMPARE(gridview->xOrigin(), 0.); + QTRY_COMPARE(gridview->contentX(), pos+10); + + delete canvas; + } +} + +void tst_QQuickGridView::creationContext() +{ + QQuickView canvas; + canvas.setGeometry(0,0,240,320); + canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); + qApp->processEvents(); + + QQuickItem *rootItem = qobject_cast(canvas.rootObject()); + QVERIFY(rootItem); + QVERIFY(rootItem->property("count").toInt() > 0); + + QQuickItem *item; + QVERIFY(item = rootItem->findChild("listItem")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); + QVERIFY(item = rootItem->findChild("header")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); + QVERIFY(item = rootItem->findChild("footer")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); +} + +void tst_QQuickGridView::snapToRow_data() +{ + QTest::addColumn("flow"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("highlightRangeMode"); + QTest::addColumn("flickStart"); + QTest::addColumn("flickEnd"); + QTest::addColumn("snapAlignment"); + QTest::addColumn("endExtent"); + QTest::addColumn("startExtent"); + + QTest::newRow("vertical, left to right") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; + + QTest::newRow("horizontal, left to right") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; + + QTest::newRow("horizontal, right to left") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0; + + QTest::newRow("vertical, left to right, enforce range") << QQuickGridView::LeftToRight << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; + + QTest::newRow("horizontal, left to right, enforce range") << QQuickGridView::TopToBottom << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; + + QTest::newRow("horizontal, right to left, enforce range") << QQuickGridView::TopToBottom << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0; +} + +void tst_QQuickGridView::snapToRow() +{ + QFETCH(QQuickGridView::Flow, flow); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(int, highlightRangeMode); + QFETCH(QPoint, flickStart); + QFETCH(QPoint, flickEnd); + QFETCH(qreal, snapAlignment); + QFETCH(qreal, endExtent); + QFETCH(qreal, startExtent); + + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToRow.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QTRY_VERIFY(gridview != 0); + + gridview->setFlow(flow); + gridview->setLayoutDirection(layoutDirection); + gridview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); + + QQuickItem *contentItem = gridview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // confirm that a flick hits an item boundary + flick(canvas, flickStart, flickEnd, 180); + QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops + if (flow == QQuickGridView::LeftToRight) + QCOMPARE(qreal(fmod(gridview->contentY(),80.0)), snapAlignment); + else + QCOMPARE(qreal(fmod(gridview->contentX(),80.0)), snapAlignment); + + // flick to end + do { + flick(canvas, flickStart, flickEnd, 180); + QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops + } while (flow == QQuickGridView::LeftToRight + ? !gridview->isAtYEnd() + : layoutDirection == Qt::LeftToRight ? !gridview->isAtXEnd() : !gridview->isAtXBeginning()); + + if (flow == QQuickGridView::LeftToRight) + QCOMPARE(gridview->contentY(), endExtent); + else + QCOMPARE(gridview->contentX(), endExtent); + + // flick to start + do { + flick(canvas, flickEnd, flickStart, 180); + QTRY_VERIFY(gridview->isMoving() == false); // wait until it stops + } while (flow == QQuickGridView::LeftToRight + ? !gridview->isAtYBeginning() + : layoutDirection == Qt::LeftToRight ? !gridview->isAtXBeginning() : !gridview->isAtXEnd()); + + if (flow == QQuickGridView::LeftToRight) + QCOMPARE(gridview->contentY(), startExtent); + else + QCOMPARE(gridview->contentX(), startExtent); + + delete canvas; +} + +void tst_QQuickGridView::unaligned() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 10; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("unaligned.qml"))); + qApp->processEvents(); + + QQuickGridView *gridview = qobject_cast(canvas->rootObject()); + QVERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + + for (int i = 0; i < 10; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QVERIFY(item); + QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); + QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); + } + + // appending + for (int i = 10; i < 18; ++i) { + model.addItem("Item" + QString::number(i), ""); + QQuickItem *item = 0; + QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); + QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); + QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); + } + + // inserting + for (int i = 0; i < 10; ++i) { + model.insertItem(i, "Item" + QString::number(i), ""); + QQuickItem *item = 0; + QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); + QCOMPARE(item->x(), qreal((i%9)*gridview->cellWidth())); + QCOMPARE(item->y(), qreal((i/9)*gridview->cellHeight())); + } + + // removing + model.removeItems(7, 10); + QTRY_COMPARE(model.count(), gridview->count()); + for (int i = 0; i < 18; ++i) { + QQuickItem *item = 0; + QTRY_VERIFY(item = findItem(contentItem, "wrapper", i)); + QCOMPARE(item->x(), qreal(i%9)*gridview->cellWidth()); + QCOMPARE(item->y(), qreal(i/9)*gridview->cellHeight()); + } + + delete canvas; +} + +QQuickView *tst_QQuickGridView::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + return canvas; +} + +void tst_QQuickGridView::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas, Qt::LeftButton, 0, from); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); + } + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); +} + +void tst_QQuickGridView::cacheBuffer() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 90; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testRightToLeft", QVariant(false)); + ctxt->setContextProperty("testTopToBottom", QVariant(false)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("gridview1.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickGridView *gridview = findItem(canvas->rootObject(), "grid"); + QVERIFY(gridview != 0); + + QQuickItem *contentItem = gridview->contentItem(); + QVERIFY(contentItem != 0); + QVERIFY(gridview->delegate() != 0); + QVERIFY(gridview->model() != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), (i/3)*60.0); + } + + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + canvas->rootObject()->setProperty("cacheBuffer", 200); + QTRY_VERIFY(gridview->cacheBuffer() == 200); + + // items will be created one at a time + for (int i = itemCount; i < qMin(itemCount+9,model.count()); ++i) { + QVERIFY(findItem(gridview, "wrapper", i) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(gridview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + int newItemCount = 0; + newItemCount = findItems(contentItem, "wrapper").count(); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < newItemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), (i/3)*60.0); + } + + // move view and confirm items in view are visible immediately and outside are created async + gridview->setContentY(300); + + for (int i = 15; i < 34; ++i) { // 34 due to staggered item creation + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item); + QTRY_COMPARE(item->x(), (i%3)*80.0); + QTRY_COMPARE(item->y(), (i/3)*60.0); + } + + QVERIFY(findItem(gridview, "wrapper", 34) == 0); + + // ensure buffered items are created + for (int i = 34; i < qMin(44,model.count()); ++i) { + QQuickItem *item = 0; + while (!item) { + qGuiApp->processEvents(); // allow refill to happen + bool b = false; + controller.incubateWhile(&b); + item = findItem(gridview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + delete canvas; +} + +void tst_QQuickGridView::asynchronous() +{ + QQuickView *canvas = createView(); + canvas->show(); + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + canvas->setSource(TESTDATA("asyncloader.qml")); + + QQuickItem *rootObject = qobject_cast(canvas->rootObject()); + QVERIFY(rootObject); + + QQuickGridView *gridview = 0; + while (!gridview) { + bool b = false; + controller.incubateWhile(&b); + gridview = rootObject->findChild("view"); + } + + // items will be created one at a time + for (int i = 0; i < 12; ++i) { + QVERIFY(findItem(gridview, "wrapper", i) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(gridview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + // verify positioning + QQuickItem *contentItem = gridview->contentItem(); + for (int i = 0; i < 12; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QVERIFY(item->x() == (i%3)*100); + QVERIFY(item->y() == (i/3)*100); + } + + delete canvas; +} + +/* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template +T *tst_QQuickGridView::findItem(QQuickItem *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item); + if (context) { + if (context->contextProperty("index").toInt() == index) { + return static_cast(item); + } + } + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +template +QList tst_QQuickGridView::findItems(QQuickItem *parent, const QString &objectName) +{ + QList items; + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + items.append(static_cast(item)); + //qDebug() << " found:" << item; + } + items += findItems(item, objectName); + } + + return items; +} + +void tst_QQuickGridView::dumpTree(QQuickItem *parent, int depth) +{ + static QString padding(" "); + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + QDeclarativeContext *context = QDeclarativeEngine::contextForObject(item); + qDebug() << padding.left(depth*2) << item << (context ? context->contextProperty("index").toInt() : -1); + dumpTree(item, depth+1); + } +} + + +QTEST_MAIN(tst_QQuickGridView) + +#include "tst_qquickgridview.moc" + diff --git a/tests/auto/qtquick2/qquickimage/data/aspectratio.qml b/tests/auto/qtquick2/qquickimage/data/aspectratio.qml new file mode 100644 index 0000000000..b26f0e1f04 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/aspectratio.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Image { + source: "heart.png" + fillMode: Image.PreserveAspectFit; +} diff --git a/tests/auto/qtquick2/qquickimage/data/big.jpeg b/tests/auto/qtquick2/qquickimage/data/big.jpeg new file mode 100644 index 0000000000..bed7bd65c3 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/big.jpeg differ diff --git a/tests/auto/qtquick2/qquickimage/data/big256.png b/tests/auto/qtquick2/qquickimage/data/big256.png new file mode 100644 index 0000000000..1dc1596d03 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/big256.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/colors.png b/tests/auto/qtquick2/qquickimage/data/colors.png new file mode 100644 index 0000000000..dfb62f3d64 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/colors.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/colors1.png b/tests/auto/qtquick2/qquickimage/data/colors1.png new file mode 100644 index 0000000000..dfb62f3d64 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/colors1.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/green.png b/tests/auto/qtquick2/qquickimage/data/green.png new file mode 100644 index 0000000000..0a2e153ba1 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/green.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/heart-win32.png b/tests/auto/qtquick2/qquickimage/data/heart-win32.png new file mode 100644 index 0000000000..351da13772 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/heart-win32.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/heart.png b/tests/auto/qtquick2/qquickimage/data/heart.png new file mode 100644 index 0000000000..abe97fee4b Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/heart.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/heart.svg b/tests/auto/qtquick2/qquickimage/data/heart.svg new file mode 100644 index 0000000000..8c982cd93c --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/heart.svg @@ -0,0 +1,55 @@ + + + + + +Heart Left-Highlight +This is a normal valentines day heart. + + +holiday +valentines + +valentine +hash(0x8a091c0) +hash(0x8a0916c) +signs_and_symbols +hash(0x8a091f0) +day + + + + +Jon Phillips + + + + +Jon Phillips + + + + +Jon Phillips + + + +image/svg+xml + + +en + + + + + + + + + + + + + + + diff --git a/tests/auto/qtquick2/qquickimage/data/heart200-win32.png b/tests/auto/qtquick2/qquickimage/data/heart200-win32.png new file mode 100644 index 0000000000..4976ff98ba Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/heart200-win32.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/heart200.png b/tests/auto/qtquick2/qquickimage/data/heart200.png new file mode 100644 index 0000000000..7fbb13c5bb Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/heart200.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/htiling.qml b/tests/auto/qtquick2/qquickimage/data/htiling.qml new file mode 100644 index 0000000000..f192f931c9 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/htiling.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 200; height: 550 + + Image { + objectName: "tiling"; anchors.fill: parent + source: "green.png"; fillMode: Image.TileHorizontally + } +} + diff --git a/tests/auto/qtquick2/qquickimage/data/mirror.qml b/tests/auto/qtquick2/qquickimage/data/mirror.qml new file mode 100644 index 0000000000..98fddf083e --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/mirror.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 300 + height: 250 + Image { + objectName: "image" + anchors.fill: parent + source: "pattern.png" + } +} diff --git a/tests/auto/qtquick2/qquickimage/data/nullpixmap.qml b/tests/auto/qtquick2/qquickimage/data/nullpixmap.qml new file mode 100644 index 0000000000..d52f41f164 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/nullpixmap.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Image { + width: 10; height:10; fillMode: Image.PreserveAspectFit + source: "" +} diff --git a/tests/auto/qtquick2/qquickimage/data/pattern.png b/tests/auto/qtquick2/qquickimage/data/pattern.png new file mode 100644 index 0000000000..d3d5e1e007 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/pattern.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/qtbug_16389.qml b/tests/auto/qtquick2/qquickimage/data/qtbug_16389.qml new file mode 100644 index 0000000000..7b8adecb11 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/qtbug_16389.qml @@ -0,0 +1,30 @@ +import QtQuick 2.0 +Rectangle { + width: 400 + height: 400 + + Item { + anchors.top: parent.top + anchors.left: parent.left + anchors.bottom: blueHandle.top + anchors.right: blueHandle.left + + Image { + id: iconImage + objectName: "iconImage" + anchors.top: parent.top + anchors.bottom: parent.bottom + source: "heart200.png" + fillMode: Image.PreserveAspectFit + smooth: true + } + } + + Rectangle { + id: blueHandle + objectName: "blueHandle" + color: "blue" + width: 25 + height: 25 + } +} diff --git a/tests/auto/qtquick2/qquickimage/data/qtbug_22125.qml b/tests/auto/qtquick2/qquickimage/data/qtbug_22125.qml new file mode 100644 index 0000000000..9b68c0a125 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/qtbug_22125.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +Item { + id: root + width: 800 + height: 800 + + GridView { + anchors.fill: parent + delegate: Image { + source: imagePath; + asynchronous: true + smooth: true + width: 200 + height: 200 + } + model: ListModel { + ListElement { + imagePath: "http://127.0.0.1:14451/big256.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/big256.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/big256.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/colors.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/colors1.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/big.jpeg" + } + ListElement { + imagePath: "http://127.0.0.1:14451/heart.png" + } + ListElement { + imagePath: "http://127.0.0.1:14451/green.png" + } + } + } +} diff --git a/tests/auto/qtquick2/qquickimage/data/rect.png b/tests/auto/qtquick2/qquickimage/data/rect.png new file mode 100644 index 0000000000..d564a2d5a5 Binary files /dev/null and b/tests/auto/qtquick2/qquickimage/data/rect.png differ diff --git a/tests/auto/qtquick2/qquickimage/data/vtiling.qml b/tests/auto/qtquick2/qquickimage/data/vtiling.qml new file mode 100644 index 0000000000..f730f6e050 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/data/vtiling.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + width: 550; height: 200 + + Image { + objectName: "tiling"; anchors.fill: parent + source: "green.png"; fillMode: Image.TileVertically + } +} + diff --git a/tests/auto/qtquick2/qquickimage/qquickimage.pro b/tests/auto/qtquick2/qquickimage/qquickimage.pro new file mode 100644 index 0000000000..fd2af3b677 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/qquickimage.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickimage +macx:CONFIG -= app_bundle + +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qquickimage.cpp ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp b/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp new file mode 100644 index 0000000000..a7883626c6 --- /dev/null +++ b/tests/auto/qtquick2/qquickimage/tst_qquickimage.cpp @@ -0,0 +1,732 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/util.h" +#include "../../shared/testhttpserver.h" + +#define SERVER_PORT 14451 +#define SERVER_ADDR "http://127.0.0.1:14451" + +Q_DECLARE_METATYPE(QQuickImageBase::Status) + +class tst_qquickimage : public QObject +{ + Q_OBJECT +public: + tst_qquickimage(); + +private slots: + void noSource(); + void imageSource(); + void imageSource_data(); + void clearSource(); + void resized(); + void preserveAspectRatio(); + void smooth(); + void mirror(); + void svg(); + void geometry(); + void geometry_data(); + void big(); + void tiling_QTBUG_6716(); + void tiling_QTBUG_6716_data(); + void noLoading(); + void paintedWidthHeight(); + void sourceSize_QTBUG_14303(); + void sourceSize_QTBUG_16389(); + void nullPixmapPaint(); + void imageCrash_QTBUG_22125(); + +private: + template + T *findItem(QQuickItem *parent, const QString &id, int index=-1); + + QDeclarativeEngine engine; +}; + +tst_qquickimage::tst_qquickimage() +{ +} + +void tst_qquickimage::noSource() +{ + QString componentStr = "import QtQuick 2.0\nImage { source: \"\" }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->source(), QUrl()); + QVERIFY(obj->status() == QQuickImage::Null); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); + QCOMPARE(obj->fillMode(), QQuickImage::Stretch); + QCOMPARE(obj->progress(), 0.0); + + delete obj; +} + +void tst_qquickimage::imageSource_data() +{ + QTest::addColumn("source"); + QTest::addColumn("width"); + QTest::addColumn("height"); + QTest::addColumn("remote"); + QTest::addColumn("async"); + QTest::addColumn("cache"); + QTest::addColumn("error"); + + QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << true << ""; + QTest::newRow("local no cache") << QUrl::fromLocalFile(TESTDATA("colors.png")).toString() << 120.0 << 120.0 << false << false << false << ""; + QTest::newRow("local async") << QUrl::fromLocalFile(TESTDATA("colors1.png")).toString() << 120.0 << 120.0 << false << true << true << ""; + QTest::newRow("local not found") << QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString() << 0.0 << 0.0 << false + << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file.png")).toString(); + QTest::newRow("local async not found") << QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString() << 0.0 << 0.0 << false + << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(TESTDATA("no-such-file-1.png")).toString(); + QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << true << ""; + QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << ""; + if (QImageReader::supportedImageFormats().contains("svg")) + QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << ""; + + QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true + << false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found"; + +} + +void tst_qquickimage::imageSource() +{ + QFETCH(QString, source); + QFETCH(double, width); + QFETCH(double, height); + QFETCH(bool, remote); + QFETCH(bool, async); + QFETCH(bool, cache); + QFETCH(QString, error); + + TestHTTPServer server(SERVER_PORT); + if (remote) { + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png"); + } + + if (!error.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); + + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + source + "\"; asynchronous: " + + (async ? QLatin1String("true") : QLatin1String("false")) + "; cache: " + + (cache ? QLatin1String("true") : QLatin1String("false")) + " }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + + if (async) + QVERIFY(obj->asynchronous() == true); + else + QVERIFY(obj->asynchronous() == false); + + if (cache) + QVERIFY(obj->cache() == true); + else + QVERIFY(obj->cache() == false); + + if (remote || async) + QTRY_VERIFY(obj->status() == QQuickImage::Loading); + + QCOMPARE(obj->source(), remote ? source : QUrl(source)); + + if (error.isEmpty()) { + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QCOMPARE(obj->width(), qreal(width)); + QCOMPARE(obj->height(), qreal(height)); + QCOMPARE(obj->fillMode(), QQuickImage::Stretch); + QCOMPARE(obj->progress(), 1.0); + } else { + QTRY_VERIFY(obj->status() == QQuickImage::Error); + } + + delete obj; +} + +void tst_qquickimage::clearSource() +{ + QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QVERIFY(obj->status() == QQuickImage::Ready); + QCOMPARE(obj->width(), 120.); + QCOMPARE(obj->height(), 120.); + QCOMPARE(obj->progress(), 1.0); + + ctxt->setContextProperty("srcImage", ""); + QVERIFY(obj->source().isEmpty()); + QVERIFY(obj->status() == QQuickImage::Null); + QCOMPARE(obj->width(), 0.); + QCOMPARE(obj->height(), 0.); + QCOMPARE(obj->progress(), 0.0); + + delete obj; +} + +void tst_qquickimage::resized() +{ + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->fillMode(), QQuickImage::Stretch); + delete obj; +} + + +void tst_qquickimage::preserveAspectRatio() +{ + QQuickView *canvas = new QQuickView(0); + canvas->show(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml"))); + QQuickImage *image = qobject_cast(canvas->rootObject()); + QVERIFY(image != 0); + image->setWidth(80.0); + QCOMPARE(image->width(), 80.); + QCOMPARE(image->height(), 80.); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("aspectratio.qml"))); + image = qobject_cast(canvas->rootObject()); + image->setHeight(60.0); + QVERIFY(image != 0); + QCOMPARE(image->height(), 60.); + QCOMPARE(image->width(), 60.); + delete canvas; +} + +void tst_qquickimage::smooth() +{ + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + TESTDATA("colors.png") + "\"; smooth: true; width: 300; height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.); + QCOMPARE(obj->height(), 300.); + QCOMPARE(obj->smooth(), true); + QCOMPARE(obj->fillMode(), QQuickImage::Stretch); + + delete obj; +} + +void tst_qquickimage::mirror() +{ + QSKIP("Test is broken on multiple levels, will need incremental fixes"); + + QMap screenshots; + QList fillModes; + fillModes << QQuickImage::Stretch << QQuickImage::PreserveAspectFit << QQuickImage::PreserveAspectCrop + << QQuickImage::Tile << QQuickImage::TileVertically << QQuickImage::TileHorizontally; + + qreal width = 300; + qreal height = 250; + + foreach (QQuickImage::FillMode fillMode, fillModes) { + QQuickView *canvas = new QQuickView; + canvas->setSource(QUrl::fromLocalFile(TESTDATA("mirror.qml"))); + + QQuickImage *obj = canvas->rootObject()->findChild("image"); + QVERIFY(obj != 0); + + obj->setFillMode(fillMode); + obj->setProperty("mirror", true); + canvas->show(); + + QImage screenshot = canvas->grabFrameBuffer(); + screenshots[fillMode] = screenshot; + delete canvas; + } + + foreach (QQuickImage::FillMode fillMode, fillModes) { + QPixmap srcPixmap; + QVERIFY(srcPixmap.load(TESTDATA("pattern.png"))); + + QPixmap expected(width, height); + expected.fill(); + QPainter p_e(&expected); + QTransform transform; + transform.translate(width, 0).scale(-1, 1.0); + p_e.setTransform(transform); + + switch (fillMode) { + case QQuickImage::Stretch: + p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + case QQuickImage::PreserveAspectFit: + p_e.drawPixmap(QRect(25, 0, height, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + case QQuickImage::PreserveAspectCrop: + { + qreal ratio = width/srcPixmap.width(); // width is the longer side + QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio); + rect.moveCenter(QRect(0, 0, width, height).center()); + p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height())); + break; + } + case QQuickImage::Tile: + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + case QQuickImage::TileVertically: + transform.scale(width / srcPixmap.width(), 1.0); + p_e.setTransform(transform); + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + case QQuickImage::TileHorizontally: + transform.scale(1.0, height / srcPixmap.height()); + p_e.setTransform(transform); + p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap); + break; + case QQuickImage::Pad: + break; + } + + QImage img = expected.toImage(); + QEXPECT_FAIL("", "QTBUG-21005 fails", Continue); + QCOMPARE(screenshots[fillMode], img); + } +} + +void tst_qquickimage::svg() +{ + if (!QImageReader::supportedImageFormats().contains("svg")) + QSKIP("svg support not available"); + + QString src = QUrl::fromLocalFile(TESTDATA("heart.svg")).toString(); + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; sourceSize.width: 300; sourceSize.height: 300 }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 300.0); + QCOMPARE(obj->height(), 300.0); + obj->setSourceSize(QSize(200,200)); + + QCOMPARE(obj->width(), 200.0); + QCOMPARE(obj->height(), 200.0); + delete obj; +} + +void tst_qquickimage::geometry_data() +{ + QTest::addColumn("fillMode"); + QTest::addColumn("explicitWidth"); + QTest::addColumn("explicitHeight"); + QTest::addColumn("itemWidth"); + QTest::addColumn("paintedWidth"); + QTest::addColumn("boundingWidth"); + QTest::addColumn("itemHeight"); + QTest::addColumn("paintedHeight"); + QTest::addColumn("boundingHeight"); + + // tested image has width 200, height 100 + + // bounding rect and item rect are equal with fillMode PreserveAspectFit, painted rect may be smaller if the aspect ratio doesn't match + QTest::newRow("PreserveAspectFit") << "PreserveAspectFit" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; + QTest::newRow("PreserveAspectFit explicit width 300") << "PreserveAspectFit" << true << false << 300.0 << 200.0 << 300.0 << 100.0 << 100.0 << 100.0; + QTest::newRow("PreserveAspectFit explicit height 400") << "PreserveAspectFit" << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 100.0 << 400.0; + QTest::newRow("PreserveAspectFit explicit width 300, height 400") << "PreserveAspectFit" << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 150.0 << 400.0; + + // bounding rect and painted rect are equal with fillMode PreserveAspectCrop, item rect may be smaller if the aspect ratio doesn't match + QTest::newRow("PreserveAspectCrop") << "PreserveAspectCrop" << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; + QTest::newRow("PreserveAspectCrop explicit width 300") << "PreserveAspectCrop" << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 150.0 << 150.0; + QTest::newRow("PreserveAspectCrop explicit height 400") << "PreserveAspectCrop" << false << true << 200.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0; + QTest::newRow("PreserveAspectCrop explicit width 300, height 400") << "PreserveAspectCrop" << true << true << 300.0 << 800.0 << 800.0 << 400.0 << 400.0 << 400.0; + + // bounding rect, painted rect and item rect are equal in stretching and tiling images + QStringList fillModes; + fillModes << "Stretch" << "Tile" << "TileVertically" << "TileHorizontally"; + foreach (QString fillMode, fillModes) { + QTest::newRow(fillMode.toLatin1()) << fillMode << false << false << 200.0 << 200.0 << 200.0 << 100.0 << 100.0 << 100.0; + QTest::newRow(QString(fillMode + " explicit width 300").toLatin1()) << fillMode << true << false << 300.0 << 300.0 << 300.0 << 100.0 << 100.0 << 100.0; + QTest::newRow(QString(fillMode + " explicit height 400").toLatin1()) << fillMode << false << true << 200.0 << 200.0 << 200.0 << 400.0 << 400.0 << 400.0; + QTest::newRow(QString(fillMode + " explicit width 300, height 400").toLatin1()) << fillMode << true << true << 300.0 << 300.0 << 300.0 << 400.0 << 400.0 << 400.0; + } +} + +void tst_qquickimage::geometry() +{ + QFETCH(QString, fillMode); + QFETCH(bool, explicitWidth); + QFETCH(bool, explicitHeight); + QFETCH(double, itemWidth); + QFETCH(double, itemHeight); + QFETCH(double, paintedWidth); + QFETCH(double, paintedHeight); + QFETCH(double, boundingWidth); + QFETCH(double, boundingHeight); + + QString src = QUrl::fromLocalFile(TESTDATA("rect.png")).toString(); + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; fillMode: Image." + fillMode + "; "; + + if (explicitWidth) + componentStr.append("width: 300; "); + if (explicitHeight) + componentStr.append("height: 400; "); + componentStr.append("}"); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->width(), itemWidth); + QCOMPARE(obj->paintedWidth(), paintedWidth); + QCOMPARE(obj->boundingRect().width(), boundingWidth); + + QCOMPARE(obj->height(), itemHeight); + QCOMPARE(obj->paintedHeight(), paintedHeight); + QCOMPARE(obj->boundingRect().height(), boundingHeight); + delete obj; +} + +void tst_qquickimage::big() +{ + // If the JPEG loader does not implement scaling efficiently, it would + // have to build a 400 MB image. That would be a bug in the JPEG loader. + + QString src = QUrl::fromLocalFile(TESTDATA("big.jpeg")).toString(); + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 100; sourceSize.height: 256 }"; + + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 100.0); + QCOMPARE(obj->height(), 256.0); + + delete obj; +} + +// As tiling_QTBUG_6716 doesn't complete, it doesn't delete the +// canvas which causes leak warnings. Use this delete on stack +// destruction pattern to work around this. +template +struct AutoDelete { + AutoDelete(T *t) : t(t) {} + ~AutoDelete() { delete t; } +private: + T *t; +}; + +void tst_qquickimage::tiling_QTBUG_6716() +{ + QSKIP("Test is broken on multiple levels, will need incremental fixes"); + + QFETCH(QString, source); + + QQuickView *canvas = new QQuickView(0); + AutoDelete del(canvas); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA(source))); + canvas->show(); + qApp->processEvents(); + + QQuickImage *tiling = findItem(canvas->rootObject(), "tiling"); + + QVERIFY(tiling != 0); + QImage img = canvas->grabFrameBuffer(); + for (int x = 0; x < tiling->width(); ++x) { + for (int y = 0; y < tiling->height(); ++y) { + QVERIFY(img.pixel(x, y) == qRgb(0, 255, 0)); + } + } +} + +void tst_qquickimage::tiling_QTBUG_6716_data() +{ + QTest::addColumn("source"); + QTest::newRow("vertical_tiling") << "vtiling.qml"; + QTest::newRow("horizontal_tiling") << "htiling.qml"; +} + +void tst_qquickimage::noLoading() +{ + qRegisterMetaType(); + + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + server.addRedirect("oldcolors.png", SERVER_ADDR "/colors.png"); + + QString componentStr = "import QtQuick 2.0\nImage { source: srcImage; cache: true }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart.png"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QVERIFY(obj->status() == QQuickImage::Ready); + + QSignalSpy sourceSpy(obj, SIGNAL(sourceChanged(const QUrl &))); + QSignalSpy progressSpy(obj, SIGNAL(progressChanged(qreal))); + QSignalSpy statusSpy(obj, SIGNAL(statusChanged(QQuickImageBase::Status))); + + // Loading local file + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png"))); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 1); + QTRY_COMPARE(progressSpy.count(), 0); + QTRY_COMPARE(statusSpy.count(), 0); + + // Loading remote file + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png"); + QTRY_VERIFY(obj->status() == QQuickImage::Loading); + QTRY_VERIFY(obj->progress() == 0.0); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 2); + QTRY_COMPARE(progressSpy.count(), 2); + QTRY_COMPARE(statusSpy.count(), 2); + + // Loading remote file again - should not go through 'Loading' state. + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("green.png"))); + ctxt->setContextProperty("srcImage", QString(SERVER_ADDR) + "/rect.png"); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + QTRY_VERIFY(obj->progress() == 1.0); + QTRY_COMPARE(sourceSpy.count(), 4); + QTRY_COMPARE(progressSpy.count(), 2); + QTRY_COMPARE(statusSpy.count(), 2); + + delete obj; +} + +void tst_qquickimage::paintedWidthHeight() +{ + { + QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString(); + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 200; height: 25; fillMode: Image.PreserveAspectFit }"; + + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 200.0); + QCOMPARE(obj->height(), 25.0); + QCOMPARE(obj->paintedWidth(), 25.0); + QCOMPARE(obj->paintedHeight(), 25.0); + + delete obj; + } + + { + QString src = QUrl::fromLocalFile(TESTDATA("heart.png")).toString(); + QString componentStr = "import QtQuick 2.0\nImage { source: \"" + src + "\"; width: 26; height: 175; fillMode: Image.PreserveAspectFit }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + QVERIFY(obj != 0); + QCOMPARE(obj->width(), 26.0); + QCOMPARE(obj->height(), 175.0); + QCOMPARE(obj->paintedWidth(), 26.0); + QCOMPARE(obj->paintedHeight(), 26.0); + + delete obj; + } +} + +void tst_qquickimage::sourceSize_QTBUG_14303() +{ + QString componentStr = "import QtQuick 2.0\nImage { source: srcImage }"; + QDeclarativeContext *ctxt = engine.rootContext(); + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png"))); + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickImage *obj = qobject_cast(component.create()); + + QSignalSpy sourceSizeSpy(obj, SIGNAL(sourceSizeChanged())); + + QTRY_VERIFY(obj != 0); + QTRY_VERIFY(obj->status() == QQuickImage::Ready); + + QTRY_COMPARE(obj->sourceSize().width(), 200); + QTRY_COMPARE(obj->sourceSize().height(), 200); + QTRY_COMPARE(sourceSizeSpy.count(), 0); + + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("colors.png"))); + QTRY_COMPARE(obj->sourceSize().width(), 120); + QTRY_COMPARE(obj->sourceSize().height(), 120); + QTRY_COMPARE(sourceSizeSpy.count(), 1); + + ctxt->setContextProperty("srcImage", QUrl::fromLocalFile(TESTDATA("heart200.png"))); + QTRY_COMPARE(obj->sourceSize().width(), 200); + QTRY_COMPARE(obj->sourceSize().height(), 200); + QTRY_COMPARE(sourceSizeSpy.count(), 2); + + delete obj; +} + +void tst_qquickimage::sourceSize_QTBUG_16389() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug_16389.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickImage *image = findItem(canvas->rootObject(), "iconImage"); + QQuickItem *handle = findItem(canvas->rootObject(), "blueHandle"); + + QCOMPARE(image->sourceSize().width(), 200); + QCOMPARE(image->sourceSize().height(), 200); + QCOMPARE(image->paintedWidth(), 0.0); + QCOMPARE(image->paintedHeight(), 0.0); + + handle->setY(20); + + QCOMPARE(image->sourceSize().width(), 200); + QCOMPARE(image->sourceSize().height(), 200); + QCOMPARE(image->paintedWidth(), 20.0); + QCOMPARE(image->paintedHeight(), 20.0); + + delete canvas; +} + +static int numberOfWarnings = 0; +static void checkWarnings(QtMsgType, const char *msg) +{ + if (!QString(msg).contains("QGLContext::makeCurrent(): Failed.")) + numberOfWarnings++; +} + +// QTBUG-15690 +void tst_qquickimage::nullPixmapPaint() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("nullpixmap.qml"))); + canvas->show(); + + QQuickImage *image = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(image != 0); + image->setSource(SERVER_ADDR + QString("/no-such-file.png")); + + QtMsgHandler previousMsgHandler = qInstallMsgHandler(checkWarnings); + + // used to print "QTransform::translate with NaN called" + QPixmap pm = QPixmap::fromImage(canvas->grabFrameBuffer()); + qInstallMsgHandler(previousMsgHandler); + QVERIFY(numberOfWarnings == 0); + delete image; +} + +void tst_qquickimage::imageCrash_QTBUG_22125() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA(""), TestHTTPServer::Delay); + + { + QQuickView view(QUrl::fromLocalFile(TESTDATA("qtbug_22125.qml"))); + view.show(); + qApp->processEvents(); + qApp->processEvents(); + // shouldn't crash when the view drops out of scope due to + // QDeclarativePixmapData attempting to dereference a pointer to + // the destroyed reader. + } + + // shouldn't crash when deleting cancelled QDeclarativePixmapReplys. + QTest::qWait(520); // Delay mode delays for 500 ms. + qApp->processEvents(QEventLoop::DeferredDeletion); +} + +/* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template +T *tst_qquickimage::findItem(QQuickItem *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), item, "index"); + if (e.evaluate().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +QTEST_MAIN(tst_qquickimage) + +#include "tst_qquickimage.moc" diff --git a/tests/auto/qtquick2/qquickitem/data/order.1.qml b/tests/auto/qtquick2/qquickitem/data/order.1.qml new file mode 100644 index 0000000000..963288b257 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem/data/order.1.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Item { + Item { objectName: "1" } + Item { objectName: "2" } + Item { objectName: "3" } +} diff --git a/tests/auto/qtquick2/qquickitem/data/order.2.qml b/tests/auto/qtquick2/qquickitem/data/order.2.qml new file mode 100644 index 0000000000..5609c77e28 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem/data/order.2.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Item { + Item { objectName: "1" } + Item { objectName: "2"; z: 1.0 } + Item { objectName: "3" } +} diff --git a/tests/auto/qtquick2/qquickitem/qquickitem.pro b/tests/auto/qtquick2/qquickitem/qquickitem.pro new file mode 100644 index 0000000000..2ebe76b09c --- /dev/null +++ b/tests/auto/qtquick2/qquickitem/qquickitem.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickitem +SOURCES += tst_qquickitem.cpp + +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private v8-private declarative-private quick-private widgets testlib diff --git a/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp b/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp new file mode 100644 index 0000000000..fd7433b64e --- /dev/null +++ b/tests/auto/qtquick2/qquickitem/tst_qquickitem.cpp @@ -0,0 +1,1190 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include +#include +#include "private/qquickfocusscope_p.h" +#include "private/qquickitem_p.h" +#include +#include +#include "../../shared/util.h" + +class TestItem : public QQuickItem +{ +Q_OBJECT +public: + TestItem(QQuickItem *parent = 0) : QQuickItem(parent), focused(false), pressCount(0), releaseCount(0), wheelCount(0) {} + + bool focused; + int pressCount; + int releaseCount; + int wheelCount; +protected: + virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } + virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } + virtual void mousePressEvent(QMouseEvent *event) { event->accept(); ++pressCount; } + virtual void mouseReleaseEvent(QMouseEvent *event) { event->accept(); ++releaseCount; } + virtual void wheelEvent(QWheelEvent *event) { event->accept(); ++wheelCount; } +}; + +class TestPolishItem : public QQuickItem +{ +Q_OBJECT +public: + TestPolishItem(QQuickItem *parent) + : QQuickItem(parent), wasPolished(false) { + QTimer::singleShot(10, this, SLOT(doPolish())); + } + + bool wasPolished; + +protected: + virtual void updatePolish() { + wasPolished = true; + } + +public slots: + void doPolish() { + polish(); + } +}; + +class TestFocusScope : public QQuickFocusScope +{ +Q_OBJECT +public: + TestFocusScope(QQuickItem *parent = 0) : QQuickFocusScope(parent), focused(false) {} + + bool focused; +protected: + virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; } + virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; } +}; + +class tst_qquickitem : public QObject +{ + Q_OBJECT +public: + tst_qquickitem(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void noCanvas(); + void simpleFocus(); + void scopedFocus(); + void addedToCanvas(); + void changeParent(); + + void constructor(); + void setParentItem(); + + void visible(); + void enabled(); + + void mouseGrab(); + void polishOutsideAnimation(); + + void wheelEvent_data(); + void wheelEvent(); + void hoverEvent_data(); + void hoverEvent(); + void hoverEventInParent(); + + void paintOrder_data(); + void paintOrder(); + +private: + + enum PaintOrderOp { + NoOp, Append, Remove, StackBefore, StackAfter, SetZ + }; + + void ensureFocus(QWindow *w) { + w->show(); + w->requestActivateWindow(); + qApp->processEvents(); + } +}; + +tst_qquickitem::tst_qquickitem() +{ +} + +void tst_qquickitem::initTestCase() +{ +} + +void tst_qquickitem::cleanupTestCase() +{ +} + +// Focus has no effect when outside a canvas +void tst_qquickitem::noCanvas() +{ + QQuickItem *root = new TestItem; + QQuickItem *child = new TestItem(root); + QQuickItem *scope = new TestItem(root); + QQuickFocusScope *scopedChild = new TestFocusScope(scope); + QQuickFocusScope *scopedChild2 = new TestFocusScope(scope); + + QCOMPARE(root->hasFocus(), false); + QCOMPARE(child->hasFocus(), false); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scopedChild->hasFocus(), false); + QCOMPARE(scopedChild2->hasFocus(), false); + + root->setFocus(true); + scope->setFocus(true); + scopedChild2->setFocus(true); + QCOMPARE(root->hasFocus(), true); + QCOMPARE(child->hasFocus(), false); + QCOMPARE(scope->hasFocus(), true); + QCOMPARE(scopedChild->hasFocus(), false); + QCOMPARE(scopedChild2->hasFocus(), true); + + root->setFocus(false); + child->setFocus(true); + scopedChild->setFocus(true); + scope->setFocus(false); + QCOMPARE(root->hasFocus(), false); + QCOMPARE(child->hasFocus(), true); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scopedChild->hasFocus(), true); + QCOMPARE(scopedChild2->hasFocus(), true); + + delete root; +} + +struct FocusData { + FocusData() : focus(false), activeFocus(false) {} + + void set(bool f, bool af) { focus = f; activeFocus = af; } + bool focus; + bool activeFocus; +}; +struct FocusState : public QHash +{ + FocusState() : activeFocusItem(0) {} + FocusState &operator<<(QQuickItem *item) { + insert(item, FocusData()); + return *this; + } + + void active(QQuickItem *i) { + activeFocusItem = i; + } + QQuickItem *activeFocusItem; +}; + +#define FVERIFY() \ + do { \ + if (focusState.activeFocusItem) { \ + QCOMPARE(canvas.activeFocusItem(), focusState.activeFocusItem); \ + if (qobject_cast(canvas.activeFocusItem())) \ + QCOMPARE(qobject_cast(canvas.activeFocusItem())->focused, true); \ + else if (qobject_cast(canvas.activeFocusItem())) \ + QCOMPARE(qobject_cast(canvas.activeFocusItem())->focused, true); \ + } else { \ + QCOMPARE(canvas.activeFocusItem(), canvas.rootItem()); \ + } \ + for (QHash::Iterator iter = focusState.begin(); \ + iter != focusState.end(); \ + iter++) { \ + QCOMPARE(iter.key()->hasFocus(), iter.value().focus); \ + QCOMPARE(iter.key()->hasActiveFocus(), iter.value().activeFocus); \ + } \ + } while (false) + +// Tests a simple set of top-level scoped items +void tst_qquickitem::simpleFocus() +{ + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem *l1c1 = new TestItem(canvas.rootItem()); + QQuickItem *l1c2 = new TestItem(canvas.rootItem()); + QQuickItem *l1c3 = new TestItem(canvas.rootItem()); + + QQuickItem *l2c1 = new TestItem(l1c1); + QQuickItem *l2c2 = new TestItem(l1c1); + QQuickItem *l2c3 = new TestItem(l1c3); + + FocusState focusState; + focusState << l1c1 << l1c2 << l1c3 + << l2c1 << l2c2 << l2c3; + FVERIFY(); + + l1c1->setFocus(true); + focusState[l1c1].set(true, true); + focusState.active(l1c1); + FVERIFY(); + + l2c3->setFocus(true); + focusState[l1c1].set(false, false); + focusState[l2c3].set(true, true); + focusState.active(l2c3); + FVERIFY(); + + l1c3->setFocus(true); + focusState[l2c3].set(false, false); + focusState[l1c3].set(true, true); + focusState.active(l1c3); + FVERIFY(); + + l1c2->setFocus(false); + FVERIFY(); + + l1c3->setFocus(false); + focusState[l1c3].set(false, false); + focusState.active(0); + FVERIFY(); + + l2c1->setFocus(true); + focusState[l2c1].set(true, true); + focusState.active(l2c1); + FVERIFY(); +} + +// Items with a focus scope +void tst_qquickitem::scopedFocus() +{ + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem *l1c1 = new TestItem(canvas.rootItem()); + QQuickItem *l1c2 = new TestItem(canvas.rootItem()); + QQuickItem *l1c3 = new TestItem(canvas.rootItem()); + + QQuickItem *l2c1 = new TestItem(l1c1); + QQuickItem *l2c2 = new TestItem(l1c1); + QQuickItem *l2c3 = new TestFocusScope(l1c3); + + QQuickItem *l3c1 = new TestItem(l2c3); + QQuickItem *l3c2 = new TestFocusScope(l2c3); + + QQuickItem *l4c1 = new TestItem(l3c2); + QQuickItem *l4c2 = new TestItem(l3c2); + + FocusState focusState; + focusState << l1c1 << l1c2 << l1c3 + << l2c1 << l2c2 << l2c3 + << l3c1 << l3c2 + << l4c1 << l4c2; + FVERIFY(); + + l4c2->setFocus(true); + focusState[l4c2].set(true, false); + FVERIFY(); + + l4c1->setFocus(true); + focusState[l4c2].set(false, false); + focusState[l4c1].set(true, false); + FVERIFY(); + + l1c1->setFocus(true); + focusState[l1c1].set(true, true); + focusState.active(l1c1); + FVERIFY(); + + l3c2->setFocus(true); + focusState[l3c2].set(true, false); + FVERIFY(); + + l2c3->setFocus(true); + focusState[l1c1].set(false, false); + focusState[l2c3].set(true, true); + focusState[l3c2].set(true, true); + focusState[l4c1].set(true, true); + focusState.active(l4c1); + FVERIFY(); + + l3c2->setFocus(false); + focusState[l3c2].set(false, false); + focusState[l4c1].set(true, false); + focusState.active(l2c3); + FVERIFY(); + + l3c2->setFocus(true); + focusState[l3c2].set(true, true); + focusState[l4c1].set(true, true); + focusState.active(l4c1); + FVERIFY(); + + l4c1->setFocus(false); + focusState[l4c1].set(false, false); + focusState.active(l3c2); + FVERIFY(); + + l1c3->setFocus(true); + focusState[l1c3].set(true, true); + focusState[l2c3].set(false, false); + focusState[l3c2].set(true, false); + focusState.active(l1c3); + FVERIFY(); +} + +// Tests focus corrects itself when a tree is added to a canvas for the first time +void tst_qquickitem::addedToCanvas() +{ + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem *item = new TestItem; + + FocusState focusState; + focusState << item; + + item->setFocus(true); + focusState[item].set(true, false); + FVERIFY(); + + item->setParentItem(canvas.rootItem()); + focusState[item].set(true, true); + focusState.active(item); + FVERIFY(); + } + + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem *item = new TestItem(canvas.rootItem()); + + QQuickItem *tree = new TestItem; + QQuickItem *c1 = new TestItem(tree); + QQuickItem *c2 = new TestItem(tree); + + FocusState focusState; + focusState << item << tree << c1 << c2; + + item->setFocus(true); + c1->setFocus(true); + c2->setFocus(true); + focusState[item].set(true, true); + focusState[c1].set(true, false); + focusState[c2].set(true, false); + focusState.active(item); + FVERIFY(); + + tree->setParentItem(item); + focusState[c1].set(false, false); + focusState[c2].set(false, false); + FVERIFY(); + } + + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + + QQuickItem *tree = new TestItem; + QQuickItem *c1 = new TestItem(tree); + QQuickItem *c2 = new TestItem(tree); + + FocusState focusState; + focusState << tree << c1 << c2; + c1->setFocus(true); + c2->setFocus(true); + focusState[c1].set(true, false); + focusState[c2].set(true, false); + FVERIFY(); + + tree->setParentItem(canvas.rootItem()); + focusState[c1].set(true, true); + focusState[c2].set(false, false); + focusState.active(c1); + FVERIFY(); + } + + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *tree = new TestFocusScope; + QQuickItem *c1 = new TestItem(tree); + QQuickItem *c2 = new TestItem(tree); + + FocusState focusState; + focusState << tree << c1 << c2; + c1->setFocus(true); + c2->setFocus(true); + focusState[c1].set(true, false); + focusState[c2].set(true, false); + FVERIFY(); + + tree->setParentItem(canvas.rootItem()); + focusState[c1].set(true, false); + focusState[c2].set(false, false); + FVERIFY(); + + tree->setFocus(true); + focusState[tree].set(true, true); + focusState[c1].set(true, true); + focusState.active(c1); + FVERIFY(); + } + + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *tree = new TestFocusScope; + QQuickItem *c1 = new TestItem(tree); + QQuickItem *c2 = new TestItem(tree); + + FocusState focusState; + focusState << tree << c1 << c2; + tree->setFocus(true); + c1->setFocus(true); + c2->setFocus(true); + focusState[tree].set(true, false); + focusState[c1].set(true, false); + focusState[c2].set(true, false); + FVERIFY(); + + tree->setParentItem(canvas.rootItem()); + focusState[tree].set(true, true); + focusState[c1].set(true, true); + focusState[c2].set(false, false); + focusState.active(c1); + FVERIFY(); + } + + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + QQuickItem *tree = new TestFocusScope; + QQuickItem *c1 = new TestItem(tree); + QQuickItem *c2 = new TestItem(tree); + + FocusState focusState; + focusState << child << tree << c1 << c2; + child->setFocus(true); + tree->setFocus(true); + c1->setFocus(true); + c2->setFocus(true); + focusState[child].set(true, true); + focusState[tree].set(true, false); + focusState[c1].set(true, false); + focusState[c2].set(true, false); + focusState.active(child); + FVERIFY(); + + tree->setParentItem(canvas.rootItem()); + focusState[tree].set(false, false); + focusState[c1].set(true, false); + focusState[c2].set(false, false); + FVERIFY(); + + tree->setFocus(true); + focusState[child].set(false, false); + focusState[tree].set(true, true); + focusState[c1].set(true, true); + focusState.active(c1); + FVERIFY(); + } +} + +void tst_qquickitem::changeParent() +{ + // Parent to no parent + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + + FocusState focusState; + focusState << child; + FVERIFY(); + + child->setFocus(true); + focusState[child].set(true, true); + focusState.active(child); + FVERIFY(); + + child->setParentItem(0); + focusState[child].set(true, false); + focusState.active(0); + FVERIFY(); + } + + // Different parent, same focus scope + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + QQuickItem *child2 = new TestItem(canvas.rootItem()); + + FocusState focusState; + focusState << child << child2; + FVERIFY(); + + child->setFocus(true); + focusState[child].set(true, true); + focusState.active(child); + FVERIFY(); + + child->setParentItem(child2); + FVERIFY(); + } + + // Different parent, different focus scope + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); + QQuickItem *item = new TestItem(child); + + FocusState focusState; + focusState << child << child2 << item; + FVERIFY(); + + item->setFocus(true); + focusState[item].set(true, true); + focusState.active(item); + FVERIFY(); + + item->setParentItem(child2); + focusState[item].set(true, false); + focusState.active(0); + FVERIFY(); + } + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); + QQuickItem *item = new TestItem(child2); + + FocusState focusState; + focusState << child << child2 << item; + FVERIFY(); + + item->setFocus(true); + focusState[item].set(true, false); + focusState.active(0); + FVERIFY(); + + item->setParentItem(child); + focusState[item].set(true, true); + focusState.active(item); + FVERIFY(); + } + { + QQuickCanvas canvas; + ensureFocus(&canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == &canvas); + QQuickItem *child = new TestItem(canvas.rootItem()); + QQuickItem *child2 = new TestFocusScope(canvas.rootItem()); + QQuickItem *item = new TestItem(child2); + + FocusState focusState; + focusState << child << child2 << item; + FVERIFY(); + + child->setFocus(true); + item->setFocus(true); + focusState[child].set(true, true); + focusState[item].set(true, false); + focusState.active(child); + FVERIFY(); + + item->setParentItem(child); + focusState[item].set(false, false); + FVERIFY(); + } + +} + +void tst_qquickitem::constructor() +{ + QQuickItem *root = new QQuickItem; + QVERIFY(root->parent() == 0); + QVERIFY(root->parentItem() == 0); + + QQuickItem *child1 = new QQuickItem(root); + QVERIFY(child1->parent() == root); + QVERIFY(child1->parentItem() == root); + QCOMPARE(root->childItems().count(), 1); + QCOMPARE(root->childItems().at(0), child1); + + QQuickItem *child2 = new QQuickItem(root); + QVERIFY(child2->parent() == root); + QVERIFY(child2->parentItem() == root); + QCOMPARE(root->childItems().count(), 2); + QCOMPARE(root->childItems().at(0), child1); + QCOMPARE(root->childItems().at(1), child2); + + delete root; +} + +void tst_qquickitem::setParentItem() +{ + QQuickItem *root = new QQuickItem; + QVERIFY(root->parent() == 0); + QVERIFY(root->parentItem() == 0); + + QQuickItem *child1 = new QQuickItem; + QVERIFY(child1->parent() == 0); + QVERIFY(child1->parentItem() == 0); + + child1->setParentItem(root); + QVERIFY(child1->parent() == 0); + QVERIFY(child1->parentItem() == root); + QCOMPARE(root->childItems().count(), 1); + QCOMPARE(root->childItems().at(0), child1); + + QQuickItem *child2 = new QQuickItem; + QVERIFY(child2->parent() == 0); + QVERIFY(child2->parentItem() == 0); + child2->setParentItem(root); + QVERIFY(child2->parent() == 0); + QVERIFY(child2->parentItem() == root); + QCOMPARE(root->childItems().count(), 2); + QCOMPARE(root->childItems().at(0), child1); + QCOMPARE(root->childItems().at(1), child2); + + child1->setParentItem(0); + QVERIFY(child1->parent() == 0); + QVERIFY(child1->parentItem() == 0); + QCOMPARE(root->childItems().count(), 1); + QCOMPARE(root->childItems().at(0), child2); + + delete root; + + QVERIFY(child1->parent() == 0); + QVERIFY(child1->parentItem() == 0); + QVERIFY(child2->parent() == 0); + QVERIFY(child2->parentItem() == 0); + + delete child1; + delete child2; +} + +void tst_qquickitem::visible() +{ + QQuickItem *root = new QQuickItem; + + QQuickItem *child1 = new QQuickItem; + child1->setParentItem(root); + + QQuickItem *child2 = new QQuickItem; + child2->setParentItem(root); + + QVERIFY(child1->isVisible()); + QVERIFY(child2->isVisible()); + + root->setVisible(false); + QVERIFY(!child1->isVisible()); + QVERIFY(!child2->isVisible()); + + root->setVisible(true); + QVERIFY(child1->isVisible()); + QVERIFY(child2->isVisible()); + + child1->setVisible(false); + QVERIFY(!child1->isVisible()); + QVERIFY(child2->isVisible()); + + child2->setParentItem(child1); + QVERIFY(!child1->isVisible()); + QVERIFY(!child2->isVisible()); + + child2->setParentItem(root); + QVERIFY(!child1->isVisible()); + QVERIFY(child2->isVisible()); + + delete root; + delete child1; + delete child2; +} + +void tst_qquickitem::enabled() +{ + QQuickItem *root = new QQuickItem; + + QQuickItem *child1 = new QQuickItem; + child1->setParentItem(root); + + QQuickItem *child2 = new QQuickItem; + child2->setParentItem(root); + + QVERIFY(child1->isEnabled()); + QVERIFY(child2->isEnabled()); + + root->setEnabled(false); + QVERIFY(!child1->isEnabled()); + QVERIFY(!child2->isEnabled()); + + root->setEnabled(true); + QVERIFY(child1->isEnabled()); + QVERIFY(child2->isEnabled()); + + child1->setEnabled(false); + QVERIFY(!child1->isEnabled()); + QVERIFY(child2->isEnabled()); + + child2->setParentItem(child1); + QVERIFY(!child1->isEnabled()); + QVERIFY(!child2->isEnabled()); + + child2->setParentItem(root); + QVERIFY(!child1->isEnabled()); + QVERIFY(child2->isEnabled()); + + delete root; + delete child1; + delete child2; +} + +void tst_qquickitem::mouseGrab() +{ + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(200, 200); + canvas->show(); + + TestItem *child1 = new TestItem; + child1->setAcceptedMouseButtons(Qt::LeftButton); + child1->setSize(QSizeF(200, 100)); + child1->setParentItem(canvas->rootItem()); + + TestItem *child2 = new TestItem; + child2->setAcceptedMouseButtons(Qt::LeftButton); + child2->setY(51); + child2->setSize(QSizeF(200, 100)); + child2->setParentItem(canvas->rootItem()); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(100); + QVERIFY(canvas->mouseGrabberItem() == child1); + QTest::qWait(100); + + QCOMPARE(child1->pressCount, 1); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QVERIFY(canvas->mouseGrabberItem() == 0); + QCOMPARE(child1->releaseCount, 1); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QVERIFY(canvas->mouseGrabberItem() == child1); + QCOMPARE(child1->pressCount, 2); + child1->setEnabled(false); + QVERIFY(canvas->mouseGrabberItem() == 0); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QCOMPARE(child1->releaseCount, 1); + child1->setEnabled(true); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QVERIFY(canvas->mouseGrabberItem() == child1); + QCOMPARE(child1->pressCount, 3); + child1->setVisible(false); + QVERIFY(canvas->mouseGrabberItem() == 0); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QCOMPARE(child1->releaseCount, 1); + child1->setVisible(true); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QVERIFY(canvas->mouseGrabberItem() == child1); + QCOMPARE(child1->pressCount, 4); + child2->grabMouse(); + QVERIFY(canvas->mouseGrabberItem() == child2); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QCOMPARE(child1->releaseCount, 1); + QCOMPARE(child2->releaseCount, 1); + + child2->grabMouse(); + QVERIFY(canvas->mouseGrabberItem() == child2); + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QCOMPARE(child1->pressCount, 4); + QCOMPARE(child2->pressCount, 1); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50,50)); + QTest::qWait(50); + QCOMPARE(child1->releaseCount, 1); + QCOMPARE(child2->releaseCount, 2); + + delete child1; + delete child2; + delete canvas; +} + +void tst_qquickitem::polishOutsideAnimation() +{ + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(200, 200); + canvas->show(); + + TestPolishItem *item = new TestPolishItem(canvas->rootItem()); + item->setSize(QSizeF(200, 100)); + QTest::qWait(50); + QTRY_VERIFY(item->wasPolished); + + delete item; + delete canvas; +} + +void tst_qquickitem::wheelEvent_data() +{ + QTest::addColumn("visible"); + QTest::addColumn("enabled"); + + QTest::newRow("visible and enabled") << true << true; + QTest::newRow("visible and disabled") << true << false; + QTest::newRow("invisible and enabled") << false << true; + QTest::newRow("invisible and disabled") << false << false; +} + +void tst_qquickitem::wheelEvent() +{ + QFETCH(bool, visible); + QFETCH(bool, enabled); + + const bool shouldReceiveWheelEvents = visible && enabled; + + QQuickCanvas *canvas = new QQuickCanvas; + canvas->resize(200, 200); + canvas->show(); + + TestItem *item = new TestItem; + item->setSize(QSizeF(200, 100)); + item->setParentItem(canvas->rootItem()); + + item->setEnabled(enabled); + item->setVisible(visible); + + QWheelEvent event(QPoint(100, 50), -120, Qt::NoButton, Qt::NoModifier, Qt::Vertical); + event.setAccepted(false); + QApplication::sendEvent(canvas, &event); + + if (shouldReceiveWheelEvents) { + QVERIFY(event.isAccepted()); + QCOMPARE(item->wheelCount, 1); + } else { + QVERIFY(!event.isAccepted()); + QCOMPARE(item->wheelCount, 0); + } + + delete canvas; +} + +class HoverItem : public QQuickItem +{ +Q_OBJECT +public: + HoverItem(QQuickItem *parent = 0) + : QQuickItem(parent), hoverEnterCount(0), hoverMoveCount(0), hoverLeaveCount(0) + { } + void resetCounters() { + hoverEnterCount = 0; + hoverMoveCount = 0; + hoverLeaveCount = 0; + } + int hoverEnterCount; + int hoverMoveCount; + int hoverLeaveCount; +protected: + virtual void hoverEnterEvent(QHoverEvent *event) { + event->accept(); + ++hoverEnterCount; + } + virtual void hoverMoveEvent(QHoverEvent *event) { + event->accept(); + ++hoverMoveCount; + } + virtual void hoverLeaveEvent(QHoverEvent *event) { + event->accept(); + ++hoverLeaveCount; + } +}; + +void tst_qquickitem::hoverEvent_data() +{ + QTest::addColumn("visible"); + QTest::addColumn("enabled"); + QTest::addColumn("acceptHoverEvents"); + + QTest::newRow("visible, enabled, accept hover") << true << true << true; + QTest::newRow("visible, disabled, accept hover") << true << false << true; + QTest::newRow("invisible, enabled, accept hover") << false << true << true; + QTest::newRow("invisible, disabled, accept hover") << false << false << true; + + QTest::newRow("visible, enabled, not accept hover") << true << true << false; + QTest::newRow("visible, disabled, not accept hover") << true << false << false; + QTest::newRow("invisible, enabled, not accept hover") << false << true << false; + QTest::newRow("invisible, disabled, not accept hover") << false << false << false; +} + +// ### For some unknown reason QTest::mouseMove() isn't working correctly. +static void sendMouseMove(QObject *object, const QPoint &position) +{ + QMouseEvent moveEvent(QEvent::MouseMove, position, Qt::NoButton, Qt::NoButton, 0); + QApplication::sendEvent(object, &moveEvent); +} + +void tst_qquickitem::hoverEvent() +{ + QFETCH(bool, visible); + QFETCH(bool, enabled); + QFETCH(bool, acceptHoverEvents); + + QQuickCanvas *canvas = new QQuickCanvas(); + canvas->resize(200, 200); + canvas->show(); + + HoverItem *item = new HoverItem; + item->setSize(QSizeF(100, 100)); + item->setParentItem(canvas->rootItem()); + + item->setEnabled(enabled); + item->setVisible(visible); + item->setAcceptHoverEvents(acceptHoverEvents); + + const QPoint outside(150, 150); + const QPoint inside(50, 50); + const QPoint anotherInside(51, 51); + + sendMouseMove(canvas, outside); + item->resetCounters(); + + // Enter, then move twice inside, then leave. + sendMouseMove(canvas, inside); + sendMouseMove(canvas, anotherInside); + sendMouseMove(canvas, inside); + sendMouseMove(canvas, outside); + + const bool shouldReceiveHoverEvents = visible && enabled && acceptHoverEvents; + if (shouldReceiveHoverEvents) { + QCOMPARE(item->hoverEnterCount, 1); + QCOMPARE(item->hoverMoveCount, 2); + QCOMPARE(item->hoverLeaveCount, 1); + } else { + QCOMPARE(item->hoverEnterCount, 0); + QCOMPARE(item->hoverMoveCount, 0); + QCOMPARE(item->hoverLeaveCount, 0); + } + + delete canvas; +} + +void tst_qquickitem::hoverEventInParent() +{ + QQuickCanvas *canvas = new QQuickCanvas(); + canvas->resize(200, 200); + canvas->show(); + + HoverItem *parentItem = new HoverItem(canvas->rootItem()); + parentItem->setSize(QSizeF(200, 200)); + parentItem->setAcceptHoverEvents(true); + + HoverItem *leftItem = new HoverItem(parentItem); + leftItem->setSize(QSizeF(100, 200)); + leftItem->setAcceptHoverEvents(true); + + HoverItem *rightItem = new HoverItem(parentItem); + rightItem->setSize(QSizeF(100, 200)); + rightItem->setPos(QPointF(100, 0)); + rightItem->setAcceptHoverEvents(true); + + const QPoint insideLeft(50, 100); + const QPoint insideRight(150, 100); + + sendMouseMove(canvas, insideLeft); + parentItem->resetCounters(); + leftItem->resetCounters(); + rightItem->resetCounters(); + + sendMouseMove(canvas, insideRight); + QCOMPARE(parentItem->hoverEnterCount, 0); + QCOMPARE(parentItem->hoverLeaveCount, 0); + QCOMPARE(leftItem->hoverEnterCount, 0); + QCOMPARE(leftItem->hoverLeaveCount, 1); + QCOMPARE(rightItem->hoverEnterCount, 1); + QCOMPARE(rightItem->hoverLeaveCount, 0); + + sendMouseMove(canvas, insideLeft); + QCOMPARE(parentItem->hoverEnterCount, 0); + QCOMPARE(parentItem->hoverLeaveCount, 0); + QCOMPARE(leftItem->hoverEnterCount, 1); + QCOMPARE(leftItem->hoverLeaveCount, 1); + QCOMPARE(rightItem->hoverEnterCount, 1); + QCOMPARE(rightItem->hoverLeaveCount, 1); + + delete canvas; +} + +void tst_qquickitem::paintOrder_data() +{ + QTest::addColumn("source"); + QTest::addColumn("op"); + QTest::addColumn("param1"); + QTest::addColumn("param2"); + QTest::addColumn("expected"); + + QTest::newRow("test 1 noop") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(NoOp) << QVariant() << QVariant() + << (QStringList() << "1" << "2" << "3"); + QTest::newRow("test 1 add") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(Append) << QVariant("new") << QVariant() + << (QStringList() << "1" << "2" << "3" << "new"); + QTest::newRow("test 1 remove") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(Remove) << QVariant(1) << QVariant() + << (QStringList() << "1" << "3"); + QTest::newRow("test 1 stack before") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(StackBefore) << QVariant(2) << QVariant(1) + << (QStringList() << "1" << "3" << "2"); + QTest::newRow("test 1 stack after") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(StackAfter) << QVariant(0) << QVariant(1) + << (QStringList() << "2" << "1" << "3"); + QTest::newRow("test 1 set z") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(SetZ) << QVariant(1) << QVariant(qreal(1.)) + << (QStringList() << "1" << "3" << "2"); + + QTest::newRow("test 2 noop") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(NoOp) << QVariant() << QVariant() + << (QStringList() << "1" << "3" << "2"); + QTest::newRow("test 2 add") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(Append) << QVariant("new") << QVariant() + << (QStringList() << "1" << "3" << "new" << "2"); + QTest::newRow("test 2 remove 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(Remove) << QVariant(1) << QVariant() + << (QStringList() << "1" << "3"); + QTest::newRow("test 2 remove 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(Remove) << QVariant(2) << QVariant() + << (QStringList() << "1" << "2"); + QTest::newRow("test 2 stack before 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(StackBefore) << QVariant(1) << QVariant(0) + << (QStringList() << "1" << "3" << "2"); + QTest::newRow("test 2 stack before 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(StackBefore) << QVariant(2) << QVariant(0) + << (QStringList() << "3" << "1" << "2"); + QTest::newRow("test 2 stack after 1") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(StackAfter) << QVariant(0) << QVariant(1) + << (QStringList() << "1" << "3" << "2"); + QTest::newRow("test 2 stack after 2") << QUrl::fromLocalFile(TESTDATA("order.2.qml")) + << int(StackAfter) << QVariant(0) << QVariant(2) + << (QStringList() << "3" << "1" << "2"); + QTest::newRow("test 1 set z") << QUrl::fromLocalFile(TESTDATA("order.1.qml")) + << int(SetZ) << QVariant(2) << QVariant(qreal(2.)) + << (QStringList() << "1" << "2" << "3"); +} + +void tst_qquickitem::paintOrder() +{ + QFETCH(QUrl, source); + QFETCH(int, op); + QFETCH(QVariant, param1); + QFETCH(QVariant, param2); + QFETCH(QStringList, expected); + + QQuickView view; + view.setSource(source); + + QQuickItem *root = qobject_cast(view.rootObject()); + QVERIFY(root); + + switch (op) { + case Append: { + QQuickItem *item = new QQuickItem(root); + item->setObjectName(param1.toString()); + } + break; + case Remove: { + QQuickItem *item = root->childItems().at(param1.toInt()); + delete item; + } + break; + case StackBefore: { + QQuickItem *item1 = root->childItems().at(param1.toInt()); + QQuickItem *item2 = root->childItems().at(param2.toInt()); + item1->stackBefore(item2); + } + break; + case StackAfter: { + QQuickItem *item1 = root->childItems().at(param1.toInt()); + QQuickItem *item2 = root->childItems().at(param2.toInt()); + item1->stackAfter(item2); + } + break; + case SetZ: { + QQuickItem *item = root->childItems().at(param1.toInt()); + item->setZ(param2.toReal()); + } + break; + default: + break; + } + + QList list = QQuickItemPrivate::get(root)->paintOrderChildItems(); + + QStringList items; + for (int i = 0; i < list.count(); ++i) + items << list.at(i)->objectName(); + + QCOMPARE(items, expected); +} + + +QTEST_MAIN(tst_qquickitem) + +#include "tst_qquickitem.moc" diff --git a/tests/auto/qtquick2/qquickitem2/data/childrenProperty.qml b/tests/auto/qtquick2/qquickitem2/data/childrenProperty.qml new file mode 100644 index 0000000000..85ddbc1446 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/childrenProperty.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + id: root + + property bool test1: root.children.length == 3 + property bool test2: root.children[0] == item1 + property bool test3: root.children[1] == item2 + property bool test4: root.children[2] == item3 + property bool test5: root.children[3] == null + + children: [ Item { id: item1 }, Item { id: item2 }, Item { id: item3 } ] +} + diff --git a/tests/auto/qtquick2/qquickitem2/data/childrenRect.qml b/tests/auto/qtquick2/qquickitem2/data/childrenRect.qml new file mode 100644 index 0000000000..ebc57aefbe --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/childrenRect.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + property int childCount: 0; + + Item { + objectName: "testItem" + width: childrenRect.width + height: childrenRect.height + + Repeater { + id: repeater + model: childCount + delegate: Rectangle { + x: index*10 + y: index*20 + width: 10 + height: 20 + + color: "red" + } + } + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/childrenRectBug.qml b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug.qml new file mode 100644 index 0000000000..86a4f19c5c --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 200 + + Item { + objectName: "theItem" + anchors.centerIn: parent + width: childrenRect.width + height: childrenRect.height + Rectangle { + id: text1 + anchors.verticalCenter: parent.verticalCenter + width: 100; height: 100; color: "green" + } + Rectangle { + anchors.left: text1.right + anchors.verticalCenter: parent.verticalCenter + width: 100; height: 100; color: "green" + } + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/childrenRectBug2.qml b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug2.qml new file mode 100644 index 0000000000..6e80ed28af --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug2.qml @@ -0,0 +1,53 @@ +import QtQuick 2.0 + +Rectangle { + width:360; + height: 200 + + Item { + objectName: "theItem" + anchors.centerIn: parent + width: childrenRect.width + height: childrenRect.height + Rectangle { + id: header1 + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: 100; height: 50 + color: "green" + } + Rectangle { + id: text1 + anchors.top: header1.bottom + anchors.topMargin: 10 + anchors.horizontalCenter: parent.horizontalCenter + width: 100; height: 50 + color: "blue" + } + } + + states: [ + State { + name: "row" + AnchorChanges { + target: header1 + anchors.horizontalCenter: undefined + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.top: undefined + } + AnchorChanges { + target: text1 + anchors.horizontalCenter: undefined + anchors.verticalCenter: parent.verticalCenter + anchors.top: undefined + anchors.left: header1.right + } + PropertyChanges { + target: text1 + anchors.leftMargin: 10 + anchors.topMargin: 0 + } + } + ] +} diff --git a/tests/auto/qtquick2/qquickitem2/data/childrenRectBug3.qml b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug3.qml new file mode 100644 index 0000000000..518e76509e --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/childrenRectBug3.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Rectangle { + width: 300 + height: 300 + + Rectangle { + height: childrenRect.height + + Repeater { + model: 1 + Rectangle { } + } + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/implicitsize.qml b/tests/auto/qtquick2/qquickitem2/data/implicitsize.qml new file mode 100644 index 0000000000..cc6aaf7d60 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/implicitsize.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Item { + implicitWidth: 200 + implicitHeight: 100 + + width: 80 + height: 60 + + function resetSize() { + width = undefined + height = undefined + } + + function changeImplicit() { + implicitWidth = 150 + implicitHeight = 80 + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/keynavigationtest.qml b/tests/auto/qtquick2/qquickitem2/data/keynavigationtest.qml new file mode 100644 index 0000000000..aacb621fb0 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/keynavigationtest.qml @@ -0,0 +1,87 @@ +import QtQuick 2.0 + +Grid { + columns: 2 + width: 100; height: 100 + function verify() { + if (item1.KeyNavigation.right != item2) + return false; + if (item1.KeyNavigation.down != item3) + return false; + if (item1.KeyNavigation.tab != item2) + return false; + if (item1.KeyNavigation.backtab != item4) + return false; + + if (item2.KeyNavigation.left != item1) + return false; + if (item2.KeyNavigation.down != item4) + return false; + if (item2.KeyNavigation.tab != item3) + return false; + if (item2.KeyNavigation.backtab != item1) + return false; + + if (item3.KeyNavigation.right != item4) + return false; + if (item3.KeyNavigation.up != item1) + return false; + if (item3.KeyNavigation.tab != item4) + return false; + if (item3.KeyNavigation.backtab != item2) + return false; + + if (item4.KeyNavigation.left != item3) + return false; + if (item4.KeyNavigation.up != item2) + return false; + if (item4.KeyNavigation.tab != item1) + return false; + if (item4.KeyNavigation.backtab != item3) + return false; + + return true; + } + + Rectangle { + id: item1 + objectName: "item1" + focus: true + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.right: item2 + KeyNavigation.down: item3 + KeyNavigation.tab: item2 + KeyNavigation.backtab: item4 + } + Rectangle { + id: item2 + objectName: "item2" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.left: item1 + KeyNavigation.down: item4 + KeyNavigation.tab: item3 + KeyNavigation.backtab: item1 + } + Rectangle { + id: item3 + objectName: "item3" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.right: item4 + KeyNavigation.up: item1 + KeyNavigation.tab: item4 + KeyNavigation.backtab: item2 + } + Rectangle { + id: item4 + objectName: "item4" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.left: item3 + KeyNavigation.up: item2 + KeyNavigation.tab: item1 + KeyNavigation.backtab: item3 + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/keynavigationtest_implicit.qml b/tests/auto/qtquick2/qquickitem2/data/keynavigationtest_implicit.qml new file mode 100644 index 0000000000..92d4ae23de --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/keynavigationtest_implicit.qml @@ -0,0 +1,68 @@ +import QtQuick 2.0 + +Grid { + columns: 2 + width: 100; height: 100 + function verify() { + if (item1.KeyNavigation.tab != item2) + return false; + if (item1.KeyNavigation.backtab != item4) + return false; + + if (item2.KeyNavigation.left != item1) + return false; + if (item2.KeyNavigation.down != item4) + return false; + if (item2.KeyNavigation.tab != item3) + return false; + if (item2.KeyNavigation.backtab != item1) + return false; + + if (item3.KeyNavigation.right != item4) + return false; + if (item3.KeyNavigation.up != item1) + return false; + if (item3.KeyNavigation.tab != item4) + return false; + if (item3.KeyNavigation.backtab != item2) + return false; + + return true; + } + + Rectangle { + id: item1 + objectName: "item1" + focus: true + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.tab: item2 + KeyNavigation.backtab: item4 + } + Rectangle { + id: item2 + objectName: "item2" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.left: item1 + KeyNavigation.down: item4 + KeyNavigation.tab: item3 + KeyNavigation.backtab: item1 + } + Rectangle { + id: item3 + objectName: "item3" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + KeyNavigation.right: item4 + KeyNavigation.up: item1 + KeyNavigation.tab: item4 + KeyNavigation.backtab: item2 + } + Rectangle { + id: item4 + objectName: "item4" + width: 50; height: 50 + color: focus ? "red" : "lightgray" + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/keyspriority.qml b/tests/auto/qtquick2/qquickitem2/data/keyspriority.qml new file mode 100644 index 0000000000..114cf0488a --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/keyspriority.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 +import Test 1.0 + +KeyTestItem { + focus: true + Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) + Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } + Keys.priority: keysTestObject.processLast ? Keys.AfterItem : Keys.BeforeItem +} diff --git a/tests/auto/qtquick2/qquickitem2/data/keystest.qml b/tests/auto/qtquick2/qquickitem2/data/keystest.qml new file mode 100644 index 0000000000..c70e0061f5 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/keystest.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Item { + focus: true + + property bool isEnabled: Keys.enabled + + Keys.onPressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) + Keys.onReleased: { keysTestObject.keyRelease(event.key, event.text, event.modifiers); event.accepted = true; } + Keys.onReturnPressed: keysTestObject.keyPress(event.key, "Return", event.modifiers) + Keys.onDigit0Pressed: keysTestObject.keyPress(event.key, event.text, event.modifiers) + Keys.onDigit9Pressed: { event.accepted = false; keysTestObject.keyPress(event.key, event.text, event.modifiers) } + Keys.onTabPressed: keysTestObject.keyPress(event.key, "Tab", event.modifiers) + Keys.onBacktabPressed: keysTestObject.keyPress(event.key, "Backtab", event.modifiers) + Keys.forwardTo: [ item2 ] + Keys.enabled: enableKeyHanding + + Item { + id: item2 + visible: forwardeeVisible + Keys.onPressed: keysTestObject.forwardedKey(event.key) + Keys.onReleased: keysTestObject.forwardedKey(event.key) + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/layoutmirroring.qml b/tests/auto/qtquick2/qquickitem2/data/layoutmirroring.qml new file mode 100644 index 0000000000..036819740c --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/layoutmirroring.qml @@ -0,0 +1,54 @@ +import QtQuick 2.0 + +Item { + property bool childrenInherit: true + Item { + objectName: "mirrored1" + LayoutMirroring.enabled: true + LayoutMirroring.childrenInherit: parent.childrenInherit + Item { + Item { + objectName: "notMirrored1" + LayoutMirroring.enabled: false + Item { + objectName: "inheritedMirror1" + } + } + Item { + objectName: "inheritedMirror2" + } + } + } + Item { + objectName: "mirrored2" + LayoutMirroring.enabled: true + LayoutMirroring.childrenInherit: false + Item { + objectName: "notMirrored2" + } + } + Item { + LayoutMirroring.enabled: true + LayoutMirroring.childrenInherit: true + Loader { + id: loader + } + } + states: State { + name: "newContent" + PropertyChanges { + target: loader + sourceComponent: component + } + } + Component { + id: component + Item { + objectName: "notMirrored3" + LayoutMirroring.enabled: false + Item { + objectName: "inheritedMirror3" + } + } + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/mapCoordinates.qml b/tests/auto/qtquick2/qquickitem2/data/mapCoordinates.qml new file mode 100644 index 0000000000..566cb220ff --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/mapCoordinates.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: root; objectName: "root" + width: 200; height: 200 + + Item { id: itemA; objectName: "itemA"; x: 50; y: 50 } + + Item { + x: 50; y: 50 + Item { id: itemB; objectName: "itemB"; x: 100; y: 100 } + } + + function mapAToB(x, y) { + var pos = itemA.mapToItem(itemB, x, y) + return Qt.point(pos.x, pos.y) + } + + function mapAFromB(x, y) { + var pos = itemA.mapFromItem(itemB, x, y) + return Qt.point(pos.x, pos.y) + } + + function mapAToNull(x, y) { + var pos = itemA.mapToItem(null, x, y) + return Qt.point(pos.x, pos.y) + } + + function mapAFromNull(x, y) { + var pos = itemA.mapFromItem(null, x, y) + return Qt.point(pos.x, pos.y) + } + + function checkMapAToInvalid(x, y) { + var pos = itemA.mapToItem(1122, x, y) + return pos == undefined; + } + + function checkMapAFromInvalid(x, y) { + var pos = itemA.mapFromItem(1122, x, y) + return pos == undefined; + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/propertychanges.qml b/tests/auto/qtquick2/qquickitem2/data/propertychanges.qml new file mode 100644 index 0000000000..3fa5ea9c23 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/propertychanges.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Item { + Item { + objectName: "item" + } + Item { + objectName: "parentItem" + } +} diff --git a/tests/auto/qtquick2/qquickitem2/data/qtbug_16871.qml b/tests/auto/qtquick2/qquickitem2/data/qtbug_16871.qml new file mode 100644 index 0000000000..f1e7377730 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/qtbug_16871.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + children: [ 10 ] +} diff --git a/tests/auto/qtquick2/qquickitem2/data/resourcesProperty.qml b/tests/auto/qtquick2/qquickitem2/data/resourcesProperty.qml new file mode 100644 index 0000000000..b8f18bb375 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/resourcesProperty.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Item { + id: root + + property bool test1 + property bool test2 + property bool test3 + property bool test4 + property bool test5 + + Component.onCompleted: { + test1 = (root.resources.length >= 3) + test2 = root.resources[0] == item1 + test3 = root.resources[1] == item2 + test4 = root.resources[2] == item3 + test5 = root.resources[10] == null + } + + resources: [ Item { id: item1 }, Item { id: item2 }, Item { id: item3 } ] +} diff --git a/tests/auto/qtquick2/qquickitem2/data/transformCrash.qml b/tests/auto/qtquick2/qquickitem2/data/transformCrash.qml new file mode 100644 index 0000000000..284e85f0e0 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/data/transformCrash.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Item { + id: wrapper + width: 200 + height: 200 + + QtObject { + id: object + } + + Component.onCompleted: wrapper.transform = object +} diff --git a/tests/auto/qtquick2/qquickitem2/qquickitem2.pro b/tests/auto/qtquick2/qquickitem2/qquickitem2.pro new file mode 100644 index 0000000000..2a1d63633c --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/qquickitem2.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickitem2 +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickitem.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qquickitem2/tst_qquickitem.cpp b/tests/auto/qtquick2/qquickitem2/tst_qquickitem.cpp new file mode 100644 index 0000000000..f04b9bac36 --- /dev/null +++ b/tests/auto/qtquick2/qquickitem2/tst_qquickitem.cpp @@ -0,0 +1,1254 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_QQuickItem : public QObject +{ + Q_OBJECT +public: + tst_QQuickItem(); + +private slots: + void initTestCase(); + void keys(); + void keysProcessingOrder(); + void keyNavigation(); + void keyNavigation_RightToLeft(); + void keyNavigation_skipNotVisible(); + void keyNavigation_implicitSetting(); + void layoutMirroring(); + void layoutMirroringIllegalParent(); + void smooth(); + void clip(); + void mapCoordinates(); + void mapCoordinates_data(); + void propertyChanges(); + void transforms(); + void transforms_data(); + void childrenRect(); + void childrenRectBug(); + void childrenRectBug2(); + void childrenRectBug3(); + + void childrenProperty(); + void resourcesProperty(); + + void transformCrash(); + void implicitSize(); + void qtbug_16871(); +private: + QDeclarativeEngine engine; +}; + +template +T *findItem(QQuickItem *parent, const QString &objectName) +{ + if (!parent) + return 0; + + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->QQuickItem::children().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) + return static_cast(item); + item = findItem(item, objectName); + if (item) + return static_cast(item); + } + + return 0; +} + +class KeysTestObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(bool processLast READ processLast NOTIFY processLastChanged) + +public: + KeysTestObject() : mKey(0), mModifiers(0), mForwardedKey(0), mLast(false) {} + + void reset() { + mKey = 0; + mText = QString(); + mModifiers = 0; + mForwardedKey = 0; + } + + bool processLast() const { return mLast; } + void setProcessLast(bool b) { + if (b != mLast) { + mLast = b; + emit processLastChanged(); + } + } + +public slots: + void keyPress(int key, QString text, int modifiers) { + mKey = key; + mText = text; + mModifiers = modifiers; + } + void keyRelease(int key, QString text, int modifiers) { + mKey = key; + mText = text; + mModifiers = modifiers; + } + void forwardedKey(int key) { + mForwardedKey = key; + } + +signals: + void processLastChanged(); + +public: + int mKey; + QString mText; + int mModifiers; + int mForwardedKey; + bool mLast; + +private: +}; + +class KeyTestItem : public QQuickItem +{ + Q_OBJECT +public: + KeyTestItem(QQuickItem *parent=0) : QQuickItem(parent), mKey(0) {} + +protected: + void keyPressEvent(QKeyEvent *e) { + mKey = e->key(); + + if (e->key() == Qt::Key_A) + e->accept(); + else + e->ignore(); + } + + void keyReleaseEvent(QKeyEvent *e) { + if (e->key() == Qt::Key_B) + e->accept(); + else + e->ignore(); + } + +public: + int mKey; +}; + +QML_DECLARE_TYPE(KeyTestItem); + + +tst_QQuickItem::tst_QQuickItem() +{ +} + +void tst_QQuickItem::initTestCase() +{ + qmlRegisterType("Test",1,0,"KeyTestItem"); +} + +void tst_QQuickItem::keys() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + KeysTestObject *testObject = new KeysTestObject; + canvas->rootContext()->setContextProperty("keysTestObject", testObject); + + canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); + canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(true)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keystest.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QVERIFY(canvas->rootObject()); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); + + QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_A)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); + QCOMPARE(testObject->mText, QLatin1String("A")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(!key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyRelease, Qt::Key_A, Qt::ShiftModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_A)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_A)); + QCOMPARE(testObject->mText, QLatin1String("A")); + QVERIFY(testObject->mModifiers == Qt::ShiftModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_Return)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Return)); + QCOMPARE(testObject->mText, QLatin1String("Return")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_0, Qt::NoModifier, "0", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_0)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_0)); + QCOMPARE(testObject->mText, QLatin1String("0")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_9, Qt::NoModifier, "9", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_9)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_9)); + QCOMPARE(testObject->mText, QLatin1String("9")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(!key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_Tab)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Tab)); + QCOMPARE(testObject->mText, QLatin1String("Tab")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_Backtab)); + QCOMPARE(testObject->mForwardedKey, int(Qt::Key_Backtab)); + QCOMPARE(testObject->mText, QLatin1String("Backtab")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + canvas->rootContext()->setContextProperty("forwardeeVisible", QVariant(false)); + key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_A)); + QCOMPARE(testObject->mForwardedKey, 0); + QCOMPARE(testObject->mText, QLatin1String("A")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(!key.isAccepted()); + + testObject->reset(); + + canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(false)); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), false); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, 0); + QVERIFY(!key.isAccepted()); + + canvas->rootContext()->setContextProperty("enableKeyHanding", QVariant(true)); + QCOMPARE(canvas->rootObject()->property("isEnabled").toBool(), true); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_Return)); + QVERIFY(key.isAccepted()); + + delete canvas; + delete testObject; +} + +void tst_QQuickItem::keysProcessingOrder() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + KeysTestObject *testObject = new KeysTestObject; + canvas->rootContext()->setContextProperty("keysTestObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keyspriority.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + KeyTestItem *testItem = qobject_cast(canvas->rootObject()); + QVERIFY(testItem); + + QKeyEvent key(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_A)); + QCOMPARE(testObject->mText, QLatin1String("A")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + testObject->setProcessLast(true); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_A, Qt::NoModifier, "A", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, 0); + QVERIFY(key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier, "B", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, int(Qt::Key_B)); + QCOMPARE(testObject->mText, QLatin1String("B")); + QVERIFY(testObject->mModifiers == Qt::NoModifier); + QVERIFY(!key.isAccepted()); + + testObject->reset(); + + key = QKeyEvent(QEvent::KeyRelease, Qt::Key_B, Qt::NoModifier, "B", false, 1); + QApplication::sendEvent(canvas, &key); + QCOMPARE(testObject->mKey, 0); + QVERIFY(key.isAccepted()); + + delete canvas; + delete testObject; +} + +QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString) +{ + QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); + QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); + return itemPrivate; +} + +QVariant childProperty(QQuickItem *rootItem, const char * itemString, const char * property) +{ + QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); + return item->property(property); +} + +bool anchorsMirrored(QQuickItem *rootItem, const char * itemString) +{ + QQuickItem *item = findItem(rootItem, QString(QLatin1String(itemString))); + QQuickItemPrivate* itemPrivate = QQuickItemPrivate::get(item); + return itemPrivate->anchors()->mirrored(); +} + +void tst_QQuickItem::layoutMirroring() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("layoutmirroring.qml"))); + canvas->show(); + + QQuickItem *rootItem = qobject_cast(canvas->rootObject()); + QVERIFY(rootItem); + QQuickItemPrivate *rootPrivate = QQuickItemPrivate::get(rootItem); + QVERIFY(rootPrivate); + + QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "mirrored2")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "notMirrored2")->effectiveLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true); + + QCOMPARE(anchorsMirrored(rootItem, "mirrored1"), true); + QCOMPARE(anchorsMirrored(rootItem, "mirrored2"), true); + QCOMPARE(anchorsMirrored(rootItem, "notMirrored1"), false); + QCOMPARE(anchorsMirrored(rootItem, "notMirrored2"), false); + QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror1"), true); + QCOMPARE(anchorsMirrored(rootItem, "inheritedMirror2"), true); + + QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritedLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritedLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true); + + QCOMPARE(childPrivate(rootItem, "mirrored1")->isMirrorImplicit, false); + QCOMPARE(childPrivate(rootItem, "mirrored2")->isMirrorImplicit, false); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->isMirrorImplicit, false); + QCOMPARE(childPrivate(rootItem, "notMirrored2")->isMirrorImplicit, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->isMirrorImplicit, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->isMirrorImplicit, true); + + QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromParent, true); + QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromParent, false); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromParent, true); + QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromParent, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromParent, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromParent, true); + + QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritMirrorFromItem, true); + QCOMPARE(childPrivate(rootItem, "mirrored2")->inheritMirrorFromItem, false); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritMirrorFromItem, false); + QCOMPARE(childPrivate(rootItem, "notMirrored2")->inheritMirrorFromItem, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritMirrorFromItem, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritMirrorFromItem, false); + + // load dynamic content using Loader that needs to inherit mirroring + rootItem->setProperty("state", "newContent"); + QCOMPARE(childPrivate(rootItem, "notMirrored3")->effectiveLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->effectiveLayoutMirror, true); + + QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritedLayoutMirror, true); + + QCOMPARE(childPrivate(rootItem, "notMirrored3")->isMirrorImplicit, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->isMirrorImplicit, true); + + QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromParent, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror3")->inheritMirrorFromParent, true); + + QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false); + QCOMPARE(childPrivate(rootItem, "notMirrored3")->inheritMirrorFromItem, false); + + // disable inheritance + rootItem->setProperty("childrenInherit", false); + + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); + + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, false); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, false); + + // re-enable inheritance + rootItem->setProperty("childrenInherit", true); + + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "mirrored1")->effectiveLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->effectiveLayoutMirror, false); + + QCOMPARE(childPrivate(rootItem, "inheritedMirror1")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "inheritedMirror2")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "mirrored1")->inheritedLayoutMirror, true); + QCOMPARE(childPrivate(rootItem, "notMirrored1")->inheritedLayoutMirror, true); + + // + // dynamic parenting + // + QQuickItem *parentItem1 = new QQuickItem(); + QQuickItemPrivate::get(parentItem1)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true + QQuickItemPrivate::get(parentItem1)->isMirrorImplicit = false; + QQuickItemPrivate::get(parentItem1)->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true + QQuickItemPrivate::get(parentItem1)->resolveLayoutMirror(); + + // inherit in constructor + QQuickItem *childItem1 = new QQuickItem(parentItem1); + QCOMPARE(QQuickItemPrivate::get(childItem1)->effectiveLayoutMirror, true); + QCOMPARE(QQuickItemPrivate::get(childItem1)->inheritMirrorFromParent, true); + + // inherit through a parent change + QQuickItem *childItem2 = new QQuickItem(); + QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); + QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); + childItem2->setParentItem(parentItem1); + QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, true); + QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, true); + + // stop inherting through a parent change + QQuickItem *parentItem2 = new QQuickItem(); + QQuickItemPrivate::get(parentItem2)->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true + QQuickItemPrivate::get(parentItem2)->resolveLayoutMirror(); + childItem2->setParentItem(parentItem2); + QCOMPARE(QQuickItemPrivate::get(childItem2)->effectiveLayoutMirror, false); + QCOMPARE(QQuickItemPrivate::get(childItem2)->inheritMirrorFromParent, false); + + delete parentItem1; + delete parentItem2; +} + +void tst_QQuickItem::layoutMirroringIllegalParent() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; QtObject { LayoutMirroring.enabled: true; LayoutMirroring.childrenInherit: true }", QUrl::fromLocalFile("")); + QTest::ignoreMessage(QtWarningMsg, "file::1:21: QML QtObject: LayoutDirection attached property only works with Items"); + QObject *object = component.create(); + QVERIFY(object != 0); +} + +void tst_QQuickItem::keyNavigation() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QQuickItem *item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + QVariant result; + QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", + Q_RETURN_ARG(QVariant, result))); + QVERIFY(result.toBool()); + + // right + QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // down + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // left + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // up + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete canvas; +} + +void tst_QQuickItem::keyNavigation_RightToLeft() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QQuickItem *rootItem = qobject_cast(canvas->rootObject()); + QVERIFY(rootItem); + QQuickItemPrivate* rootItemPrivate = QQuickItemPrivate::get(rootItem); + + rootItemPrivate->effectiveLayoutMirror = true; // LayoutMirroring.mirror: true + rootItemPrivate->isMirrorImplicit = false; + rootItemPrivate->inheritMirrorFromItem = true; // LayoutMirroring.inherit: true + rootItemPrivate->resolveLayoutMirror(); + + QEvent wa(QEvent::WindowActivate); + QApplication::sendEvent(canvas, &wa); + QFocusEvent fe(QEvent::FocusIn); + QApplication::sendEvent(canvas, &fe); + + QQuickItem *item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + QVariant result; + QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", + Q_RETURN_ARG(QVariant, result))); + QVERIFY(result.toBool()); + + // right + QKeyEvent key(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // left + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete canvas; +} + +void tst_QQuickItem::keyNavigation_skipNotVisible() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QQuickItem *item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // Set item 2 to not visible + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + item->setVisible(false); + QVERIFY(!item->isVisible()); + + // right + QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + //Set item 3 to not visible + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + item->setVisible(false); + QVERIFY(!item->isVisible()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete canvas; +} + +void tst_QQuickItem::keyNavigation_implicitSetting() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("keynavigationtest_implicit.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QEvent wa(QEvent::WindowActivate); + QApplication::sendEvent(canvas, &wa); + QFocusEvent fe(QEvent::FocusIn); + QApplication::sendEvent(canvas, &fe); + + QQuickItem *item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + QVariant result; + QVERIFY(QMetaObject::invokeMethod(canvas->rootObject(), "verify", + Q_RETURN_ARG(QVariant, result))); + QVERIFY(result.toBool()); + + // right + QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // back to item1 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // down + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // move to item4 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // left + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // back to item4 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // up + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Up, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item2"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // back to item4 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Down, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // tab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item1"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // back to item4 + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item4"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + // backtab + key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1); + QApplication::sendEvent(canvas, &key); + QVERIFY(key.isAccepted()); + + item = findItem(canvas->rootObject(), "item3"); + QVERIFY(item); + QVERIFY(item->hasActiveFocus()); + + delete canvas; +} + +void tst_QQuickItem::smooth() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0; Item { smooth: false; }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QSignalSpy spy(item, SIGNAL(smoothChanged(bool))); + + QVERIFY(item); + QVERIFY(!item->smooth()); + + item->setSmooth(true); + QVERIFY(item->smooth()); + QCOMPARE(spy.count(),1); + QList arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + + item->setSmooth(true); + QCOMPARE(spy.count(),1); + + item->setSmooth(false); + QVERIFY(!item->smooth()); + QCOMPARE(spy.count(),2); + item->setSmooth(false); + QCOMPARE(spy.count(),2); + + delete item; +} + +void tst_QQuickItem::clip() +{ + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0\nItem { clip: false\n }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QSignalSpy spy(item, SIGNAL(clipChanged(bool))); + + QVERIFY(item); + QVERIFY(!item->clip()); + + item->setClip(true); + QVERIFY(item->clip()); + + QList arguments = spy.first(); + QVERIFY(arguments.count() == 1); + QVERIFY(arguments.at(0).toBool() == true); + + QCOMPARE(spy.count(),1); + item->setClip(true); + QCOMPARE(spy.count(),1); + + item->setClip(false); + QVERIFY(!item->clip()); + QCOMPARE(spy.count(),2); + item->setClip(false); + QCOMPARE(spy.count(),2); + + delete item; +} + +void tst_QQuickItem::mapCoordinates() +{ + QFETCH(int, x); + QFETCH(int, y); + + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(300, 300)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root != 0); + QQuickItem *a = findItem(canvas->rootObject(), "itemA"); + QVERIFY(a != 0); + QQuickItem *b = findItem(canvas->rootObject(), "itemB"); + QVERIFY(b != 0); + + QVariant result; + + QVERIFY(QMetaObject::invokeMethod(root, "mapAToB", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QCOMPARE(result.value(), qobject_cast(a)->mapToItem(b, QPointF(x, y))); + + QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QCOMPARE(result.value(), qobject_cast(a)->mapFromItem(b, QPointF(x, y))); + + QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QCOMPARE(result.value(), qobject_cast(a)->mapToScene(QPointF(x, y))); + + QVERIFY(QMetaObject::invokeMethod(root, "mapAFromNull", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QCOMPARE(result.value(), qobject_cast(a)->mapFromScene(QPointF(x, y))); + + QString warning1 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapToItem() given argument \"1122\" which is neither null nor an Item"; + QString warning2 = QUrl::fromLocalFile(TESTDATA("mapCoordinates.qml")).toString() + ":48:5: QML Item: mapFromItem() given argument \"1122\" which is neither null nor an Item"; + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning1)); + QVERIFY(QMetaObject::invokeMethod(root, "checkMapAToInvalid", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QVERIFY(result.toBool()); + + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning2)); + QVERIFY(QMetaObject::invokeMethod(root, "checkMapAFromInvalid", + Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y))); + QVERIFY(result.toBool()); + + delete canvas; +} + +void tst_QQuickItem::mapCoordinates_data() +{ + QTest::addColumn("x"); + QTest::addColumn("y"); + + for (int i=-20; i<=20; i+=10) + QTest::newRow(QTest::toString(i)) << i << i; +} + +void tst_QQuickItem::transforms_data() +{ + QTest::addColumn("qml"); + QTest::addColumn("transform"); + QTest::newRow("translate") << QByteArray("Translate { x: 10; y: 20 }") + << QTransform(1,0,0,0,1,0,10,20,1); + QTest::newRow("rotation") << QByteArray("Rotation { angle: 90 }") + << QTransform(0,1,0,-1,0,0,0,0,1); + QTest::newRow("scale") << QByteArray("Scale { xScale: 1.5; yScale: -2 }") + << QTransform(1.5,0,0,0,-2,0,0,0,1); + QTest::newRow("sequence") << QByteArray("[ Translate { x: 10; y: 20 }, Scale { xScale: 1.5; yScale: -2 } ]") + << QTransform(1,0,0,0,1,0,10,20,1) * QTransform(1.5,0,0,0,-2,0,0,0,1); +} + +void tst_QQuickItem::transforms() +{ + QFETCH(QByteArray, qml); + QFETCH(QTransform, transform); + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0\nItem { transform: "+qml+"}", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(item->itemTransform(0,0), transform); +} + +void tst_QQuickItem::childrenProperty() +{ + QDeclarativeComponent component(&engine, TESTDATA("childrenProperty.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test1").toBool(), true); + QCOMPARE(o->property("test2").toBool(), true); + QCOMPARE(o->property("test3").toBool(), true); + QCOMPARE(o->property("test4").toBool(), true); + QCOMPARE(o->property("test5").toBool(), true); + delete o; +} + +void tst_QQuickItem::resourcesProperty() +{ + QDeclarativeComponent component(&engine, TESTDATA("resourcesProperty.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test1").toBool(), true); + QCOMPARE(o->property("test2").toBool(), true); + QCOMPARE(o->property("test3").toBool(), true); + QCOMPARE(o->property("test4").toBool(), true); + QCOMPARE(o->property("test5").toBool(), true); + delete o; +} + +void tst_QQuickItem::propertyChanges() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(300, 300)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(QGuiApplication::focusWindow() == canvas); + + QQuickItem *item = findItem(canvas->rootObject(), "item"); + QQuickItem *parentItem = findItem(canvas->rootObject(), "parentItem"); + + QVERIFY(item); + QVERIFY(parentItem); + + QSignalSpy parentSpy(item, SIGNAL(parentChanged(QQuickItem *))); + QSignalSpy widthSpy(item, SIGNAL(widthChanged())); + QSignalSpy heightSpy(item, SIGNAL(heightChanged())); + QSignalSpy baselineOffsetSpy(item, SIGNAL(baselineOffsetChanged(qreal))); + QSignalSpy childrenRectSpy(parentItem, SIGNAL(childrenRectChanged(QRectF))); + QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); + QSignalSpy wantsFocusSpy(parentItem, SIGNAL(activeFocusChanged(bool))); + QSignalSpy childrenChangedSpy(parentItem, SIGNAL(childrenChanged())); + QSignalSpy xSpy(item, SIGNAL(xChanged())); + QSignalSpy ySpy(item, SIGNAL(yChanged())); + + item->setParentItem(parentItem); + item->setWidth(100.0); + item->setHeight(200.0); + item->setFocus(true); + item->setBaselineOffset(10.0); + + QCOMPARE(item->parentItem(), parentItem); + QCOMPARE(parentSpy.count(),1); + QList parentArguments = parentSpy.first(); + QVERIFY(parentArguments.count() == 1); + QCOMPARE(item->parentItem(), qvariant_cast(parentArguments.at(0))); + QCOMPARE(childrenChangedSpy.count(),1); + + item->setParentItem(parentItem); + QCOMPARE(childrenChangedSpy.count(),1); + + QCOMPARE(item->width(), 100.0); + QCOMPARE(widthSpy.count(),1); + + QCOMPARE(item->height(), 200.0); + QCOMPARE(heightSpy.count(),1); + + QCOMPARE(item->baselineOffset(), 10.0); + QCOMPARE(baselineOffsetSpy.count(),1); + QList baselineOffsetArguments = baselineOffsetSpy.first(); + QVERIFY(baselineOffsetArguments.count() == 1); + QCOMPARE(item->baselineOffset(), baselineOffsetArguments.at(0).toReal()); + + QCOMPARE(parentItem->childrenRect(), QRectF(0.0,0.0,100.0,200.0)); + QCOMPARE(childrenRectSpy.count(),1); + QList childrenRectArguments = childrenRectSpy.at(0); + QVERIFY(childrenRectArguments.count() == 1); + QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF()); + + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(focusSpy.count(),1); + QList focusArguments = focusSpy.first(); + QVERIFY(focusArguments.count() == 1); + QCOMPARE(focusArguments.at(0).toBool(), true); + + QCOMPARE(parentItem->hasActiveFocus(), false); + QCOMPARE(parentItem->hasFocus(), false); + QCOMPARE(wantsFocusSpy.count(),0); + + item->setX(10.0); + QCOMPARE(item->x(), 10.0); + QCOMPARE(xSpy.count(), 1); + + item->setY(10.0); + QCOMPARE(item->y(), 10.0); + QCOMPARE(ySpy.count(), 1); + + delete canvas; +} + +void tst_QQuickItem::childrenRect() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRect.qml"))); + canvas->setBaseSize(QSize(240,320)); + canvas->show(); + + QQuickItem *o = canvas->rootObject(); + QQuickItem *item = o->findChild("testItem"); + QCOMPARE(item->width(), qreal(0)); + QCOMPARE(item->height(), qreal(0)); + + o->setProperty("childCount", 1); + QCOMPARE(item->width(), qreal(10)); + QCOMPARE(item->height(), qreal(20)); + + o->setProperty("childCount", 5); + QCOMPARE(item->width(), qreal(50)); + QCOMPARE(item->height(), qreal(100)); + + o->setProperty("childCount", 0); + QCOMPARE(item->width(), qreal(0)); + QCOMPARE(item->height(), qreal(0)); + + delete o; + delete canvas; +} + +// QTBUG-11383 +void tst_QQuickItem::childrenRectBug() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug.qml"))); + canvas->show(); + + QQuickItem *o = canvas->rootObject(); + QQuickItem *item = o->findChild("theItem"); + QCOMPARE(item->width(), qreal(200)); + QCOMPARE(item->height(), qreal(100)); + QCOMPARE(item->x(), qreal(100)); + + delete canvas; +} + +// QTBUG-11465 +void tst_QQuickItem::childrenRectBug2() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug2.qml"))); + canvas->show(); + + QQuickRectangle *rect = qobject_cast(canvas->rootObject()); + QVERIFY(rect); + QQuickItem *item = rect->findChild("theItem"); + QCOMPARE(item->width(), qreal(100)); + QCOMPARE(item->height(), qreal(110)); + QCOMPARE(item->x(), qreal(130)); + + QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect); + rectPrivate->setState("row"); + QCOMPARE(item->width(), qreal(210)); + QCOMPARE(item->height(), qreal(50)); + QCOMPARE(item->x(), qreal(75)); + + delete canvas; +} + +// QTBUG-12722 +void tst_QQuickItem::childrenRectBug3() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("childrenRectBug3.qml"))); + canvas->show(); + + //don't crash on delete + delete canvas; +} + +// QTBUG-13893 +void tst_QQuickItem::transformCrash() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("transformCrash.qml"))); + canvas->show(); + + delete canvas; +} + +void tst_QQuickItem::implicitSize() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("implicitsize.qml"))); + canvas->show(); + + QQuickItem *item = qobject_cast(canvas->rootObject()); + QVERIFY(item); + QCOMPARE(item->width(), qreal(80)); + QCOMPARE(item->height(), qreal(60)); + + QCOMPARE(item->implicitWidth(), qreal(200)); + QCOMPARE(item->implicitHeight(), qreal(100)); + + QMetaObject::invokeMethod(item, "resetSize"); + + QCOMPARE(item->width(), qreal(200)); + QCOMPARE(item->height(), qreal(100)); + + QMetaObject::invokeMethod(item, "changeImplicit"); + + QCOMPARE(item->implicitWidth(), qreal(150)); + QCOMPARE(item->implicitHeight(), qreal(80)); + QCOMPARE(item->width(), qreal(150)); + QCOMPARE(item->height(), qreal(80)); + + delete canvas; +} + +void tst_QQuickItem::qtbug_16871() +{ + QDeclarativeComponent component(&engine, TESTDATA("qtbug_16871.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + delete o; +} + +QTEST_MAIN(tst_QQuickItem) + +#include "tst_qquickitem.moc" diff --git a/tests/auto/qtquick2/qquicklistview/data/ComponentView.qml b/tests/auto/qtquick2/qquicklistview/data/ComponentView.qml new file mode 100644 index 0000000000..3e87be8799 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/ComponentView.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +ListView { + id: view + + property string title + + width: 100; height: 100; + + model: 1 + delegate: Text { objectName: "listItem"; text: view.title } + header: Text { objectName: "header"; text: view.title } + footer: Text { objectName: "footer"; text: view.title } + section.delegate: Text { objectName: "section"; text: view.title } + section.property: "modelData" +} diff --git a/tests/auto/qtquick2/qquicklistview/data/asyncloader.qml b/tests/auto/qtquick2/qquicklistview/data/asyncloader.qml new file mode 100644 index 0000000000..f038f0960c --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/asyncloader.qml @@ -0,0 +1,36 @@ + +import QtQuick 2.0 + +Rectangle { + id: root + width: 300; height: 400 + color: "#2200FF00" + + Loader { + asynchronous: true + sourceComponent: viewComp + anchors.fill: parent + } + + Component { + id: viewComp + ListView { + objectName: "view" + width: 300; height: 400 + model: 20 + delegate: aDelegate + + highlight: Rectangle { color: "lightsteelblue" } + } + } + // The delegate for each list + Component { + id: aDelegate + Item { + objectName: "wrapper" + width: 300 + height: 50 + Text { text: 'Index: ' + index } + } + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/attachedSignals.qml b/tests/auto/qtquick2/qquicklistview/data/attachedSignals.qml new file mode 100644 index 0000000000..2c3c0bbada --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/attachedSignals.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +ListView { + id: view + width: 240; height: 320 + + property variant addedDelegates: [] + property int removedDelegateCount + + model: testModel + + delegate: Rectangle { + width: 200; height: delegateHeight + border.width: 1 + ListView.onAdd: { + var obj = ListView.view.addedDelegates + obj.push(model.name) + ListView.view.addedDelegates = obj + } + ListView.onRemove: { + view.removedDelegateCount += 1 + } + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/creationContext.qml b/tests/auto/qtquick2/qquicklistview/data/creationContext.qml new file mode 100644 index 0000000000..79a682788b --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/creationContext.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +ComponentView { + title: "Hello!" +} diff --git a/tests/auto/qtquick2/qquicklistview/data/displaylist.qml b/tests/auto/qtquick2/qquicklistview/data/displaylist.qml new file mode 100644 index 0000000000..4e8fd32f6a --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/displaylist.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + id: root + property real delegateHeight: 20 + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: root.delegateHeight + Behavior on height { NumberAnimation { duration: 200} } + width: 240 + Text { + text: index + } + Text { + x: 30 + objectName: "displayText" + text: display + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + }, + Component { + id: myHighlight + Rectangle { color: "green" } + } + ] + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: testModel + delegate: myDelegate + highlight: myHighlight + highlightMoveSpeed: 1000 + highlightResizeSpeed: 1000 + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/fillModelOnComponentCompleted.qml b/tests/auto/qtquick2/qquicklistview/data/fillModelOnComponentCompleted.qml new file mode 100644 index 0000000000..906e6adb6b --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/fillModelOnComponentCompleted.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + + ListModel { id: testModel } + + ListView { + id: list + objectName: "list" + width: parent.width + anchors.top: parent.top + anchors.bottom: parent.bottom + model: testModel + + delegate: Text { + objectName: "wrapper" + font.pointSize: 20 + text: index + } + footer: Rectangle { + width: parent.width + height: 40 + color: "green" + } + header: Text { objectName: "header"; text: "Header" } + } + + Component.onCompleted: { + if (setCurrentToZero == 0) + list.currentIndex = 0 + for (var i=0; i<30; i++) testModel.append({"name" : i, "val": i}) + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/footer.qml b/tests/auto/qtquick2/qquicklistview/data/footer.qml new file mode 100644 index 0000000000..2a5619999e --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/footer.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +Rectangle { + property bool showHeader: false + + function changeFooter() { + list.footer = footer2 + } + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 40 + Text { + text: index + " " + x + "," + y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + Component { + id: headerComponent + Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } + } + + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: testModel + delegate: myDelegate + header: parent.showHeader ? headerComponent : null + footer: Text { objectName: "footer"; text: "Footer " + x + "," + y; width: 100; height: 30 } + } + + Component { + id: footer2 + Text { objectName: "footer2"; text: "Footer 2 " + x + "," + y; width: 50; height: 20 } + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/header.qml b/tests/auto/qtquick2/qquicklistview/data/header.qml new file mode 100644 index 0000000000..bf70310630 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/header.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + function changeHeader() { + list.header = header2 + } + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 30 + width: 240 + Text { + text: index + " " + x + "," + y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ListView { + id: list + objectName: "list" + focus: true + width: initialViewWidth + height: initialViewHeight + snapMode: ListView.SnapToItem + model: testModel + delegate: myDelegate + header: Text { objectName: "header"; text: "Header " + x + "," + y; width: 100; height: 30 } + } + Component { + id: header2 + Text { objectName: "header2"; text: "Header " + x + "," + y; width: 50; height: 20 } + } + +} diff --git a/tests/auto/qtquick2/qquicklistview/data/headerfooter.qml b/tests/auto/qtquick2/qquicklistview/data/headerfooter.qml new file mode 100644 index 0000000000..8e8463d645 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/headerfooter.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +ListView { + id: view + property bool horizontal: false + property bool rtl: false + width: 240 + height: 320 + + orientation: horizontal ? ListView.Horizontal : ListView.Vertical + header: Rectangle { + objectName: "header" + width: horizontal ? 20 : view.width + height: horizontal ? view.height : 20 + color: "red" + } + footer: Rectangle { + objectName: "footer" + width: horizontal ? 30 : view.width + height: horizontal ? view.height : 30 + color: "blue" + } + + delegate: Text { width: 30; height: 30; text: index + "(" + x + ")" } + layoutDirection: rtl ? Qt.RightToLeft : Qt.LeftToRight +} diff --git a/tests/auto/qtquick2/qquicklistview/data/itemlist.qml b/tests/auto/qtquick2/qquicklistview/data/itemlist.qml new file mode 100644 index 0000000000..5c7ecdd5e8 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/itemlist.qml @@ -0,0 +1,46 @@ +// This example demonstrates placing items in a view using +// a VisualItemModel + +import QtQuick 2.0 + +Rectangle { + color: "lightgray" + width: 240 + height: 320 + + VisualItemModel { + id: itemModel + objectName: "itemModel" + Rectangle { + objectName: "item1" + height: ListView.view ? ListView.view.height : 0 + width: view.width; color: "#FFFEF0" + Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item2" + height: ListView.view ? ListView.view.height : 0 + width: view.width; color: "#F0FFF7" + Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item3" + height: ListView.view ? ListView.view.height : 0 + width: view.width; color: "#F4F0FF" + Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + ListView { + id: view + objectName: "view" + anchors.fill: parent + anchors.bottomMargin: 30 + model: itemModel + preferredHighlightBegin: 0 + preferredHighlightEnd: 0 + highlightRangeMode: "StrictlyEnforceRange" + orientation: ListView.Horizontal + flickDeceleration: 2000 + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange-nohighlight.qml b/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange-nohighlight.qml new file mode 100644 index 0000000000..1db1096499 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange-nohighlight.qml @@ -0,0 +1,61 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + color: "transparent" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + } + } + + Rectangle { // current listview item should be always in this area + y: 100 + height: 20 + width: 240 + color: "purple" + } + + ListView { + id: list + objectName: "list" + width: 240 + height: 320 + model: testModel + delegate: myDelegate + focus: true + + preferredHighlightBegin: 100 + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" + + section.property: "number" + section.delegate: Rectangle { width: 240; height: 10; color: "lightsteelblue" } + } +} + diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange.qml b/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange.qml new file mode 100644 index 0000000000..f1bf6c2b57 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-enforcerange.qml @@ -0,0 +1,55 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Item { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + } + } + + Component { + id: myHighlight + Rectangle { + color: "lightsteelblue" + } + } + + ListView { + id: list + objectName: "list" + width: 240 + height: 320 + model: testModel + delegate: myDelegate + highlight: myHighlight + preferredHighlightBegin: 100 + preferredHighlightEnd: 100 + highlightRangeMode: "StrictlyEnforceRange" + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-initCurrent.qml b/tests/auto/qtquick2/qquicklistview/data/listview-initCurrent.qml new file mode 100644 index 0000000000..c4f1860eda --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-initCurrent.qml @@ -0,0 +1,64 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + property int current: list.currentIndex + property bool showHeader: false + property bool showFooter: false + + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + + Component { + id: headerFooter + Rectangle { height: 30; width: 240; color: "blue" } + } + + ListView { + id: list + objectName: "list" + focus: true + currentIndex: 20 + width: 240 + height: 320 + keyNavigationWraps: testWrap + delegate: myDelegate + highlightMoveSpeed: 1000 + model: testModel + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-noCurrent.qml b/tests/auto/qtquick2/qquicklistview/data/listview-noCurrent.qml new file mode 100644 index 0000000000..079966d8e4 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-noCurrent.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + property int current: list.currentIndex + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ] + ListView { + id: list + objectName: "list" + focus: true + currentIndex: -1 + width: 240 + height: 320 + delegate: myDelegate + highlightMoveSpeed: 1000 + model: testModel + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-sections.qml b/tests/auto/qtquick2/qquicklistview/data/listview-sections.qml new file mode 100644 index 0000000000..d5b8a4400d --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-sections.qml @@ -0,0 +1,64 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Item { + id: wrapper + objectName: "wrapper" + height: ListView.previousSection != ListView.section ? 40 : 20; + width: 240 + Rectangle { + y: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 + height: 20 + width: parent.width + color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 100 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + objectName: "nextSection" + x: 150 + text: wrapper.ListView.nextSection + } + Text { + x: 200 + text: wrapper.y + } + } + Rectangle { + color: "#99bb99" + height: wrapper.ListView.previousSection != wrapper.ListView.section ? 20 : 0 + width: parent.width + visible: wrapper.ListView.previousSection != wrapper.ListView.section ? true : false + Text { text: wrapper.ListView.section } + } + } + } + ] + ListView { + id: list + objectName: "list" + width: 240 + height: 320 + model: testModel + delegate: myDelegate + section.property: "number" + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listview-sections_delegate.qml b/tests/auto/qtquick2/qquicklistview/data/listview-sections_delegate.qml new file mode 100644 index 0000000000..496d8d7784 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listview-sections_delegate.qml @@ -0,0 +1,71 @@ +import QtQuick 2.0 + +Rectangle { + property string sectionProperty: "number" + property int sectionPositioning: ViewSection.InlineLabels + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: myDelegate + Item { + id: wrapper + objectName: "wrapper" + height: 20; + width: 240 + Rectangle { + height: 20 + width: parent.width + color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white" + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 100 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + objectName: "nextSection" + x: 150 + text: wrapper.ListView.nextSection + } + Text { + x: 200 + text: wrapper.y + } + } + ListView.onRemove: SequentialAnimation { + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + NumberAnimation { target: wrapper; property: "height"; to: 0; duration: 100; easing.type: Easing.InOutQuad } + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } + } + } + } + ] + ListView { + id: list + objectName: "list" + width: 240 + height: 320 + model: testModel + delegate: myDelegate + section.property: sectionProperty + section.delegate: Rectangle { + objectName: "sect_" + section + color: "#99bb99" + height: 20 + width: list.width + Text { text: section + ", " + parent.y + ", " + parent.objectName } + } + section.labelPositioning: sectionPositioning + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/listviewtest.qml b/tests/auto/qtquick2/qquicklistview/data/listviewtest.qml new file mode 100644 index 0000000000..47b341c1fc --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/listviewtest.qml @@ -0,0 +1,133 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 320 + color: "#ffffff" + + property int count: list.count + property bool showHeader: false + property bool showFooter: false + property real hr: list.visibleArea.heightRatio + function heightRatio() { + return list.visibleArea.heightRatio + } + + function checkProperties() { + testObject.error = false; + if (list.model != testModel) { + console.log("model property incorrect"); + testObject.error = true; + } + if (!testObject.animate && list.delegate != myDelegate) { + console.log("delegate property incorrect - expected myDelegate"); + testObject.error = true; + } + if (testObject.animate && list.delegate != animatedDelegate) { + console.log("delegate property incorrect - expected animatedDelegate"); + testObject.error = true; + } + if (testObject.invalidHighlight && list.highlight != invalidHl) { + console.log("highlight property incorrect - expected invalidHl"); + testObject.error = true; + } + if (!testObject.invalidHighlight && list.highlight != myHighlight) { + console.log("highlight property incorrect - expected myHighlight"); + testObject.error = true; + } + } + resources: [ + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "#EEEEEE" + } + }, + Component { + id: animatedDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + ListView.onRemove: SequentialAnimation { + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true } + NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: "InOutQuad" } + PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false } + + } + } + }, + Component { + id: myHighlight + Rectangle { color: "green" } + }, + Component { + id: invalidHl + SmoothedAnimation {} + }, + Component { + id: headerFooter + Rectangle { height: 30; width: 240; color: "blue" } + } + ] + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: testModel + delegate: testObject.animate ? animatedDelegate : myDelegate + highlight: testObject.invalidHighlight ? invalidHl : myHighlight + highlightMoveSpeed: 1000 + highlightResizeSpeed: 1000 + cacheBuffer: testObject.cacheBuffer + header: root.showHeader ? headerFooter : null + footer: root.showFooter ? headerFooter : null + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/manual-highlight.qml b/tests/auto/qtquick2/qquicklistview/data/manual-highlight.qml new file mode 100644 index 0000000000..aac4599f01 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/manual-highlight.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Item { + + ListModel { + id: model + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + ListElement { + name: "Bob Brown" + number: "555 5845" + } + } + + Component { + id: highlight + Rectangle { + objectName: "highlight" + width: 180; height: 20 + color: "lightsteelblue"; radius: 5 + y: list.currentItem.y+5 + } + } + + ListView { + id: list + objectName: "list" + anchors.fill: parent + model: model + delegate: Text { objectName: "wrapper"; text: name } + + highlight: highlight + highlightFollowsCurrentItem: false + focus: true + } + +} diff --git a/tests/auto/qtquick2/qquicklistview/data/margins.qml b/tests/auto/qtquick2/qquicklistview/data/margins.qml new file mode 100644 index 0000000000..19bbef500f --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/margins.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 320 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 240 + Text { + text: index + } + Text { + x: 30 + id: textName + objectName: "textName" + text: name + } + Text { + x: 120 + id: textNumber + objectName: "textNumber" + text: number + } + Text { + x: 200 + text: wrapper.y + } + color: ListView.isCurrentItem ? "lightsteelblue" : "white" + } + } + ListView { + id: list + objectName: "list" + anchors.fill: parent + topMargin: 30 + bottomMargin: 50 + model: testModel + delegate: myDelegate + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/propertychangestest.qml b/tests/auto/qtquick2/qquicklistview/data/propertychangestest.qml new file mode 100644 index 0000000000..146f3f13b0 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/propertychangestest.qml @@ -0,0 +1,71 @@ +import QtQuick 2.0 + +Rectangle { + width: 180; height: 120; color: "white" + Component { + id: delegate + Item { + id: wrapper + width: 180; height: 40; + Column { + x: 5; y: 5 + Text { text: 'Name: ' + name } + Text { text: 'Number: ' + number } + } + } + } + Component { + id: highlightRed + Rectangle { + color: "red" + radius: 10 + opacity: 0.5 + } + } + ListView { + objectName: "listView" + anchors.fill: parent + model: listModel + delegate: delegate + highlight: highlightRed + focus: true + highlightFollowsCurrentItem: true + preferredHighlightBegin: 0.0 + preferredHighlightEnd: 0.0 + highlightRangeMode: ListView.ApplyRange + keyNavigationWraps: true + cacheBuffer: 10 + snapMode: ListView.SnapToItem + } + + data:[ + ListModel { + id: listModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + }, + ListModel { + objectName: "alternateModel" + ListElement { + name: "Jack" + number: "555 8426" + } + ListElement { + name: "Mary" + number: "555 3264" + } + } + ] +} + + diff --git a/tests/auto/qtquick2/qquicklistview/data/qtbug-21742.qml b/tests/auto/qtquick2/qquicklistview/data/qtbug-21742.qml new file mode 100644 index 0000000000..774f9041fb --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/qtbug-21742.qml @@ -0,0 +1,36 @@ +import QtQuick 2.0 + +Rectangle { + height: 200 + width: 200 + property int count: menuView.count + + Component.onCompleted: { setModel(); } + + function setModel() + { + menuModel.append({"enabledItem" : true}); + menuView.currentIndex = 0; + } + + ListModel { + id: menuModel + } + + ListView { + id: menuView + anchors.fill: parent + model: menuModel + delegate: mything + } + + Component { + id: mything + Rectangle { + height: 50 + width: 200 + color: index == menuView.currentIndex ? "green" : "blue" + } + } + +} \ No newline at end of file diff --git a/tests/auto/qtquick2/qquicklistview/data/qtbug14821.qml b/tests/auto/qtquick2/qquicklistview/data/qtbug14821.qml new file mode 100644 index 0000000000..0a5e0acbb4 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/qtbug14821.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +ListView { + id: view + width: 300; height: 200 + focus: true + keyNavigationWraps: true + + model: 100 + + preferredHighlightBegin: 90 + preferredHighlightEnd: 110 + + highlightRangeMode: ListView.StrictlyEnforceRange + highlight: Component { + Rectangle { + border.color: "blue" + border.width: 3 + color: "transparent" + width: 300; height: 15 + } + } + + delegate: Component { + Item { + height: 15 + (view.currentIndex == index ? 20 : 0) + width: 200 + Text { text: 'Index: ' + index; anchors.verticalCenter: parent.verticalCenter } + } + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/qtbug16037.qml b/tests/auto/qtquick2/qquicklistview/data/qtbug16037.qml new file mode 100644 index 0000000000..21faeb3f32 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/qtbug16037.qml @@ -0,0 +1,37 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + + function setModel() { + listView.model = listModel1 + } + + ListModel { + id: listModel1 + ListElement { text: "Apple" } + ListElement { text: "Banana" } + ListElement { text: "Orange" } + ListElement { text: "Coconut" } + } + + Rectangle { + width: 200 + height: listView.contentHeight + color: "yellow" + anchors.centerIn: parent + + ListView { + id: listView + objectName: "listview" + anchors.fill: parent + + delegate: Item { + width: 200 + height: 20 + Text { text: model.text; anchors.centerIn: parent } + } + } + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/resizeview.qml b/tests/auto/qtquick2/qquicklistview/data/resizeview.qml new file mode 100644 index 0000000000..071cdedf2e --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/resizeview.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Rectangle { + id: root + + property real initialHeight + + ListView { + id: list + objectName: "list" + width: 240 + height: initialHeight + model: testModel + delegate: Rectangle { + objectName: "wrapper" + width: 240 + height: 20 + border.width: 1 + } + } +} + diff --git a/tests/auto/qtquick2/qquicklistview/data/rightToLeft.qml b/tests/auto/qtquick2/qquicklistview/data/rightToLeft.qml new file mode 100644 index 0000000000..6d77de26f4 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/rightToLeft.qml @@ -0,0 +1,42 @@ +// This example demonstrates how item positioning +// changes in right-to-left layout direction + +import QtQuick 2.0 + +Rectangle { + color: "lightgray" + width: 640 + height: 320 + + VisualItemModel { + id: itemModel + objectName: "itemModel" + Rectangle { + objectName: "item1" + height: view.height; width: 100; color: "#FFFEF0" + Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item2" + height: view.height; width: 200; color: "#F0FFF7" + Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item3" + height: view.height; width: 240; color: "#F4F0FF" + Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + ListView { + id: view + objectName: "view" + anchors.fill: parent + anchors.bottomMargin: 30 + model: itemModel + highlightRangeMode: "StrictlyEnforceRange" + orientation: ListView.Horizontal + flickDeceleration: 2000 + layoutDirection: Qt.RightToLeft + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/sizelessthan1.qml b/tests/auto/qtquick2/qquicklistview/data/sizelessthan1.qml new file mode 100644 index 0000000000..aa9dc20ae9 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/sizelessthan1.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 0.5 + width: 240 + color: ((index % 2) == 1 ? "red" : "blue") + } + } + ListView { + id: list + objectName: "list" + focus: true + width: 240 + height: 320 + model: testModel + delegate: myDelegate + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/snapToItem.qml b/tests/auto/qtquick2/qquicklistview/data/snapToItem.qml new file mode 100644 index 0000000000..6f201072f0 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/snapToItem.qml @@ -0,0 +1,49 @@ +import QtQuick 2.0 + +Rectangle { + id: root + width: 240 + height: 240 + color: "#ffffff" + + Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 80 + width: 80 + Column { + Text { + text: index + } + Text { + text: wrapper.x + ", " + wrapper.y + } + } + color: ListView.isCurrentItem ? "lightsteelblue" : "transparent" + } + } + ListView { + id: list + objectName: "list" + anchors.fill: parent +// preferredHighlightBegin: 20 +// preferredHighlightEnd: 100 + preferredHighlightBegin: 20 + preferredHighlightEnd: 100 + snapMode: ListView.SnapToItem + orientation: ListView.Horizontal + layoutDirection: Qt.RightToLeft + highlightRangeMode: ListView.StrictlyEnforceRange + highlight: Rectangle { width: 80; height: 80; color: "yellow" } + model: 18 + delegate: myDelegate + } + + Text { + anchors.right: parent.right + anchors.bottom: parent.bottom + text: list.contentX + ", " + list.contentY + } +} diff --git a/tests/auto/qtquick2/qquicklistview/data/strictlyenforcerange.qml b/tests/auto/qtquick2/qquicklistview/data/strictlyenforcerange.qml new file mode 100644 index 0000000000..7960ac4abb --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/data/strictlyenforcerange.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +ListView { + id: list + objectName: "list" + width: 320 + height: 480 + + function fillModel() { + list.model.append({"col": "red"}); + list.currentIndex = list.count-1 + list.model.append({"col": "blue"}); + list.currentIndex = list.count-1 + list.model.append({"col": "green"}); + list.currentIndex = list.count-1 + } + + model: ListModel { id: listModel } // empty model + delegate: Rectangle { id: wrapper; objectName: "wrapper"; color: col; width: 300; height: 400 } + orientation: "Horizontal" + snapMode: "SnapToItem" + cacheBuffer: 1000 + + preferredHighlightBegin: 10 + preferredHighlightEnd: 10 + + highlightRangeMode: "StrictlyEnforceRange" + focus: true +} diff --git a/tests/auto/qtquick2/qquicklistview/incrementalmodel.cpp b/tests/auto/qtquick2/qquicklistview/incrementalmodel.cpp new file mode 100644 index 0000000000..53d30915f5 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/incrementalmodel.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "incrementalmodel.h" +#include +#include + +IncrementalModel::IncrementalModel(QObject *parent) + : QAbstractListModel(parent), count(0) +{ + for (int i = 0; i < 100; ++i) + list.append("Item " + QString::number(i)); +} + +int IncrementalModel::rowCount(const QModelIndex & /* parent */) const +{ + return count; +} + +QVariant IncrementalModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() >= list.size() || index.row() < 0) + return QVariant(); + + if (role == Qt::DisplayRole) + return list.at(index.row()); + return QVariant(); +} + +bool IncrementalModel::canFetchMore(const QModelIndex & /* index */) const +{ + if (count < list.size()) + return true; + else + return false; +} + +void IncrementalModel::fetchMore(const QModelIndex & /* index */) +{ + int remainder = list.size() - count; + int itemsToFetch = qMin(5, remainder); + + beginInsertRows(QModelIndex(), count, count+itemsToFetch-1); + + count += itemsToFetch; + + endInsertRows(); +} diff --git a/tests/auto/qtquick2/qquicklistview/incrementalmodel.h b/tests/auto/qtquick2/qquicklistview/incrementalmodel.h new file mode 100644 index 0000000000..a6cddb6b07 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/incrementalmodel.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IncrementalModel_H +#define IncrementalModel_H + +#include +#include +#include + +class IncrementalModel : public QAbstractListModel +{ + Q_OBJECT + +public: + IncrementalModel(QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +protected: + bool canFetchMore(const QModelIndex &parent) const; + void fetchMore(const QModelIndex &parent); + +private: + QStringList list; + int count; +}; + +#endif diff --git a/tests/auto/qtquick2/qquicklistview/qquicklistview.pro b/tests/auto/qtquick2/qquicklistview/qquicklistview.pro new file mode 100644 index 0000000000..be88679c62 --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/qquicklistview.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquicklistview +macx:CONFIG -= app_bundle + +HEADERS += incrementalmodel.h +SOURCES += tst_qquicklistview.cpp incrementalmodel.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private widgets widgets-private v8-private opengl-private testlib diff --git a/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp new file mode 100644 index 0000000000..780033bbeb --- /dev/null +++ b/tests/auto/qtquick2/qquicklistview/tst_qquicklistview.cpp @@ -0,0 +1,4379 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include "incrementalmodel.h" +#include + +Q_DECLARE_METATYPE(Qt::LayoutDirection) +Q_DECLARE_METATYPE(QQuickListView::Orientation) + +class tst_QQuickListView : public QObject +{ + Q_OBJECT +public: + tst_QQuickListView(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + // Test both QListModelInterface and QAbstractItemModel model types + void qListModelInterface_items(); + void qAbstractItemModel_items(); + + void qListModelInterface_changed(); + void qAbstractItemModel_changed(); + + void qListModelInterface_inserted(); + void qListModelInterface_inserted_more(); + void qListModelInterface_inserted_more_data(); + void qAbstractItemModel_inserted(); + void qAbstractItemModel_inserted_more(); + void qAbstractItemModel_inserted_more_data(); + + void qListModelInterface_removed(); + void qAbstractItemModel_removed(); + + void qListModelInterface_moved(); + void qListModelInterface_moved_data(); + void qAbstractItemModel_moved(); + void qAbstractItemModel_moved_data(); + + void multipleChanges(); + void multipleChanges_data(); + + void qListModelInterface_clear(); + void qAbstractItemModel_clear(); + + void insertBeforeVisible(); + void insertBeforeVisible_data(); + void swapWithFirstItem(); + void itemList(); + void currentIndex_delayedItemCreation(); + void currentIndex_delayedItemCreation_data(); + void currentIndex(); + void noCurrentIndex(); + void enforceRange(); + void enforceRange_withoutHighlight(); + void spacing(); + void sections(); + void sectionsPositioning(); + void sectionsDelegate(); + void cacheBuffer(); + void positionViewAtIndex(); + void resetModel(); + void propertyChanges(); + void componentChanges(); + void modelChanges(); + void manualHighlight(); + void header(); + void header_data(); + void header_delayItemCreation(); + void footer(); + void footer_data(); + void headerFooter(); + void resizeView(); + void resizeViewAndRepaint(); + void sizeLessThan1(); + void QTBUG_14821(); + void resizeDelegate(); + void resizeFirstDelegate(); + void QTBUG_16037(); + void indexAt(); + void incrementalModel(); + void onAdd(); + void onAdd_data(); + void onRemove(); + void onRemove_data(); + void rightToLeft(); + void test_mirroring(); + void margins(); + void creationContext(); + void snapToItem_data(); + void snapToItem(); + + void QTBUG_9791(); + void QTBUG_11105(); + void QTBUG_21742(); + + void asynchronous(); + +private: + template void items(); + template void changed(); + template void inserted(); + template void inserted_more(); + template void removed(bool animated); + template void moved(); + template void clear(); + QQuickView *createView(); + void flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration); + QQuickItem *findVisibleChild(QQuickItem *parent, const QString &objectName); + template + T *findItem(QQuickItem *parent, const QString &id, int index=-1); + template + QList findItems(QQuickItem *parent, const QString &objectName); + void dumpTree(QQuickItem *parent, int depth = 0); + + void inserted_more_data(); + void moved_data(); +}; + +void tst_QQuickListView::initTestCase() +{ +} + +void tst_QQuickListView::cleanupTestCase() +{ + +} +class TestObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(bool error READ error WRITE setError NOTIFY changedError) + Q_PROPERTY(bool animate READ animate NOTIFY changedAnim) + Q_PROPERTY(bool invalidHighlight READ invalidHighlight NOTIFY changedHl) + Q_PROPERTY(int cacheBuffer READ cacheBuffer NOTIFY changedCacheBuffer) + +public: + TestObject(QObject *parent = 0) + : QObject(parent), mError(true), mAnimate(false), mInvalidHighlight(false) + , mCacheBuffer(0) {} + + bool error() const { return mError; } + void setError(bool err) { mError = err; emit changedError(); } + + bool animate() const { return mAnimate; } + void setAnimate(bool anim) { mAnimate = anim; emit changedAnim(); } + + bool invalidHighlight() const { return mInvalidHighlight; } + void setInvalidHighlight(bool invalid) { mInvalidHighlight = invalid; emit changedHl(); } + + int cacheBuffer() const { return mCacheBuffer; } + void setCacheBuffer(int buffer) { mCacheBuffer = buffer; emit changedCacheBuffer(); } + +signals: + void changedError(); + void changedAnim(); + void changedHl(); + void changedCacheBuffer(); + +public: + bool mError; + bool mAnimate; + bool mInvalidHighlight; + int mCacheBuffer; +}; + +template +void tst_qquicklistview_move(int from, int to, int n, T *items) +{ + if (from > to) { + // Only move forwards - flip if backwards moving + int tfrom = from; + int tto = to; + from = tto; + to = tto+n; + n = tfrom-tto; + } + if (n == 1) { + items->move(from, to); + } else { + T replaced; + int i=0; + typename T::ConstIterator it=items->begin(); it += from+n; + for (; ibegin(); it += from; + for (; ibegin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } +} + +class TestModel : public QListModelInterface +{ + Q_OBJECT +public: + TestModel(QObject *parent = 0) : QListModelInterface(parent) {} + ~TestModel() {} + + enum Roles { Name, Number }; + + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + int count() const { return list.count(); } + + QList roles() const { return QList() << Name << Number; } + QString toString(int role) const { + switch (role) { + case Name: + return "name"; + case Number: + return "number"; + default: + return ""; + } + } + + QVariant data(int index, int role) const + { + if (role==0) + return list.at(index).first; + if (role==1) + return list.at(index).second; + return QVariant(); + } + QHash data(int index, const QList &roles) const { + QHash returnHash; + + for (int i = 0; i < roles.size(); ++i) { + int role = roles.at(i); + QVariant info; + switch (role) { + case Name: + info = list.at(index).first; + break; + case Number: + info = list.at(index).second; + break; + default: + break; + } + returnHash.insert(role, info); + } + return returnHash; + } + + void addItem(const QString &name, const QString &number) { + list.append(QPair(name, number)); + emit itemsInserted(list.count()-1, 1); + } + + void insertItem(int index, const QString &name, const QString &number) { + list.insert(index, QPair(name, number)); + emit itemsInserted(index, 1); + } + + void insertItems(int index, const QList > &items) { + for (int i=0; i(items[i].first, items[i].second)); + emit itemsInserted(index, items.count()); + } + + void removeItem(int index) { + list.removeAt(index); + emit itemsRemoved(index, 1); + } + + void removeItems(int index, int count) { + int c = count; + while (c--) + list.removeAt(index); + emit itemsRemoved(index, count); + } + + void moveItem(int from, int to) { + list.move(from, to); + emit itemsMoved(from, to, 1); + } + + void moveItems(int from, int to, int count) { + tst_qquicklistview_move(from, to, count, &list); + emit itemsMoved(from, to, count); + } + + void modifyItem(int index, const QString &name, const QString &number) { + list[index] = QPair(name, number); + emit itemsChanged(index, 1, roles()); + } + + void clear() { + int count = list.count(); + list.clear(); + emit itemsRemoved(0, count); + } + +private: + QList > list; +}; + + +class TestModel2 : public QAbstractListModel +{ +public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + TestModel2(QObject *parent=0) : QAbstractListModel(parent) { + QHash roles; + roles[Name] = "name"; + roles[Number] = "number"; + setRoleNames(roles); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; + } + + int count() const { return rowCount(); } + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + void addItem(const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair(name, number)); + emit endInsertRows(); + } + + void addItems(const QList > &items) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()+items.count()-1); + for (int i=0; i(items[i].first, items[i].second)); + emit endInsertRows(); + } + + void insertItem(int index, const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair(name, number)); + emit endInsertRows(); + } + + void insertItems(int index, const QList > &items) { + emit beginInsertRows(QModelIndex(), index, index+items.count()-1); + for (int i=0; i(items[i].first, items[i].second)); + emit endInsertRows(); + } + + void removeItem(int index) { + emit beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + emit endRemoveRows(); + } + + void removeItems(int index, int count) { + emit beginRemoveRows(QModelIndex(), index, index+count-1); + while (count--) + list.removeAt(index); + emit endRemoveRows(); + } + + void moveItem(int from, int to) { + emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); + list.move(from, to); + emit endMoveRows(); + } + + void moveItems(int from, int to, int count) { + emit beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); + tst_qquicklistview_move(from, to, count, &list); + emit endMoveRows(); + } + + void modifyItem(int idx, const QString &name, const QString &number) { + list[idx] = QPair(name, number); + emit dataChanged(index(idx,0), index(idx,0)); + } + + void clear() { + int count = list.count(); + emit beginRemoveRows(QModelIndex(), 0, count-1); + list.clear(); + emit endRemoveRows(); + } + +private: + QList > list; +}; + +tst_QQuickListView::tst_QQuickListView() +{ +} + +template +void tst_QQuickListView::items() +{ + QQuickView *canvas = createView(); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QTRY_VERIFY(testObject->error() == false); + + QTRY_VERIFY(listview->highlightItem() != 0); + QTRY_COMPARE(listview->count(), model.count()); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + // current item should be first item + QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); + + for (int i = 0; i < model.count(); ++i) { + QQuickText *name = findItem(contentItem, "textName", i); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(contentItem, "textNumber", i); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + // switch to other delegate + testObject->setAnimate(true); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(listview->currentItem()); + + // set invalid highlight + testObject->setInvalidHighlight(true); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(listview->currentItem()); + QTRY_VERIFY(listview->highlightItem() == 0); + + // back to normal highlight + testObject->setInvalidHighlight(false); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QTRY_VERIFY(testObject->error() == false); + QTRY_VERIFY(listview->currentItem()); + QTRY_VERIFY(listview->highlightItem() != 0); + + // set an empty model and confirm that items are destroyed + T model2; + ctxt->setContextProperty("testModel", &model2); + + int itemCount = findItems(contentItem, "wrapper").count(); + QTRY_VERIFY(itemCount == 0); + + QTRY_COMPARE(listview->highlightResizeSpeed(), 1000.0); + QTRY_COMPARE(listview->highlightMoveSpeed(), 1000.0); + + delete canvas; + delete testObject; +} + + +template +void tst_QQuickListView::changed() +{ + QQuickView *canvas = createView(); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickFlickable *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.modifyItem(1, "Will", "9876"); + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + delete canvas; + delete testObject; +} + +template +void tst_QQuickListView::inserted() +{ + QQuickView *canvas = createView(); + canvas->show(); + + T model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.insertItem(1, "Will", "9876"); + + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_COMPARE(item->y(), i*20.0); + } + + model.insertItem(0, "Foo", "1111"); // zero index, and current item + + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item + + name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + QTRY_COMPARE(listview->currentIndex(), 1); + + // Confirm items positioned correctly + for (int i = 0; i < model.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_COMPARE(item->y(), i*20.0); + } + + for (int i = model.count(); i < 30; ++i) + model.insertItem(i, "Hello", QString::number(i)); + + listview->setContentY(80); + + // Insert item outside visible area + model.insertItem(1, "Hello", "1324"); + + QTRY_VERIFY(listview->contentY() == 80); + + // Confirm items positioned correctly + for (int i = 5; i < 5+15; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.0 - 20.0); + } + +// QTRY_COMPARE(listview->contentItemHeight(), model.count() * 20.0); + + // QTBUG-19675 + model.clear(); + model.insertItem(0, "Hello", "1234"); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->y(), 0.); + QVERIFY(listview->contentY() == 0); + + delete canvas; + delete testObject; +} + +template +void tst_QQuickListView::inserted_more() +{ + QFETCH(qreal, contentY); + QFETCH(int, insertIndex); + QFETCH(int, insertCount); + QFETCH(qreal, itemsOffsetAfterMove); + + QQuickText *name; + QQuickText *number; + QQuickView *canvas = createView(); + canvas->show(); + + T model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + listview->setContentY(contentY); + + QList > newData; + for (int i=0; iproperty("count").toInt(), model.count()); + + // check visibleItems.first() is in correct position + QQuickItem *item0 = findItem(contentItem, "wrapper", 0); + QVERIFY(item0); + QCOMPARE(item0->y(), itemsOffsetAfterMove); + + QList items = findItems(contentItem, "wrapper"); + int firstVisibleIndex = -1; + for (int i=0; iy() >= contentY) { + QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); + firstVisibleIndex = e.evaluate().toInt(); + break; + } + } + QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::inserted_more_data() +{ + QTest::addColumn("contentY"); + QTest::addColumn("insertIndex"); + QTest::addColumn("insertCount"); + QTest::addColumn("itemsOffsetAfterMove"); + + QTest::newRow("add 1, before visible items") + << 80.0 // show 4-19 + << 3 << 1 + << -20.0; // insert above first visible i.e. 0 is at -20, first visible should not move + + QTest::newRow("add multiple, before visible") + << 80.0 // show 4-19 + << 3 << 3 + << -20.0 * 3; // again first visible should not move + + QTest::newRow("add 1, at start of visible, content at start") + << 0.0 + << 0 << 1 + << 0.0; + + QTest::newRow("add multiple, start of visible, content at start") + << 0.0 + << 0 << 3 + << 0.0; + + QTest::newRow("add 1, at start of visible, content not at start") + << 80.0 // show 4-19 + << 4 << 1 + << 0.0; + + QTest::newRow("add multiple, at start of visible, content not at start") + << 80.0 // show 4-19 + << 4 << 3 + << 0.0; + + + QTest::newRow("add 1, at end of visible, content at start") + << 0.0 + << 15 << 1 + << 0.0; + + QTest::newRow("add 1, at end of visible, content at start") + << 0.0 + << 15 << 3 + << 0.0; + + QTest::newRow("add 1, at end of visible, content not at start") + << 80.0 // show 4-19 + << 19 << 1 + << 0.0; + + QTest::newRow("add multiple, at end of visible, content not at start") + << 80.0 // show 4-19 + << 19 << 3 + << 0.0; + + + QTest::newRow("add 1, after visible, content at start") + << 0.0 + << 16 << 1 + << 0.0; + + QTest::newRow("add 1, after visible, content at start") + << 0.0 + << 16 << 3 + << 0.0; + + QTest::newRow("add 1, after visible, content not at start") + << 80.0 // show 4-19 + << 20 << 1 + << 0.0; + + QTest::newRow("add multiple, after visible, content not at start") + << 80.0 // show 4-19 + << 20 << 3 + << 0.0; +} + +void tst_QQuickListView::insertBeforeVisible() +{ + QFETCH(int, insertIndex); + QFETCH(int, insertCount); + QFETCH(int, cacheBuffer); + + QQuickText *name; + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + listview->setCacheBuffer(cacheBuffer); + + // trigger a refill (not just setting contentY) so that the visibleItems grid is updated + int firstVisibleIndex = 20; // move to an index where the top item is not visible + listview->setContentY(firstVisibleIndex * 20.0); + listview->setCurrentIndex(firstVisibleIndex); + qApp->processEvents(); + QTRY_COMPARE(listview->currentIndex(), firstVisibleIndex); + QQuickItem *item = findItem(contentItem, "wrapper", firstVisibleIndex); + QVERIFY(item); + QCOMPARE(item->y(), listview->contentY()); + + QList > newData; + for (int i=0; iproperty("count").toInt(), model.count()); + + // now, moving to the top of the view should position the inserted items correctly + int itemsOffsetAfterMove = -(insertCount * 20); + listview->setCurrentIndex(0); + QTRY_COMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(listview->contentY(), 0.0 + itemsOffsetAfterMove); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::insertBeforeVisible_data() +{ + QTest::addColumn("insertIndex"); + QTest::addColumn("insertCount"); + QTest::addColumn("cacheBuffer"); + + QTest::newRow("insert 1 at 0, 0 buffer") << 0 << 1 << 0; + QTest::newRow("insert 1 at 0, 100 buffer") << 0 << 1 << 100; + QTest::newRow("insert 1 at 0, 500 buffer") << 0 << 1 << 500; + + QTest::newRow("insert 1 at 1, 0 buffer") << 1 << 1 << 0; + QTest::newRow("insert 1 at 1, 100 buffer") << 1 << 1 << 100; + QTest::newRow("insert 1 at 1, 500 buffer") << 1 << 1 << 500; + + QTest::newRow("insert multiple at 0, 0 buffer") << 0 << 3 << 0; + QTest::newRow("insert multiple at 0, 100 buffer") << 0 << 3 << 100; + QTest::newRow("insert multiple at 0, 500 buffer") << 0 << 3 << 500; + + QTest::newRow("insert multiple at 1, 0 buffer") << 1 << 3 << 0; + QTest::newRow("insert multiple at 1, 100 buffer") << 1 << 3 << 100; + QTest::newRow("insert multiple at 1, 500 buffer") << 1 << 3 << 500; +} + +template +void tst_QQuickListView::removed(bool /* animated */) +{ + QQuickView *canvas = createView(); + + T model; + for (int i = 0; i < 50; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.removeItem(1); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + QQuickText *name = findItem(contentItem, "textName", 1); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(1)); + QQuickText *number = findItem(contentItem, "textNumber", 1); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(1)); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*20); + } + + // Remove first item (which is the current item); + model.removeItem(0); // post: top item starts at 20 + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),i*20.0 + 20.0); + } + + // Remove items not visible + model.removeItem(18); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),i*20.0+20.0); + } + + // Remove items before visible + listview->setContentY(80); + listview->setCurrentIndex(10); + + model.removeItem(1); // post: top item will be at 40 + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + // Confirm items positioned correctly + for (int i = 2; i < 18; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),40+i*20.0); + } + + // Remove current index + QTRY_VERIFY(listview->currentIndex() == 9); + QQuickItem *oldCurrent = listview->currentItem(); + model.removeItem(9); + + QTRY_COMPARE(listview->currentIndex(), 9); + QTRY_VERIFY(listview->currentItem() != oldCurrent); + + listview->setContentY(40); // That's the top now + // let transitions settle. + QTest::qWait(300); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),40+i*20.0); + } + + // remove current item beyond visible items. + listview->setCurrentIndex(20); + listview->setContentY(40); + model.removeItem(20); + + QTRY_COMPARE(listview->currentIndex(), 20); + QTRY_VERIFY(listview->currentItem() != 0); + + // remove item before current, but visible + listview->setCurrentIndex(8); + oldCurrent = listview->currentItem(); + model.removeItem(6); + + QTRY_COMPARE(listview->currentIndex(), 7); + QTRY_VERIFY(listview->currentItem() == oldCurrent); + + listview->setContentY(80); + QTest::qWait(300); + + // remove all visible items + model.removeItems(1, 18); + QTRY_COMPARE(listview->count() , model.count()); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i+1); + if (!item) qWarning() << "Item" << i+1 << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(),80+i*20.0); + } + + model.removeItems(1, 17); + QTRY_COMPARE(listview->count() , model.count()); + + model.removeItems(2, 1); + QTRY_COMPARE(listview->count() , model.count()); + + model.addItem("New", "1"); + QTRY_COMPARE(listview->count() , model.count()); + + QTRY_VERIFY(name = findItem(contentItem, "textName", model.count()-1)); + QCOMPARE(name->text(), QString("New")); + + // Add some more items so that we don't run out + model.clear(); + for (int i = 0; i < 50; i++) + model.addItem("Item" + QString::number(i), ""); + + // QTBUG-QTBUG-20575 + listview->setCurrentIndex(0); + listview->setContentY(30); + model.removeItem(0); + QTRY_VERIFY(name = findItem(contentItem, "textName", 0)); + + // QTBUG-19198 move to end and remove all visible items one at a time. + listview->positionViewAtEnd(); + for (int i = 0; i < 18; ++i) + model.removeItems(model.count() - 1, 1); + QTRY_VERIFY(findItems(contentItem, "wrapper").count() > 16); + + delete canvas; + delete testObject; +} + +template +void tst_QQuickListView::clear() +{ + QQuickView *canvas = createView(); + + T model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + model.clear(); + + QTRY_VERIFY(listview->count() == 0); + QTRY_VERIFY(listview->currentItem() == 0); + QTRY_VERIFY(listview->contentY() == 0); + QVERIFY(listview->currentIndex() == -1); + + // confirm sanity when adding an item to cleared list + model.addItem("New", "1"); + QTRY_VERIFY(listview->count() == 1); + QVERIFY(listview->currentItem() != 0); + QVERIFY(listview->currentIndex() == 0); + + delete canvas; + delete testObject; +} + +template +void tst_QQuickListView::moved() +{ + QFETCH(qreal, contentY); + QFETCH(int, from); + QFETCH(int, to); + QFETCH(int, count); + QFETCH(qreal, itemsOffsetAfterMove); + + QQuickText *name; + QQuickText *number; + QQuickView *canvas = createView(); + canvas->show(); + + T model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickItem *currentItem = listview->currentItem(); + QTRY_VERIFY(currentItem != 0); + + listview->setContentY(contentY); + model.moveItems(from, to, count); + + // wait for items to move + QTest::qWait(100); + + QList items = findItems(contentItem, "wrapper"); + int firstVisibleIndex = -1; + for (int i=0; iy() >= contentY) { + QDeclarativeExpression e(qmlContext(items[i]), items[i], "index"); + firstVisibleIndex = e.evaluate().toInt(); + break; + } + } + QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex)); + + // Confirm items positioned correctly and indexes correct + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = firstVisibleIndex; i < model.count() && i < itemCount; ++i) { + if (i >= firstVisibleIndex + 16) // index has moved out of view + continue; + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + + // current index should have been updated + if (item == currentItem) + QTRY_COMPARE(listview->currentIndex(), i); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::moved_data() +{ + QTest::addColumn("contentY"); + QTest::addColumn("from"); + QTest::addColumn("to"); + QTest::addColumn("count"); + QTest::addColumn("itemsOffsetAfterMove"); + + // model starts with 30 items, each 20px high, in area 320px high + // 16 items should be visible at a time + // itemsOffsetAfterMove should be > 0 whenever items above the visible pos have moved + + QTest::newRow("move 1 forwards, within visible items") + << 0.0 + << 1 << 4 << 1 + << 0.0; + + QTest::newRow("move 1 forwards, from non-visible -> visible") + << 80.0 // show 4-19 + << 1 << 18 << 1 + << 20.0; // removed 1 item above the first visible, so item 0 should drop down by 1 to minimize movement + + QTest::newRow("move 1 forwards, from non-visible -> visible (move first item)") + << 80.0 // show 4-19 + << 0 << 4 << 1 + << 20.0; // first item has moved to below item4, everything drops down by size of 1 item + + QTest::newRow("move 1 forwards, from visible -> non-visible") + << 0.0 + << 1 << 16 << 1 + << 0.0; + + QTest::newRow("move 1 forwards, from visible -> non-visible (move first item)") + << 0.0 + << 0 << 16 << 1 + << 0.0; + + + QTest::newRow("move 1 backwards, within visible items") + << 0.0 + << 4 << 1 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, within visible items (to first index)") + << 0.0 + << 4 << 0 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from non-visible -> visible") + << 0.0 + << 20 << 4 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from non-visible -> visible (move last item)") + << 0.0 + << 29 << 15 << 1 + << 0.0; + + QTest::newRow("move 1 backwards, from visible -> non-visible") + << 80.0 // show 4-19 + << 16 << 1 << 1 + << -20.0; // to minimize movement, item 0 moves to -20, and other items do not move + + QTest::newRow("move 1 backwards, from visible -> non-visible (move first item)") + << 80.0 // show 4-19 + << 16 << 0 << 1 + << -20.0; // to minimize movement, item 16 (now at 0) moves to -20, and other items do not move + + + QTest::newRow("move multiple forwards, within visible items") + << 0.0 + << 0 << 5 << 3 + << 0.0; + + QTest::newRow("move multiple forwards, before visible items") + << 140.0 // show 7-22 + << 4 << 5 << 3 // 4,5,6 move to below 7 + << 20.0 * 3; // 4,5,6 moved down + + QTest::newRow("move multiple forwards, from non-visible -> visible") + << 80.0 // show 4-19 + << 1 << 5 << 3 + << 20.0 * 3; // moving 3 from above the content y should adjust y positions accordingly + + QTest::newRow("move multiple forwards, from non-visible -> visible (move first item)") + << 80.0 // show 4-19 + << 0 << 5 << 3 + << 20.0 * 3; // moving 3 from above the content y should adjust y positions accordingly + + QTest::newRow("move multiple forwards, from visible -> non-visible") + << 0.0 + << 1 << 16 << 3 + << 0.0; + + QTest::newRow("move multiple forwards, from visible -> non-visible (move first item)") + << 0.0 + << 0 << 16 << 3 + << 0.0; + + + QTest::newRow("move multiple backwards, within visible items") + << 0.0 + << 4 << 1 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, within visible items (move first item)") + << 0.0 + << 10 << 0 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from non-visible -> visible") + << 0.0 + << 20 << 4 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from non-visible -> visible (move last item)") + << 0.0 + << 27 << 10 << 3 + << 0.0; + + QTest::newRow("move multiple backwards, from visible -> non-visible") + << 80.0 // show 4-19 + << 16 << 1 << 3 + << -20.0 * 3; // to minimize movement, 0 moves by -60, and other items do not move + + QTest::newRow("move multiple backwards, from visible -> non-visible (move first item)") + << 80.0 // show 4-19 + << 16 << 0 << 3 + << -20.0 * 3; // to minimize movement, 16,17,18 move to above item 0, and other items do not move +} + + +struct ListChange { + enum { Inserted, Removed, Moved, SetCurrent } type; + int index; + int count; + int to; // Move + + static ListChange insert(int index, int count = 1) { ListChange c = { Inserted, index, count, -1 }; return c; } + static ListChange remove(int index, int count = 1) { ListChange c = { Removed, index, count, -1 }; return c; } + static ListChange move(int index, int to, int count) { ListChange c = { Moved, index, count, to }; return c; } + static ListChange setCurrent(int index) { ListChange c = { SetCurrent, index, -1, -1 }; return c; } +}; +Q_DECLARE_METATYPE(QList) + +void tst_QQuickListView::multipleChanges() +{ + QFETCH(int, startCount); + QFETCH(QList, changes); + QFETCH(int, newCount); + QFETCH(int, newCurrentIndex); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < startCount; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + for (int i=0; i > items; + for (int j=changes[i].index; jsetCurrentIndex(changes[i].index); + break; + } + } + + QTRY_COMPARE(listview->count(), newCount); + QCOMPARE(listview->count(), model.count()); + QTRY_COMPARE(listview->currentIndex(), newCurrentIndex); + + QQuickText *name; + QQuickText *number; + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i=0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i))); + name = findItem(contentItem, "textName", i); + QVERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(i)); + number = findItem(contentItem, "textNumber", i); + QVERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(i)); + } + + delete testObject; + delete canvas; +} + +void tst_QQuickListView::multipleChanges_data() +{ + QTest::addColumn("startCount"); + QTest::addColumn >("changes"); + QTest::addColumn("newCount"); + QTest::addColumn("newCurrentIndex"); + + QList changes; + + for (int i=1; i<30; i++) + changes << ListChange::remove(0); + QTest::newRow("remove all but 1, first->last") << 30 << changes << 1 << 0; + + changes << ListChange::remove(0); + QTest::newRow("remove all") << 30 << changes << 0 << -1; + + changes.clear(); + changes << ListChange::setCurrent(29); + for (int i=29; i>0; i--) + changes << ListChange::remove(i); + QTest::newRow("remove last (current) -> first") << 30 << changes << 1 << 0; + + QTest::newRow("remove then insert at 0") << 10 << (QList() + << ListChange::remove(0, 1) + << ListChange::insert(0, 1) + ) << 10 << 1; + + QTest::newRow("remove then insert at non-zero index") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::remove(2, 1) + << ListChange::insert(2, 1) + ) << 10 << 3; + + QTest::newRow("remove current then insert below it") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::remove(1, 3) + << ListChange::insert(2, 2) + ) << 9 << 1; + + QTest::newRow("remove current index then move it down") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::remove(1, 3) + << ListChange::move(1, 5, 1) + ) << 7 << 5; + + QTest::newRow("remove current index then move it up") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::remove(4, 3) + << ListChange::move(4, 1, 1) + ) << 7 << 1; + + + QTest::newRow("insert multiple times") << 0 << (QList() + << ListChange::insert(0, 2) + << ListChange::insert(0, 4) + << ListChange::insert(0, 6) + ) << 12 << 10; + + QTest::newRow("insert multiple times with current index changes") << 0 << (QList() + << ListChange::insert(0, 2) + << ListChange::insert(0, 4) + << ListChange::insert(0, 6) + << ListChange::setCurrent(3) + << ListChange::insert(3, 2) + ) << 14 << 5; + + QTest::newRow("insert and remove all") << 0 << (QList() + << ListChange::insert(0, 30) + << ListChange::remove(0, 30) + ) << 0 << -1; + + QTest::newRow("insert and remove current") << 30 << (QList() + << ListChange::insert(1) + << ListChange::setCurrent(1) + << ListChange::remove(1) + ) << 30 << 1; + + QTest::newRow("insert before 0, then remove cross section of new and old items") << 10 << (QList() + << ListChange::insert(0, 10) + << ListChange::remove(5, 10) + ) << 10 << 5; + + QTest::newRow("insert multiple, then move new items to end") << 10 << (QList() + << ListChange::insert(0, 3) + << ListChange::move(0, 10, 3) + ) << 13 << 0; + + QTest::newRow("insert multiple, then move new and some old items to end") << 10 << (QList() + << ListChange::insert(0, 3) + << ListChange::move(0, 8, 5) + ) << 13 << 11; + + QTest::newRow("insert multiple at end, then move new and some old items to start") << 10 << (QList() + << ListChange::setCurrent(9) + << ListChange::insert(10, 3) + << ListChange::move(8, 0, 5) + ) << 13 << 1; + + + QTest::newRow("move back and forth to same index") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::move(1, 2, 2) + << ListChange::move(2, 1, 2) + ) << 10 << 1; + + QTest::newRow("move forwards then back") << 10 << (QList() + << ListChange::setCurrent(2) + << ListChange::move(1, 2, 3) + << ListChange::move(3, 0, 5) + ) << 10 << 0; + + QTest::newRow("move current, then remove it") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 0, 1) + << ListChange::remove(0) + ) << 9 << 0; + + QTest::newRow("move current, then insert before it") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 0, 1) + << ListChange::insert(0) + ) << 11 << 1; + + QTest::newRow("move multiple, then remove them") << 10 << (QList() + << ListChange::setCurrent(1) + << ListChange::move(5, 1, 3) + << ListChange::remove(1, 3) + ) << 7 << 1; + + QTest::newRow("move multiple, then insert before them") << 10 << (QList() + << ListChange::setCurrent(5) + << ListChange::move(5, 1, 3) + << ListChange::insert(1, 5) + ) << 15 << 6; + + QTest::newRow("move multiple, then insert after them") << 10 << (QList() + << ListChange::setCurrent(3) + << ListChange::move(0, 1, 2) + << ListChange::insert(3, 5) + ) << 15 << 8; + + + QTest::newRow("clear current") << 0 << (QList() + << ListChange::insert(0, 5) + << ListChange::setCurrent(-1) + << ListChange::remove(0, 5) + << ListChange::insert(0, 5) + ) << 5 << -1; +} + +void tst_QQuickListView::swapWithFirstItem() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + // ensure content position is stable + listview->setContentY(0); + model.moveItem(1, 0); + QTRY_VERIFY(listview->contentY() == 0); + + delete testObject; + delete canvas; +} + +void tst_QQuickListView::enforceRange() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QTRY_COMPARE(listview->preferredHighlightBegin(), 100.0); + QTRY_COMPARE(listview->preferredHighlightEnd(), 100.0); + QTRY_COMPARE(listview->highlightRangeMode(), QQuickListView::StrictlyEnforceRange); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // view should be positioned at the top of the range. + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QTRY_VERIFY(item); + QTRY_COMPARE(listview->contentY(), -100.0); + + QQuickText *name = findItem(contentItem, "textName", 0); + QTRY_VERIFY(name != 0); + QTRY_COMPARE(name->text(), model.name(0)); + QQuickText *number = findItem(contentItem, "textNumber", 0); + QTRY_VERIFY(number != 0); + QTRY_COMPARE(number->text(), model.number(0)); + + // Check currentIndex is updated when contentItem moves + listview->setContentY(20); + + QTRY_COMPARE(listview->currentIndex(), 6); + + // change model + TestModel model2; + for (int i = 0; i < 5; i++) + model2.addItem("Item" + QString::number(i), ""); + + ctxt->setContextProperty("testModel", &model2); + QCOMPARE(listview->count(), 5); + + delete canvas; +} + +void tst_QQuickListView::enforceRange_withoutHighlight() +{ + // QTBUG-20287 + // If no highlight is set but StrictlyEnforceRange is used, the content should still move + // to the correct position (i.e. to the next/previous item, not next/previous section) + // when moving up/down via incrementCurrentIndex() and decrementCurrentIndex() + + QQuickView *canvas = createView(); + canvas->show(); + QTest::qWait(200); + + TestModel model; + model.addItem("Item 0", "a"); + model.addItem("Item 1", "b"); + model.addItem("Item 2", "b"); + model.addItem("Item 3", "c"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-enforcerange-nohighlight.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + qreal expectedPos = -100.0; + + expectedPos += 10.0; // scroll past 1st section's delegate (10px height) + QTRY_COMPARE(listview->contentY(), expectedPos); + + expectedPos += 20 + 10; // scroll past 1st section and section delegate of 2nd section + QTest::keyClick(canvas, Qt::Key_Down); + + QTRY_COMPARE(listview->contentY(), expectedPos); + + expectedPos += 20; // scroll past 1st item of 2nd section + QTest::keyClick(canvas, Qt::Key_Down); + QTRY_COMPARE(listview->contentY(), expectedPos); + + expectedPos += 20 + 10; // scroll past 2nd item of 2nd section and section delegate of 3rd section + QTest::keyClick(canvas, Qt::Key_Down); + QTRY_COMPARE(listview->contentY(), expectedPos); + + delete canvas; +} + +void tst_QQuickListView::spacing() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*20); + } + + listview->setSpacing(10); + QTRY_VERIFY(listview->spacing() == 10); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*30); + } + + listview->setSpacing(0); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.0); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::sections() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i/5)); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20 + ((i+4)/5) * 20)); + QQuickText *next = findItem(item, "nextSection"); + QCOMPARE(next->text().toInt(), (i+1)/5); + } + + QSignalSpy currentSectionChangedSpy(listview, SIGNAL(currentSectionChanged())); + + // Remove section boundary + model.removeItem(5); + QTRY_COMPARE(listview->count(), model.count()); + + // New section header created + QQuickItem *item = findItem(contentItem, "wrapper", 5); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 40.0); + + model.insertItem(3, "New Item", "0"); + QTRY_COMPARE(listview->count(), model.count()); + + // Section header moved + item = findItem(contentItem, "wrapper", 5); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 20.0); + + item = findItem(contentItem, "wrapper", 6); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 40.0); + + // insert item which will become a section header + model.insertItem(6, "Replace header", "1"); + QTRY_COMPARE(listview->count(), model.count()); + + item = findItem(contentItem, "wrapper", 6); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 40.0); + + item = findItem(contentItem, "wrapper", 7); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 20.0); + + QTRY_COMPARE(listview->currentSection(), QString("0")); + + listview->setContentY(140); + QTRY_COMPARE(listview->currentSection(), QString("1")); + + QTRY_COMPARE(currentSectionChangedSpy.count(), 1); + + listview->setContentY(20); + QTRY_COMPARE(listview->currentSection(), QString("0")); + + QTRY_COMPARE(currentSectionChangedSpy.count(), 2); + + item = findItem(contentItem, "wrapper", 1); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 20.0); + + // check that headers change when item changes + listview->setContentY(0); + model.modifyItem(0, "changed", "2"); + QTest::qWait(300); + + item = findItem(contentItem, "wrapper", 1); + QTRY_VERIFY(item); + QTRY_COMPARE(item->height(), 40.0); + + delete canvas; +} + +void tst_QQuickListView::sectionsDelegate() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i/5)); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20 + ((i+5)/5) * 20)); + QQuickText *next = findItem(item, "nextSection"); + QCOMPARE(next->text().toInt(), (i+1)/5); + } + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, "sect_" + QString::number(i)); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*6)); + } + + model.modifyItem(0, "One", "aaa"); + model.modifyItem(1, "Two", "aaa"); + model.modifyItem(2, "Three", "aaa"); + model.modifyItem(3, "Four", "aaa"); + model.modifyItem(4, "Five", "aaa"); + QTest::qWait(300); + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, + "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*6)); + } + + // remove section boundary + model.removeItem(5); + QTRY_COMPARE(listview->count(), model.count()); + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, + "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + QVERIFY(item); + } + + // QTBUG-17606 + QList items = findItems(contentItem, "sect_1"); + QCOMPARE(items.count(), 1); + + // QTBUG-17759 + model.modifyItem(0, "One", "aaa"); + model.modifyItem(1, "One", "aaa"); + model.modifyItem(2, "One", "aaa"); + model.modifyItem(3, "Four", "aaa"); + model.modifyItem(4, "Four", "aaa"); + model.modifyItem(5, "Four", "aaa"); + model.modifyItem(6, "Five", "aaa"); + model.modifyItem(7, "Five", "aaa"); + model.modifyItem(8, "Five", "aaa"); + model.modifyItem(9, "Two", "aaa"); + model.modifyItem(10, "Two", "aaa"); + model.modifyItem(11, "Two", "aaa"); + QTRY_COMPARE(findItems(contentItem, "sect_aaa").count(), 1); + canvas->rootObject()->setProperty("sectionProperty", "name"); + // ensure view has settled. + QTRY_COMPARE(findItems(contentItem, "sect_Four").count(), 1); + for (int i = 0; i < 4; ++i) { + QQuickItem *item = findItem(contentItem, + "sect_" + model.name(i*3)); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*4)); + } + + // QTBUG-17769 + model.removeItems(10, 20); + // ensure view has settled. + QTRY_COMPARE(findItems(contentItem, "wrapper").count(), 10); + // Drag view up beyond bounds + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(20,20)); + { + QMouseEvent mv(QEvent::MouseMove, QPoint(20,0), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + } + { + QMouseEvent mv(QEvent::MouseMove, QPoint(20,-50), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + } + { + QMouseEvent mv(QEvent::MouseMove, QPoint(20,-200), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + } + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(20,-200)); + // view should settle back at 0 + QTRY_COMPARE(listview->contentY(), 0.0); + + delete canvas; +} + +void tst_QQuickListView::sectionsPositioning() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i/5)); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listview-sections_delegate.qml"))); + qApp->processEvents(); + canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart | QQuickViewSection::NextLabelAtEnd))); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, "sect_" + QString::number(i)); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*6)); + } + + QQuickItem *topItem = findVisibleChild(contentItem, "sect_0"); // section header + QVERIFY(topItem); + QCOMPARE(topItem->y(), 0.); + + QQuickItem *bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer + QVERIFY(bottomItem); + QCOMPARE(bottomItem->y(), 300.); + + // move down a little and check that section header is at top + listview->setContentY(10); + QCOMPARE(topItem->y(), 0.); + + // push the top header up + listview->setContentY(110); + topItem = findVisibleChild(contentItem, "sect_0"); // section header + QVERIFY(topItem); + QCOMPARE(topItem->y(), 100.); + + QQuickItem *item = findVisibleChild(contentItem, "sect_1"); + QVERIFY(item); + QCOMPARE(item->y(), 120.); + + bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer + QVERIFY(bottomItem); + QCOMPARE(bottomItem->y(), 410.); + + // Move past section 0 + listview->setContentY(120); + topItem = findVisibleChild(contentItem, "sect_0"); // section header + QVERIFY(!topItem); + + // Push section footer down + listview->setContentY(70); + bottomItem = findVisibleChild(contentItem, "sect_4"); // section footer + QVERIFY(bottomItem); + QCOMPARE(bottomItem->y(), 380.); + + // Change current section + listview->setContentY(10); + model.modifyItem(0, "One", "aaa"); + model.modifyItem(1, "Two", "aaa"); + model.modifyItem(2, "Three", "aaa"); + model.modifyItem(3, "Four", "aaa"); + model.modifyItem(4, "Five", "aaa"); + QTest::qWait(300); + + QTRY_COMPARE(listview->currentSection(), QString("aaa")); + + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, + "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*6)); + } + + topItem = findVisibleChild(contentItem, "sect_aaa"); // section header + QVERIFY(topItem); + QCOMPARE(topItem->y(), 10.); + + // remove section boundary + listview->setContentY(120); + model.removeItem(5); + QTRY_COMPARE(listview->count(), model.count()); + for (int i = 0; i < 3; ++i) { + QQuickItem *item = findItem(contentItem, + "sect_" + (i == 0 ? QString("aaa") : QString::number(i))); + QVERIFY(item); + QTRY_COMPARE(item->y(), qreal(i*20*6)); + } + + QVERIFY(topItem = findVisibleChild(contentItem, "sect_1")); + QTRY_COMPARE(topItem->y(), 120.); + + // Change the next section + listview->setContentY(0); + bottomItem = findVisibleChild(contentItem, "sect_3"); // section footer + QVERIFY(bottomItem); + QTRY_COMPARE(bottomItem->y(), 300.); + + model.modifyItem(14, "New", "new"); + + QTRY_VERIFY(bottomItem = findVisibleChild(contentItem, "sect_new")); // section footer + QTRY_COMPARE(bottomItem->y(), 300.); + + // Turn sticky footer off + listview->setContentY(40); + canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels | QQuickViewSection::CurrentLabelAtStart))); + item = findVisibleChild(contentItem, "sect_new"); // inline label restored + QVERIFY(item); + QCOMPARE(item->y(), 360.); + + // Turn sticky header off + listview->setContentY(30); + canvas->rootObject()->setProperty("sectionPositioning", QVariant(int(QQuickViewSection::InlineLabels))); + item = findVisibleChild(contentItem, "sect_aaa"); // inline label restored + QVERIFY(item); + QCOMPARE(item->y(), 0.); + + delete canvas; +} + +void tst_QQuickListView::currentIndex_delayedItemCreation() +{ + QFETCH(bool, setCurrentToZero); + + QQuickView *canvas = createView(); + + TestModel model; + + // test currentIndexChanged() is emitted even if currentIndex = 0 on start up + // (since the currentItem will have changed and that shares the same index) + canvas->rootContext()->setContextProperty("setCurrentToZero", setCurrentToZero); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QSignalSpy spy(listview, SIGNAL(currentItemChanged())); + QCOMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(spy.count(), 1); + + delete canvas; +} + +void tst_QQuickListView::currentIndex_delayedItemCreation_data() +{ + QTest::addColumn("setCurrentToZero"); + + QTest::newRow("set to 0") << true; + QTest::newRow("don't set to 0") << false; +} + +void tst_QQuickListView::currentIndex() +{ + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("testWrap", QVariant(false)); + + QString filename(TESTDATA("listview-initCurrent.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // current item should be 20th item at startup + // and current item should be in view + QCOMPARE(listview->currentIndex(), 20); + QCOMPARE(listview->contentY(), 100.0); + QCOMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 20)); + QCOMPARE(listview->highlightItem()->y(), listview->currentItem()->y()); + + // no wrap + listview->setCurrentIndex(0); + QCOMPARE(listview->currentIndex(), 0); + // confirm that the velocity is updated + QTRY_VERIFY(listview->verticalVelocity() != 0.0); + + listview->incrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 1); + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + // with wrap + ctxt->setContextProperty("testWrap", QVariant(true)); + QVERIFY(listview->isWrapEnabled()); + + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), model.count()-1); + + QTRY_COMPARE(listview->contentY(), 280.0); + + listview->incrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + QTRY_COMPARE(listview->contentY(), 0.0); + + + // footer should become visible if it is out of view, and then current index is set to count-1 + canvas->rootObject()->setProperty("showFooter", true); + QTRY_VERIFY(listview->footerItem()); + listview->setCurrentIndex(model.count()-2); + QTRY_VERIFY(listview->footerItem()->y() > listview->contentY() + listview->height()); + listview->setCurrentIndex(model.count()-1); + QTRY_COMPARE(listview->contentY() + listview->height(), (20.0 * model.count()) + listview->footerItem()->height()); + canvas->rootObject()->setProperty("showFooter", false); + + // header should become visible if it is out of view, and then current index is set to 0 + canvas->rootObject()->setProperty("showHeader", true); + QTRY_VERIFY(listview->headerItem()); + listview->setCurrentIndex(1); + QTRY_VERIFY(listview->headerItem()->y() + listview->headerItem()->height() < listview->contentY()); + listview->setCurrentIndex(0); + QTRY_COMPARE(listview->contentY(), -listview->headerItem()->height()); + canvas->rootObject()->setProperty("showHeader", false); + + + // Test keys + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_VERIFY(qGuiApp->focusWindow() == canvas); + + listview->setCurrentIndex(0); + + QTest::keyClick(canvas, Qt::Key_Down); + QCOMPARE(listview->currentIndex(), 1); + + QTest::keyClick(canvas, Qt::Key_Up); + QCOMPARE(listview->currentIndex(), 0); + + // hold down Key_Down + for (int i=0; icurrentIndex(), i+1); + } + QTest::keyRelease(canvas, Qt::Key_Down); + QTRY_COMPARE(listview->currentIndex(), model.count()-1); + QTRY_COMPARE(listview->contentY(), 280.0); + + // hold down Key_Up + for (int i=model.count()-1; i > 0; i--) { + QTest::simulateEvent(canvas, true, Qt::Key_Up, Qt::NoModifier, "", true); + QTRY_COMPARE(listview->currentIndex(), i-1); + } + QTest::keyRelease(canvas, Qt::Key_Up); + QTRY_COMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(listview->contentY(), 0.0); + + + // turn off auto highlight + listview->setHighlightFollowsCurrentItem(false); + QVERIFY(listview->highlightFollowsCurrentItem() == false); + + QVERIFY(listview->highlightItem()); + qreal hlPos = listview->highlightItem()->y(); + + listview->setCurrentIndex(4); + QTRY_COMPARE(listview->highlightItem()->y(), hlPos); + + // insert item before currentIndex + listview->setCurrentIndex(28); + model.insertItem(0, "Foo", "1111"); + QTRY_COMPARE(canvas->rootObject()->property("current").toInt(), 29); + + // check removing highlight by setting currentIndex to -1; + listview->setCurrentIndex(-1); + + QCOMPARE(listview->currentIndex(), -1); + QVERIFY(!listview->highlightItem()); + QVERIFY(!listview->currentItem()); + + delete canvas; +} + +void tst_QQuickListView::noCurrentIndex() +{ + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), QString::number(i)); + + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + QString filename(TESTDATA("listview-noCurrent.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // current index should be -1 at startup + // and we should not have a currentItem or highlightItem + QCOMPARE(listview->currentIndex(), -1); + QCOMPARE(listview->contentY(), 0.0); + QVERIFY(!listview->highlightItem()); + QVERIFY(!listview->currentItem()); + + listview->setCurrentIndex(2); + QCOMPARE(listview->currentIndex(), 2); + QVERIFY(listview->highlightItem()); + QVERIFY(listview->currentItem()); + + delete canvas; +} + +void tst_QQuickListView::itemList() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("itemlist.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "view"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickVisualItemModel *model = canvas->rootObject()->findChild("itemModel"); + QTRY_VERIFY(model != 0); + + QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(listview->currentIndex(), 0); + + QQuickItem *item = findItem(contentItem, "item1"); + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), 0.0); + QCOMPARE(item->height(), listview->height()); + + QQuickText *text = findItem(contentItem, "text1"); + QTRY_VERIFY(text); + QTRY_COMPARE(text->text(), QLatin1String("index: 0")); + + listview->setCurrentIndex(2); + + item = findItem(contentItem, "item3"); + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), 480.0); + + text = findItem(contentItem, "text3"); + QTRY_VERIFY(text); + QTRY_COMPARE(text->text(), QLatin1String("index: 2")); + + delete canvas; +} + +void tst_QQuickListView::cacheBuffer() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 90; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + QTRY_VERIFY(listview->delegate() != 0); + QTRY_VERIFY(listview->model() != 0); + QTRY_VERIFY(listview->highlight() != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*20); + } + + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + testObject->setCacheBuffer(200); + QTRY_VERIFY(listview->cacheBuffer() == 200); + + // items will be created one at a time + for (int i = itemCount; i < qMin(itemCount+10,model.count()); ++i) { + QVERIFY(findItem(listview, "wrapper", i) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(listview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + int newItemCount = 0; + newItemCount = findItems(contentItem, "wrapper").count(); + + // Confirm items positioned correctly + for (int i = 0; i < model.count() && i < newItemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*20); + } + + // move view and confirm items in view are visible immediately and outside are created async + listview->setContentY(300); + + for (int i = 15; i < 32; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QVERIFY(item); + QVERIFY(item->y() == i*20); + } + + QVERIFY(findItem(listview, "wrapper", 32) == 0); + + // ensure buffered items are created + for (int i = 32; i < qMin(41,model.count()); ++i) { + QQuickItem *item = 0; + while (!item) { + qGuiApp->processEvents(); // allow refill to happen + bool b = false; + controller.incubateWhile(&b); + item = findItem(listview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::positionViewAtIndex() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position on a currently visible item + listview->positionViewAtIndex(3, QQuickListView::Beginning); + QTRY_COMPARE(listview->contentY(), 60.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 3; i < model.count() && i < itemCount-3-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position on an item beyond the visible items + listview->positionViewAtIndex(22, QQuickListView::Beginning); + QTRY_COMPARE(listview->contentY(), 440.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 22; i < model.count() && i < itemCount-22-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position on an item that would leave empty space if positioned at the top + listview->positionViewAtIndex(28, QQuickListView::Beginning); + QTRY_COMPARE(listview->contentY(), 480.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 24; i < model.count() && i < itemCount-24-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position at the beginning again + listview->positionViewAtIndex(0, QQuickListView::Beginning); + QTRY_COMPARE(listview->contentY(), 0.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount-1; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position at End using last index + listview->positionViewAtIndex(model.count()-1, QQuickListView::End); + QTRY_COMPARE(listview->contentY(), 480.); + + // Confirm items positioned correctly + itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 24; i < model.count(); ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + // Position at End + listview->positionViewAtIndex(20, QQuickListView::End); + QTRY_COMPARE(listview->contentY(), 100.); + + // Position in Center + listview->positionViewAtIndex(15, QQuickListView::Center); + QTRY_COMPARE(listview->contentY(), 150.); + + // Ensure at least partially visible + listview->positionViewAtIndex(15, QQuickListView::Visible); + QTRY_COMPARE(listview->contentY(), 150.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QQuickListView::Visible); + QTRY_COMPARE(listview->contentY(), 302.); + + listview->setContentY(320); + listview->positionViewAtIndex(15, QQuickListView::Visible); + QTRY_COMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QQuickListView::Visible); + QTRY_COMPARE(listview->contentY(), 85.); + + listview->setContentY(75); + listview->positionViewAtIndex(20, QQuickListView::Visible); + QTRY_COMPARE(listview->contentY(), 100.); + + // Ensure completely visible + listview->setContentY(120); + listview->positionViewAtIndex(20, QQuickListView::Contain); + QTRY_COMPARE(listview->contentY(), 120.); + + listview->setContentY(302); + listview->positionViewAtIndex(15, QQuickListView::Contain); + QTRY_COMPARE(listview->contentY(), 300.); + + listview->setContentY(85); + listview->positionViewAtIndex(20, QQuickListView::Contain); + QTRY_COMPARE(listview->contentY(), 100.); + + // positionAtBeginnging + listview->positionViewAtBeginning(); + QTRY_COMPARE(listview->contentY(), 0.); + + listview->setContentY(80); + canvas->rootObject()->setProperty("showHeader", true); + listview->positionViewAtBeginning(); + QTRY_COMPARE(listview->contentY(), -30.); + + // positionAtEnd + listview->positionViewAtEnd(); + QTRY_COMPARE(listview->contentY(), 480.); // 40*20 - 320 + + listview->setContentY(80); + canvas->rootObject()->setProperty("showFooter", true); + listview->positionViewAtEnd(); + QTRY_COMPARE(listview->contentY(), 510.); + + // set current item to outside visible view, position at beginning + // and ensure highlight moves to current item + listview->setCurrentIndex(1); + listview->positionViewAtBeginning(); + QTRY_COMPARE(listview->contentY(), -30.); + QVERIFY(listview->highlightItem()); + QCOMPARE(listview->highlightItem()->y(), 20.); + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::resetModel() +{ + QQuickView *canvas = createView(); + + QStringList strings; + strings << "one" << "two" << "three"; + QStringListModel model(strings); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(listview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(contentItem, "displayText", i); + QTRY_VERIFY(display != 0); + QTRY_COMPARE(display->text(), strings.at(i)); + } + + strings.clear(); + strings << "four" << "five" << "six" << "seven"; + model.setStringList(strings); + + QTRY_COMPARE(listview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(contentItem, "displayText", i); + QTRY_VERIFY(display != 0); + QTRY_COMPARE(display->text(), strings.at(i)); + } + + delete canvas; +} + +void tst_QQuickListView::propertyChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickListView *listView = canvas->rootObject()->findChild("listView"); + QTRY_VERIFY(listView); + + QSignalSpy highlightFollowsCurrentItemSpy(listView, SIGNAL(highlightFollowsCurrentItemChanged())); + QSignalSpy preferredHighlightBeginSpy(listView, SIGNAL(preferredHighlightBeginChanged())); + QSignalSpy preferredHighlightEndSpy(listView, SIGNAL(preferredHighlightEndChanged())); + QSignalSpy highlightRangeModeSpy(listView, SIGNAL(highlightRangeModeChanged())); + QSignalSpy keyNavigationWrapsSpy(listView, SIGNAL(keyNavigationWrapsChanged())); + QSignalSpy cacheBufferSpy(listView, SIGNAL(cacheBufferChanged())); + QSignalSpy snapModeSpy(listView, SIGNAL(snapModeChanged())); + + QTRY_COMPARE(listView->highlightFollowsCurrentItem(), true); + QTRY_COMPARE(listView->preferredHighlightBegin(), 0.0); + QTRY_COMPARE(listView->preferredHighlightEnd(), 0.0); + QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::ApplyRange); + QTRY_COMPARE(listView->isWrapEnabled(), true); + QTRY_COMPARE(listView->cacheBuffer(), 10); + QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapToItem); + + listView->setHighlightFollowsCurrentItem(false); + listView->setPreferredHighlightBegin(1.0); + listView->setPreferredHighlightEnd(1.0); + listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); + listView->setWrapEnabled(false); + listView->setCacheBuffer(3); + listView->setSnapMode(QQuickListView::SnapOneItem); + + QTRY_COMPARE(listView->highlightFollowsCurrentItem(), false); + QTRY_COMPARE(listView->preferredHighlightBegin(), 1.0); + QTRY_COMPARE(listView->preferredHighlightEnd(), 1.0); + QTRY_COMPARE(listView->highlightRangeMode(), QQuickListView::StrictlyEnforceRange); + QTRY_COMPARE(listView->isWrapEnabled(), false); + QTRY_COMPARE(listView->cacheBuffer(), 3); + QTRY_COMPARE(listView->snapMode(), QQuickListView::SnapOneItem); + + QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1); + QTRY_COMPARE(preferredHighlightBeginSpy.count(),1); + QTRY_COMPARE(preferredHighlightEndSpy.count(),1); + QTRY_COMPARE(highlightRangeModeSpy.count(),1); + QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); + QTRY_COMPARE(cacheBufferSpy.count(),1); + QTRY_COMPARE(snapModeSpy.count(),1); + + listView->setHighlightFollowsCurrentItem(false); + listView->setPreferredHighlightBegin(1.0); + listView->setPreferredHighlightEnd(1.0); + listView->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); + listView->setWrapEnabled(false); + listView->setCacheBuffer(3); + listView->setSnapMode(QQuickListView::SnapOneItem); + + QTRY_COMPARE(highlightFollowsCurrentItemSpy.count(),1); + QTRY_COMPARE(preferredHighlightBeginSpy.count(),1); + QTRY_COMPARE(preferredHighlightEndSpy.count(),1); + QTRY_COMPARE(highlightRangeModeSpy.count(),1); + QTRY_COMPARE(keyNavigationWrapsSpy.count(),1); + QTRY_COMPARE(cacheBufferSpy.count(),1); + QTRY_COMPARE(snapModeSpy.count(),1); + + delete canvas; +} + +void tst_QQuickListView::componentChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickListView *listView = canvas->rootObject()->findChild("listView"); + QTRY_VERIFY(listView); + + QDeclarativeComponent component(canvas->engine()); + component.setData("import QtQuick 2.0; Rectangle { color: \"blue\"; }", QUrl::fromLocalFile("")); + + QDeclarativeComponent delegateComponent(canvas->engine()); + delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); + + QSignalSpy highlightSpy(listView, SIGNAL(highlightChanged())); + QSignalSpy delegateSpy(listView, SIGNAL(delegateChanged())); + QSignalSpy headerSpy(listView, SIGNAL(headerChanged())); + QSignalSpy footerSpy(listView, SIGNAL(footerChanged())); + + listView->setHighlight(&component); + listView->setHeader(&component); + listView->setFooter(&component); + listView->setDelegate(&delegateComponent); + + QTRY_COMPARE(listView->highlight(), &component); + QTRY_COMPARE(listView->header(), &component); + QTRY_COMPARE(listView->footer(), &component); + QTRY_COMPARE(listView->delegate(), &delegateComponent); + + QTRY_COMPARE(highlightSpy.count(),1); + QTRY_COMPARE(delegateSpy.count(),1); + QTRY_COMPARE(headerSpy.count(),1); + QTRY_COMPARE(footerSpy.count(),1); + + listView->setHighlight(&component); + listView->setHeader(&component); + listView->setFooter(&component); + listView->setDelegate(&delegateComponent); + + QTRY_COMPARE(highlightSpy.count(),1); + QTRY_COMPARE(delegateSpy.count(),1); + QTRY_COMPARE(headerSpy.count(),1); + QTRY_COMPARE(footerSpy.count(),1); + + delete canvas; +} + +void tst_QQuickListView::modelChanges() +{ + QQuickView *canvas = createView(); + QTRY_VERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychangestest.qml"))); + + QQuickListView *listView = canvas->rootObject()->findChild("listView"); + QTRY_VERIFY(listView); + + QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); + QTRY_VERIFY(alternateModel); + QVariant modelVariant = QVariant::fromValue(alternateModel); + QSignalSpy modelSpy(listView, SIGNAL(modelChanged())); + + listView->setModel(modelVariant); + QTRY_COMPARE(listView->model(), modelVariant); + QTRY_COMPARE(modelSpy.count(),1); + + listView->setModel(modelVariant); + QTRY_COMPARE(modelSpy.count(),1); + + listView->setModel(QVariant()); + QTRY_COMPARE(modelSpy.count(),2); + + delete canvas; +} + +void tst_QQuickListView::QTBUG_9791() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("strictlyenforcerange.qml"))); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + QTRY_VERIFY(listview->delegate() != 0); + QTRY_VERIFY(listview->model() != 0); + + QMetaObject::invokeMethod(listview, "fillModel"); + qApp->processEvents(); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + QCOMPARE(itemCount, 3); + + for (int i = 0; i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), i*300.0); + } + + // check that view is positioned correctly + QTRY_COMPARE(listview->contentX(), 590.0); + + delete canvas; +} + +void tst_QQuickListView::manualHighlight() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + QString filename(TESTDATA("manual-highlight.qml")); + canvas->setSource(QUrl::fromLocalFile(filename)); + + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(listview->currentIndex(), 0); + QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 0)); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); + + listview->setCurrentIndex(2); + + QTRY_COMPARE(listview->currentIndex(), 2); + QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); + + // QTBUG-15972 + listview->positionViewAtIndex(3, QQuickListView::Contain); + + QTRY_COMPARE(listview->currentIndex(), 2); + QTRY_COMPARE(listview->currentItem(), findItem(contentItem, "wrapper", 2)); + QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y()); + + delete canvas; +} + +void tst_QQuickListView::QTBUG_11105() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_VERIFY(item->y() == i*20); + } + + listview->positionViewAtIndex(20, QQuickListView::Beginning); + QCOMPARE(listview->contentY(), 280.); + + TestModel model2; + for (int i = 0; i < 5; i++) + model2.addItem("Item" + QString::number(i), ""); + + ctxt->setContextProperty("testModel", &model2); + + itemCount = findItems(contentItem, "wrapper").count(); + QCOMPARE(itemCount, 5); + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::header() +{ + QFETCH(QQuickListView::Orientation, orientation); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QPointF, initialHeaderPos); + QFETCH(QPointF, firstDelegatePos); + QFETCH(QPointF, initialContentPos); + QFETCH(QPointF, changedHeaderPos); + QFETCH(QPointF, changedContentPos); + QFETCH(QPointF, resizeContentPos); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QQuickView *canvas = createView(); + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->rootContext()->setContextProperty("initialViewWidth", 240); + canvas->rootContext()->setContextProperty("initialViewHeight", 320); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *header = findItem(contentItem, "header"); + QVERIFY(header); + + QVERIFY(header == listview->headerItem()); + + QCOMPARE(header->width(), 100.); + QCOMPARE(header->height(), 30.); + QCOMPARE(header->pos(), initialHeaderPos); + QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); + + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + model.clear(); + QCOMPARE(header->pos(), initialHeaderPos); // header should stay where it is + + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QSignalSpy headerItemSpy(listview, SIGNAL(headerItemChanged())); + QMetaObject::invokeMethod(canvas->rootObject(), "changeHeader"); + + QCOMPARE(headerItemSpy.count(), 1); + + header = findItem(contentItem, "header"); + QVERIFY(!header); + header = findItem(contentItem, "header2"); + QVERIFY(header); + + QVERIFY(header == listview->headerItem()); + + QCOMPARE(header->pos(), changedHeaderPos); + QCOMPARE(header->width(), 50.); + QCOMPARE(header->height(), 20.); + QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos); + QCOMPARE(item->pos(), firstDelegatePos); + + delete canvas; + + + // QTBUG-21207 header should become visible if view resizes from initial empty size + + canvas = createView(); + canvas->rootContext()->setContextProperty("testModel", &model); + canvas->rootContext()->setContextProperty("initialViewWidth", 0.0); + canvas->rootContext()->setContextProperty("initialViewHeight", 0.0); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("header.qml"))); + + listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + + listview->setWidth(240); + listview->setHeight(320); + QTRY_COMPARE(listview->headerItem()->pos(), initialHeaderPos); + QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); + + + delete canvas; +} + +void tst_QQuickListView::header_data() +{ + QTest::addColumn("orientation"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("initialHeaderPos"); + QTest::addColumn("changedHeaderPos"); + QTest::addColumn("initialContentPos"); + QTest::addColumn("changedContentPos"); + QTest::addColumn("firstDelegatePos"); + QTest::addColumn("resizeContentPos"); + + // header1 = 100 x 30 + // header2 = 50 x 20 + // delegates = 240 x 20 + // view width = 240 + + // header above items, top left + QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, 0) + << QPointF(0, -10); + + // header above items, top right + QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, -30) + << QPointF(0, -20) + << QPointF(0, 0) + << QPointF(0, -10); + + // header to left of items + QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight + << QPointF(-100, 0) + << QPointF(-50, 0) + << QPointF(-100, 0) + << QPointF(-50, 0) + << QPointF(0, 0) + << QPointF(-40, 0); + + // header to right of items + QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(-240 + 100, 0) + << QPointF(-240 + 50, 0) + << QPointF(-240, 0) + << QPointF(-240 + 40, 0); +} + +void tst_QQuickListView::header_delayItemCreation() +{ + QQuickView *canvas = createView(); + + TestModel model; + + canvas->rootContext()->setContextProperty("setCurrentToZero", QVariant(false)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("fillModelOnComponentCompleted.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); + + QCOMPARE(listview->contentY(), -header->height()); + + model.clear(); + QTRY_COMPARE(header->y(), -header->height()); + + delete canvas; +} + +void tst_QQuickListView::footer() +{ + QFETCH(QQuickListView::Orientation, orientation); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(QPointF, initialFooterPos); + QFETCH(QPointF, firstDelegatePos); + QFETCH(QPointF, initialContentPos); + QFETCH(QPointF, changedFooterPos); + QFETCH(QPointF, changedContentPos); + QFETCH(QPointF, resizeContentPos); + + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 3; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("footer.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickText *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + + QVERIFY(footer == listview->footerItem()); + + QCOMPARE(footer->pos(), initialFooterPos); + QCOMPARE(footer->width(), 100.); + QCOMPARE(footer->height(), 30.); + QCOMPARE(QPointF(listview->contentX(), listview->contentY()), initialContentPos); + + QQuickItem *item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + // remove one item + model.removeItem(1); + + if (orientation == QQuickListView::Vertical) { + QTRY_COMPARE(footer->y(), initialFooterPos.y() - 20); // delegate height = 20 + } else { + QTRY_COMPARE(footer->x(), layoutDirection == Qt::LeftToRight ? + initialFooterPos.x() - 40 : initialFooterPos.x() + 40); // delegate width = 40 + } + + // remove all items + model.clear(); + + QPointF posWhenNoItems(0, 0); + if (orientation == QQuickListView::Horizontal && layoutDirection == Qt::RightToLeft) + posWhenNoItems.setX(-100); + QTRY_COMPARE(footer->pos(), posWhenNoItems); + + // if header is present, it's at a negative pos, so the footer should not move + canvas->rootObject()->setProperty("showHeader", true); + QTRY_COMPARE(footer->pos(), posWhenNoItems); + canvas->rootObject()->setProperty("showHeader", false); + + // add 30 items + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QSignalSpy footerItemSpy(listview, SIGNAL(footerItemChanged())); + QMetaObject::invokeMethod(canvas->rootObject(), "changeFooter"); + + QCOMPARE(footerItemSpy.count(), 1); + + footer = findItem(contentItem, "footer"); + QVERIFY(!footer); + footer = findItem(contentItem, "footer2"); + QVERIFY(footer); + + QVERIFY(footer == listview->footerItem()); + + QCOMPARE(footer->pos(), changedFooterPos); + QCOMPARE(footer->width(), 50.); + QCOMPARE(footer->height(), 20.); + QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), changedContentPos); + + item = findItem(contentItem, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->pos(), firstDelegatePos); + + listview->positionViewAtEnd(); + footer->setHeight(10); + footer->setWidth(40); + QTRY_COMPARE(QPointF(listview->contentX(), listview->contentY()), resizeContentPos); + + delete canvas; +} + +void tst_QQuickListView::footer_data() +{ + QTest::addColumn("orientation"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("initialFooterPos"); + QTest::addColumn("changedFooterPos"); + QTest::addColumn("initialContentPos"); + QTest::addColumn("changedContentPos"); + QTest::addColumn("firstDelegatePos"); + QTest::addColumn("resizeContentPos"); + + // footer1 = 100 x 30 + // footer2 = 50 x 20 + // delegates = 40 x 20 + // view width = 240 + // view height = 320 + + // footer below items, bottom left + QTest::newRow("vertical, layout left to right") << QQuickListView::Vertical << Qt::LeftToRight + << QPointF(0, 3 * 20) + << QPointF(0, 30 * 20) // added 30 items + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 30 * 20 - 320 + 10); + + // footer below items, bottom right + QTest::newRow("vertical, layout right to left") << QQuickListView::Vertical << Qt::RightToLeft + << QPointF(0, 3 * 20) + << QPointF(0, 30 * 20) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 30 * 20 - 320 + 10); + + // footer to right of items + QTest::newRow("horizontal, layout left to right") << QQuickListView::Horizontal << Qt::LeftToRight + << QPointF(40 * 3, 0) + << QPointF(40 * 30, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(0, 0) + << QPointF(40 * 30 - 240 + 40, 0); + + // footer to left of items + QTest::newRow("horizontal, layout right to left") << QQuickListView::Horizontal << Qt::RightToLeft + << QPointF(-(40 * 3) - 100, 0) + << QPointF(-(40 * 30) - 50, 0) // 50 = new footer width + << QPointF(-240, 0) + << QPointF(-240, 0) + << QPointF(-40, 0) + << QPointF(-(40 * 30) - 40, 0); +} + +class LVAccessor : public QQuickListView +{ +public: + qreal minY() const { return minYExtent(); } + qreal maxY() const { return maxYExtent(); } + qreal minX() const { return minXExtent(); } + qreal maxX() const { return maxXExtent(); } +}; + +void tst_QQuickListView::headerFooter() +{ + { + // Vertical + QQuickView *canvas = createView(); + + TestModel model; + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->y(), -header->height()); + + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->y(), 0.); + + QCOMPARE(static_cast(listview)->minY(), header->height()); + QCOMPARE(static_cast(listview)->maxY(), header->height()); + + delete canvas; + } + { + // Horizontal + QQuickView *canvas = createView(); + + TestModel model; + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); + canvas->rootObject()->setProperty("horizontal", true); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->x(), -header->width()); + + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->x(), 0.); + + QCOMPARE(static_cast(listview)->minX(), header->width()); + QCOMPARE(static_cast(listview)->maxX(), header->width()); + + delete canvas; + } + { + // Horizontal RTL + QQuickView *canvas = createView(); + + TestModel model; + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("headerfooter.qml"))); + canvas->rootObject()->setProperty("horizontal", true); + canvas->rootObject()->setProperty("rtl", true); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickItem *header = findItem(contentItem, "header"); + QVERIFY(header); + QCOMPARE(header->x(), 0.); + + QQuickItem *footer = findItem(contentItem, "footer"); + QVERIFY(footer); + QCOMPARE(footer->x(), -footer->width()); + + QCOMPARE(static_cast(listview)->minX(), 240. - header->width()); + QCOMPARE(static_cast(listview)->maxX(), 240. - header->width()); + + delete canvas; + } +} + +void tst_QQuickListView::resizeView() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*20.); + } + + QVariant heightRatio; + QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); + QCOMPARE(heightRatio.toReal(), 0.4); + + listview->setHeight(200); + + QMetaObject::invokeMethod(canvas->rootObject(), "heightRatio", Q_RETURN_ARG(QVariant, heightRatio)); + QCOMPARE(heightRatio.toReal(), 0.25); + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::resizeViewAndRepaint() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + for (int i = 0; i < 40; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("initialHeight", 100); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizeview.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // item at index 10 should not be currently visible + QVERIFY(!findItem(contentItem, "wrapper", 10)); + + listview->setHeight(320); + QTRY_VERIFY(findItem(contentItem, "wrapper", 10)); + + listview->setHeight(100); + QTRY_VERIFY(!findItem(contentItem, "wrapper", 10)); + + delete canvas; +} + +void tst_QQuickListView::sizeLessThan1() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("sizelessthan1.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // Confirm items positioned correctly + int itemCount = findItems(contentItem, "wrapper").count(); + for (int i = 0; i < model.count() && i < itemCount; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + if (!item) qWarning() << "Item" << i << "not found"; + QTRY_VERIFY(item); + QTRY_COMPARE(item->y(), i*0.5); + } + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::QTBUG_14821() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug14821.qml"))); + qApp->processEvents(); + + QQuickListView *listview = qobject_cast(canvas->rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + listview->decrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 99); + + listview->incrementCurrentIndex(); + QCOMPARE(listview->currentIndex(), 0); + + delete canvas; +} + +void tst_QQuickListView::resizeDelegate() +{ + QQuickView *canvas = createView(); + canvas->show(); + + QStringList strings; + for (int i = 0; i < 30; ++i) + strings << QString::number(i); + QStringListModel model(strings); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QCOMPARE(listview->count(), model.rowCount()); + + listview->setCurrentIndex(25); + listview->setContentY(0); + QTest::qWait(300); + + for (int i = 0; i < 16; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QCOMPARE(item->y(), i*20.0); + } + + QCOMPARE(listview->currentItem()->y(), 500.0); + QTRY_COMPARE(listview->highlightItem()->y(), 500.0); + + canvas->rootObject()->setProperty("delegateHeight", 30); + QTest::qWait(300); + + for (int i = 0; i < 11; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QTRY_COMPARE(item->y(), i*30.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 750.0); + QTRY_COMPARE(listview->highlightItem()->y(), 750.0); + + listview->setCurrentIndex(1); + listview->positionViewAtIndex(25, QQuickListView::Beginning); + listview->positionViewAtIndex(5, QQuickListView::Beginning); + + for (int i = 5; i < 16; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QCOMPARE(item->y(), i*30.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 30.0); + QTRY_COMPARE(listview->highlightItem()->y(), 30.0); + + canvas->rootObject()->setProperty("delegateHeight", 20); + QTest::qWait(300); + + for (int i = 5; i < 11; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QTRY_COMPARE(item->y(), 150 + (i-5)*20.0); + } + + QTRY_COMPARE(listview->currentItem()->y(), 70.0); + QTRY_COMPARE(listview->highlightItem()->y(), 70.0); + + delete canvas; +} + +void tst_QQuickListView::resizeFirstDelegate() +{ + // QTBUG-20712: Content Y jumps constantly if first delegate height == 0 + // and other delegates have height > 0 + + QSKIP("Test unstable - QTBUG-22872"); + + QQuickView *canvas = createView(); + canvas->show(); + + // bug only occurs when all items in the model are visible + TestModel model; + for (int i = 0; i < 10; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickItem *item = 0; + for (int i = 0; i < model.count(); ++i) { + item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QCOMPARE(item->y(), i*20.0); + } + + item = findItem(contentItem, "wrapper", 0); + item->setHeight(0); + + // check the content y has not jumped up and down + QCOMPARE(listview->contentY(), 0.0); + QSignalSpy spy(listview, SIGNAL(contentYChanged())); + QTest::qWait(100); + QCOMPARE(spy.count(), 0); + + for (int i = 1; i < model.count(); ++i) { + item = findItem(contentItem, "wrapper", i); + QVERIFY(item != 0); + QTRY_COMPARE(item->y(), (i-1)*20.0); + } + + + // QTBUG-22014: refill doesn't clear items scrolling off the top of the + // list if they follow a zero-sized delegate + + for (int i = 0; i < 10; i++) + model.addItem("Item" + QString::number(i), ""); + + item = findItem(contentItem, "wrapper", 1); + QVERIFY(item); + item->setHeight(0); + + listview->setCurrentIndex(19); + qApp->processEvents(); + + // items 0-2 should have been deleted + for (int i=0; i<3; i++) { + QTRY_VERIFY(!findItem(contentItem, "wrapper", i)); + } + + delete testObject; + delete canvas; +} + +void tst_QQuickListView::QTBUG_16037() +{ + QQuickView *canvas = createView(); + canvas->show(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("qtbug16037.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "listview"); + QTRY_VERIFY(listview != 0); + + QVERIFY(listview->contentHeight() <= 0.0); + + QMetaObject::invokeMethod(canvas->rootObject(), "setModel"); + + QTRY_COMPARE(listview->contentHeight(), 80.0); + + delete canvas; +} + +void tst_QQuickListView::indexAt() +{ + QQuickView *canvas = createView(); + + TestModel model; + for (int i = 0; i < 30; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("listviewtest.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QCOMPARE(listview->indexAt(0,0), 0); + QCOMPARE(listview->indexAt(0,19), 0); + QCOMPARE(listview->indexAt(239,19), 0); + QCOMPARE(listview->indexAt(0,20), 1); + QCOMPARE(listview->indexAt(240,20), -1); + + delete canvas; + delete testObject; +} + +void tst_QQuickListView::incrementalModel() +{ + QQuickView *canvas = createView(); + + IncrementalModel model; + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaylist.qml"))); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QTRY_COMPARE(listview->count(), 20); + + listview->positionViewAtIndex(10, QQuickListView::Beginning); + + QTRY_COMPARE(listview->count(), 25); + + delete canvas; +} + +void tst_QQuickListView::onAdd() +{ + QFETCH(int, initialItemCount); + QFETCH(int, itemsToAdd); + + const int delegateHeight = 10; + TestModel2 model; + + // these initial items should not trigger ListView.onAdd + for (int i=0; isetGeometry(0,0,200, delegateHeight * (initialItemCount + itemsToAdd)); + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("delegateHeight", delegateHeight); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); + + QObject *object = canvas->rootObject(); + object->setProperty("width", canvas->width()); + object->setProperty("height", canvas->height()); + qApp->processEvents(); + + QList > items; + for (int i=0; irootObject()->property("count").toInt(), model.count()); + + QVariantList result = object->property("addedDelegates").toList(); + QCOMPARE(result.count(), items.count()); + for (int i=0; i("initialItemCount"); + QTest::addColumn("itemsToAdd"); + + QTest::newRow("0, add 1") << 0 << 1; + QTest::newRow("0, add 2") << 0 << 2; + QTest::newRow("0, add 10") << 0 << 10; + + QTest::newRow("1, add 1") << 1 << 1; + QTest::newRow("1, add 2") << 1 << 2; + QTest::newRow("1, add 10") << 1 << 10; + + QTest::newRow("5, add 1") << 5 << 1; + QTest::newRow("5, add 2") << 5 << 2; + QTest::newRow("5, add 10") << 5 << 10; +} + +void tst_QQuickListView::onRemove() +{ + QFETCH(int, initialItemCount); + QFETCH(int, indexToRemove); + QFETCH(int, removeCount); + + const int delegateHeight = 10; + TestModel2 model; + for (int i=0; irootContext(); + ctxt->setContextProperty("testModel", &model); + ctxt->setContextProperty("delegateHeight", delegateHeight); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("attachedSignals.qml"))); + QObject *object = canvas->rootObject(); + + model.removeItems(indexToRemove, removeCount); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + + QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount)); + + delete canvas; +} + +void tst_QQuickListView::onRemove_data() +{ + QTest::addColumn("initialItemCount"); + QTest::addColumn("indexToRemove"); + QTest::addColumn("removeCount"); + + QTest::newRow("remove first") << 1 << 0 << 1; + QTest::newRow("two items, remove first") << 2 << 0 << 1; + QTest::newRow("two items, remove last") << 2 << 1 << 1; + QTest::newRow("two items, remove all") << 2 << 0 << 2; + + QTest::newRow("four items, remove first") << 4 << 0 << 1; + QTest::newRow("four items, remove 0-2") << 4 << 0 << 2; + QTest::newRow("four items, remove 1-3") << 4 << 1 << 2; + QTest::newRow("four items, remove 2-4") << 4 << 2 << 2; + QTest::newRow("four items, remove last") << 4 << 3 << 1; + QTest::newRow("four items, remove all") << 4 << 0 << 4; + + QTest::newRow("ten items, remove 1-8") << 10 << 0 << 8; + QTest::newRow("ten items, remove 2-7") << 10 << 2 << 5; + QTest::newRow("ten items, remove 4-10") << 10 << 4 << 6; +} + +void tst_QQuickListView::rightToLeft() +{ + QQuickView *canvas = createView(); + canvas->setGeometry(0,0,640,320); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); + qApp->processEvents(); + + QVERIFY(canvas->rootObject() != 0); + QQuickListView *listview = findItem(canvas->rootObject(), "view"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QQuickVisualItemModel *model = canvas->rootObject()->findChild("itemModel"); + QTRY_VERIFY(model != 0); + + QTRY_VERIFY(model->count() == 3); + QTRY_COMPARE(listview->currentIndex(), 0); + + // initial position at first item, right edge aligned + QCOMPARE(listview->contentX(), -640.); + + QQuickItem *item = findItem(contentItem, "item1"); + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), -100.0); + QCOMPARE(item->height(), listview->height()); + + QQuickText *text = findItem(contentItem, "text1"); + QTRY_VERIFY(text); + QTRY_COMPARE(text->text(), QLatin1String("index: 0")); + + listview->setCurrentIndex(2); + + item = findItem(contentItem, "item3"); + QTRY_VERIFY(item); + QTRY_COMPARE(item->x(), -540.0); + + text = findItem(contentItem, "text3"); + QTRY_VERIFY(text); + QTRY_COMPARE(text->text(), QLatin1String("index: 2")); + + QCOMPARE(listview->contentX(), -640.); + + // Ensure resizing maintains position relative to right edge + qobject_cast(canvas->rootObject())->setWidth(600); + QTRY_COMPARE(listview->contentX(), -600.); + + delete canvas; +} + +void tst_QQuickListView::test_mirroring() +{ + QQuickView *canvasA = createView(); + canvasA->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); + QQuickListView *listviewA = findItem(canvasA->rootObject(), "view"); + QTRY_VERIFY(listviewA != 0); + + QQuickView *canvasB = createView(); + canvasB->setSource(QUrl::fromLocalFile(TESTDATA("rightToLeft.qml"))); + QQuickListView *listviewB = findItem(canvasB->rootObject(), "view"); + QTRY_VERIFY(listviewA != 0); + qApp->processEvents(); + + QList objectNames; + objectNames << "item1" << "item2"; // << "item3" + + listviewA->setProperty("layoutDirection", Qt::LeftToRight); + listviewB->setProperty("layoutDirection", Qt::RightToLeft); + QCOMPARE(listviewA->layoutDirection(), listviewA->effectiveLayoutDirection()); + + // LTR != RTL + foreach (const QString objectName, objectNames) + QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); + + listviewA->setProperty("layoutDirection", Qt::LeftToRight); + listviewB->setProperty("layoutDirection", Qt::LeftToRight); + + // LTR == LTR + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); + + QVERIFY(listviewB->layoutDirection() == listviewB->effectiveLayoutDirection()); + QQuickItemPrivate::get(listviewB)->setLayoutMirror(true); + QVERIFY(listviewB->layoutDirection() != listviewB->effectiveLayoutDirection()); + + // LTR != LTR+mirror + foreach (const QString objectName, objectNames) + QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); + + listviewA->setProperty("layoutDirection", Qt::RightToLeft); + + // RTL == LTR+mirror + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); + + listviewB->setProperty("layoutDirection", Qt::RightToLeft); + + // RTL != RTL+mirror + foreach (const QString objectName, objectNames) + QVERIFY(findItem(listviewA, objectName)->x() != findItem(listviewB, objectName)->x()); + + listviewA->setProperty("layoutDirection", Qt::LeftToRight); + + // LTR == RTL+mirror + foreach (const QString objectName, objectNames) + QCOMPARE(findItem(listviewA, objectName)->x(), findItem(listviewB, objectName)->x()); + + delete canvasA; + delete canvasB; +} + +void tst_QQuickListView::margins() +{ + QQuickView *canvas = createView(); + + TestModel2 model; + for (int i = 0; i < 50; i++) + model.addItem("Item" + QString::number(i), ""); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("margins.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + QCOMPARE(listview->contentY(), -30.); + QCOMPARE(listview->yOrigin(), 0.); + + // check end bound + listview->positionViewAtEnd(); + qreal pos = listview->contentY(); + listview->setContentY(pos + 80); + listview->returnToBounds(); + QTRY_COMPARE(listview->contentY(), pos + 50); + + // remove item before visible and check that top margin is maintained + // and yOrigin is updated + listview->setContentY(100); + model.removeItem(1); + QTest::qWait(100); + listview->setContentY(-50); + listview->returnToBounds(); + QCOMPARE(listview->yOrigin(), 20.); + QTRY_COMPARE(listview->contentY(), -10.); + + // reduce top margin + listview->setTopMargin(20); + QCOMPARE(listview->yOrigin(), 20.); + QTRY_COMPARE(listview->contentY(), 0.); + + // check end bound + listview->positionViewAtEnd(); + pos = listview->contentY(); + listview->setContentY(pos + 80); + listview->returnToBounds(); + QTRY_COMPARE(listview->contentY(), pos + 50); + + // reduce bottom margin + pos = listview->contentY(); + listview->setBottomMargin(40); + QCOMPARE(listview->yOrigin(), 20.); + QTRY_COMPARE(listview->contentY(), pos-10); + + delete canvas; +} + +void tst_QQuickListView::snapToItem_data() +{ + QTest::addColumn("orientation"); + QTest::addColumn("layoutDirection"); + QTest::addColumn("highlightRangeMode"); + QTest::addColumn("flickStart"); + QTest::addColumn("flickEnd"); + QTest::addColumn("snapAlignment"); + QTest::addColumn("endExtent"); + QTest::addColumn("startExtent"); + + QTest::newRow("vertical, left to right") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; + + QTest::newRow("horizontal, left to right") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::NoHighlightRange) + << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1200.0 << 0.0; + + QTest::newRow("horizontal, right to left") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::NoHighlightRange) + << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 << -240.0; + + QTest::newRow("vertical, left to right, enforce range") << QQuickListView::Vertical << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 200) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; + + QTest::newRow("horizontal, left to right, enforce range") << QQuickListView::Horizontal << Qt::LeftToRight << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(200, 20) << QPoint(20, 20) << 60.0 << 1340.0 << -20.0; + + QTest::newRow("horizontal, right to left, enforce range") << QQuickListView::Horizontal << Qt::RightToLeft << int(QQuickItemView::StrictlyEnforceRange) + << QPoint(20, 20) << QPoint(200, 20) << -60.0 << -1200.0 - 240.0 - 140.0 << -220.0; +} + +void tst_QQuickListView::snapToItem() +{ + QFETCH(QQuickListView::Orientation, orientation); + QFETCH(Qt::LayoutDirection, layoutDirection); + QFETCH(int, highlightRangeMode); + QFETCH(QPoint, flickStart); + QFETCH(QPoint, flickEnd); + QFETCH(qreal, snapAlignment); + QFETCH(qreal, endExtent); + QFETCH(qreal, startExtent); + + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("snapToItem.qml"))); + canvas->show(); + qApp->processEvents(); + + QQuickListView *listview = findItem(canvas->rootObject(), "list"); + QTRY_VERIFY(listview != 0); + + listview->setOrientation(orientation); + listview->setLayoutDirection(layoutDirection); + listview->setHighlightRangeMode(QQuickItemView::HighlightRangeMode(highlightRangeMode)); + + QQuickItem *contentItem = listview->contentItem(); + QTRY_VERIFY(contentItem != 0); + + // confirm that a flick hits an item boundary + flick(canvas, flickStart, flickEnd, 180); + QTRY_VERIFY(listview->isMoving() == false); // wait until it stops + if (orientation == QQuickListView::Vertical) + QCOMPARE(qreal(fmod(listview->contentY(),80.0)), snapAlignment); + else + QCOMPARE(qreal(fmod(listview->contentX(),80.0)), snapAlignment); + + // flick to end + do { + flick(canvas, flickStart, flickEnd, 180); + QTRY_VERIFY(listview->isMoving() == false); // wait until it stops + } while (orientation == QQuickListView::Vertical + ? !listview->isAtYEnd() + : layoutDirection == Qt::LeftToRight ? !listview->isAtXEnd() : !listview->isAtXBeginning()); + + if (orientation == QQuickListView::Vertical) + QCOMPARE(listview->contentY(), endExtent); + else + QCOMPARE(listview->contentX(), endExtent); + + // flick to start + do { + flick(canvas, flickEnd, flickStart, 180); + QTRY_VERIFY(listview->isMoving() == false); // wait until it stops + } while (orientation == QQuickListView::Vertical + ? !listview->isAtYBeginning() + : layoutDirection == Qt::LeftToRight ? !listview->isAtXBeginning() : !listview->isAtXEnd()); + + if (orientation == QQuickListView::Vertical) + QCOMPARE(listview->contentY(), startExtent); + else + QCOMPARE(listview->contentX(), startExtent); + + delete canvas; +} + +void tst_QQuickListView::qListModelInterface_items() +{ + items(); +} + +void tst_QQuickListView::qAbstractItemModel_items() +{ + items(); +} + +void tst_QQuickListView::qListModelInterface_changed() +{ + changed(); +} + +void tst_QQuickListView::qAbstractItemModel_changed() +{ + changed(); +} + +void tst_QQuickListView::qListModelInterface_inserted() +{ + inserted(); +} + +void tst_QQuickListView::qListModelInterface_inserted_more() +{ + inserted_more(); +} + +void tst_QQuickListView::qListModelInterface_inserted_more_data() +{ + inserted_more_data(); +} + +void tst_QQuickListView::qAbstractItemModel_inserted() +{ + inserted(); +} + +void tst_QQuickListView::qAbstractItemModel_inserted_more() +{ + inserted_more(); +} + +void tst_QQuickListView::qAbstractItemModel_inserted_more_data() +{ + inserted_more_data(); +} + +void tst_QQuickListView::qListModelInterface_removed() +{ + removed(false); + removed(true); +} + +void tst_QQuickListView::qAbstractItemModel_removed() +{ + removed(false); + removed(true); +} + +void tst_QQuickListView::qListModelInterface_moved() +{ + moved(); +} + +void tst_QQuickListView::qListModelInterface_moved_data() +{ + moved_data(); +} + +void tst_QQuickListView::qAbstractItemModel_moved() +{ + moved(); +} + +void tst_QQuickListView::qAbstractItemModel_moved_data() +{ + moved_data(); +} + +void tst_QQuickListView::qListModelInterface_clear() +{ + clear(); +} + +void tst_QQuickListView::qAbstractItemModel_clear() +{ + clear(); +} + +void tst_QQuickListView::creationContext() +{ + QQuickView canvas; + canvas.setGeometry(0,0,240,320); + canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); + qApp->processEvents(); + + QQuickItem *rootItem = qobject_cast(canvas.rootObject()); + QVERIFY(rootItem); + QVERIFY(rootItem->property("count").toInt() > 0); + + QQuickItem *item; + QVERIFY(item = rootItem->findChild("listItem")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); + QVERIFY(item = rootItem->findChild("header")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); + QVERIFY(item = rootItem->findChild("footer")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); + QVERIFY(item = rootItem->findChild("section")); + QCOMPARE(item->property("text").toString(), QString("Hello!")); +} + +void tst_QQuickListView::QTBUG_21742() +{ + QQuickView canvas; + canvas.setGeometry(0,0,200,200); + canvas.setSource(QUrl::fromLocalFile(TESTDATA("qtbug-21742.qml"))); + qApp->processEvents(); + + QQuickItem *rootItem = qobject_cast(canvas.rootObject()); + QVERIFY(rootItem); + QCOMPARE(rootItem->property("count").toInt(), 1); +} + +QQuickView *tst_QQuickListView::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + return canvas; +} + +void tst_QQuickListView::flick(QQuickView *canvas, const QPoint &from, const QPoint &to, int duration) +{ + const int pointCount = 5; + QPoint diff = to - from; + + // send press, five equally spaced moves, and release. + QTest::mousePress(canvas, Qt::LeftButton, 0, from); + + for (int i = 0; i < pointCount; ++i) { + QMouseEvent mv(QEvent::MouseMove, from + (i+1)*diff/pointCount, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + QTest::qWait(duration/pointCount); + QCoreApplication::processEvents(); + } + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, to); +} + +void tst_QQuickListView::asynchronous() +{ + QQuickView *canvas = createView(); + canvas->show(); + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + canvas->setSource(TESTDATA("asyncloader.qml")); + + QQuickItem *rootObject = qobject_cast(canvas->rootObject()); + QVERIFY(rootObject); + + QQuickListView *listview = 0; + while (!listview) { + bool b = false; + controller.incubateWhile(&b); + listview = rootObject->findChild("view"); + } + + // items will be created one at a time + for (int i = 0; i < 8; ++i) { + QVERIFY(findItem(listview, "wrapper", i) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(listview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + // verify positioning + QQuickItem *contentItem = listview->contentItem(); + for (int i = 0; i < 8; ++i) { + QQuickItem *item = findItem(contentItem, "wrapper", i); + QTRY_COMPARE(item->y(), i*50.0); + } + + delete canvas; +} + +QQuickItem *tst_QQuickListView::findVisibleChild(QQuickItem *parent, const QString &objectName) +{ + QQuickItem *item = 0; + QList items = parent->findChildren(objectName); + for (int i = 0; i < items.count(); ++i) { + if (items.at(i)->isVisible()) { + item = items.at(i); + break; + } + } + return item; +} +/* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index +*/ +template +T *tst_QQuickListView::findItem(QQuickItem *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), item, "index"); + if (e.evaluate().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +template +QList tst_QQuickListView::findItems(QQuickItem *parent, const QString &objectName) +{ + QList items; + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item || !item->isVisible()) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) + items.append(static_cast(item)); + items += findItems(item, objectName); + } + + return items; +} + +void tst_QQuickListView::dumpTree(QQuickItem *parent, int depth) +{ + static QString padding(" "); + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + qDebug() << padding.left(depth*2) << item; + dumpTree(item, depth+1); + } +} + +QTEST_MAIN(tst_QQuickListView) + +#include "tst_qquicklistview.moc" + diff --git a/tests/auto/qtquick2/qquickloader/data/ActiveComponent.qml b/tests/auto/qtquick2/qquickloader/data/ActiveComponent.qml new file mode 100644 index 0000000000..24c6f7ad91 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/ActiveComponent.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + id: behaviorCounter + property int behaviorCount: 0 + property int canary: 0 + + Behavior on canary { + NumberAnimation { target: behaviorCounter; property: "behaviorCount"; to: (behaviorCounter.behaviorCount + 1); duration: 0 } + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/AnchoredLoader.qml b/tests/auto/qtquick2/qquickloader/data/AnchoredLoader.qml new file mode 100644 index 0000000000..1a2a620d7f --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/AnchoredLoader.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 300 + height: 200 + color: "blue" + Loader { + objectName: "loader" + anchors.fill: parent + sourceComponent: Component { + Rectangle { color: "red"; objectName: "sourceElement" } + } + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/BigComponent.qml b/tests/auto/qtquick2/qquickloader/data/BigComponent.qml new file mode 100644 index 0000000000..df92532c43 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/BigComponent.qml @@ -0,0 +1,5015 @@ +import QtQuick 2.0 + +Item { + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} + Item {} +} diff --git a/tests/auto/qtquick2/qquickloader/data/BlueRect.qml b/tests/auto/qtquick2/qquickloader/data/BlueRect.qml new file mode 100644 index 0000000000..e96ac00f21 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/BlueRect.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Rectangle { + objectName: "blue" + width: 100 + height: 100 + color: "blue" +} diff --git a/tests/auto/qtquick2/qquickloader/data/CreationContextLoader.qml b/tests/auto/qtquick2/qquickloader/data/CreationContextLoader.qml new file mode 100644 index 0000000000..4dd73e797c --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/CreationContextLoader.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Loader { + id: myLoader + property int testProperty: 1912 + sourceComponent: loaderComponent + Component { + id: loaderComponent + Item { + Component.onCompleted: { + test = (myLoader.testProperty == 1912); + } + } + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/GraphicsWidget250x250.qml b/tests/auto/qtquick2/qquickloader/data/GraphicsWidget250x250.qml new file mode 100644 index 0000000000..dae8e3fbbb --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/GraphicsWidget250x250.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +QGraphicsWidget { + size: "250x250" +} diff --git a/tests/auto/qtquick2/qquickloader/data/GreenRect.qml b/tests/auto/qtquick2/qquickloader/data/GreenRect.qml new file mode 100644 index 0000000000..99cefaf176 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/GreenRect.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Rectangle { + width: 100; height: 100 + color: "green" + Component.onCompleted: myLoader.source = "BlueRect.qml" +} diff --git a/tests/auto/qtquick2/qquickloader/data/InitialPropertyValuesComponent.qml b/tests/auto/qtquick2/qquickloader/data/InitialPropertyValuesComponent.qml new file mode 100644 index 0000000000..24c6f7ad91 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/InitialPropertyValuesComponent.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + id: behaviorCounter + property int behaviorCount: 0 + property int canary: 0 + + Behavior on canary { + NumberAnimation { target: behaviorCounter; property: "behaviorCount"; to: (behaviorCounter.behaviorCount + 1); duration: 0 } + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/InvalidSourceComponent.qml b/tests/auto/qtquick2/qquickloader/data/InvalidSourceComponent.qml new file mode 100644 index 0000000000..7efa4a5f61 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/InvalidSourceComponent.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + RandomError +} diff --git a/tests/auto/qtquick2/qquickloader/data/NoResize.qml b/tests/auto/qtquick2/qquickloader/data/NoResize.qml new file mode 100644 index 0000000000..9b3ea6410b --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/NoResize.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Item { + width: 200; height: 80 + Loader { + source: "Rect120x60.qml" + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/NoResizeGraphicsWidget.qml b/tests/auto/qtquick2/qquickloader/data/NoResizeGraphicsWidget.qml new file mode 100644 index 0000000000..c0f51d8c35 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/NoResizeGraphicsWidget.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 80 + Loader { + source: "GraphicsWidget250x250.qml" + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/QTBUG_16928.qml b/tests/auto/qtquick2/qquickloader/data/QTBUG_16928.qml new file mode 100644 index 0000000000..903d7f0812 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/QTBUG_16928.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + color: "green" + width: loader.implicitWidth+50 + height: loader.implicitHeight+50 + + Loader { + id: loader + sourceComponent: Item { + anchors.centerIn: parent + + implicitWidth: 200 + implicitHeight: 200 + Rectangle { + color: "red" + anchors.fill: parent + } + } + anchors.fill: parent + anchors.margins: 15 + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/QTBUG_17114.qml b/tests/auto/qtquick2/qquickloader/data/QTBUG_17114.qml new file mode 100644 index 0000000000..7402037553 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/QTBUG_17114.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + property real loaderWidth: loader.width + property real loaderHeight: loader.height + width: 200 + height: 200 + + Loader { + id: loader + sourceComponent: Item { + property real iwidth: 32 + property real iheight: 32 + width: iwidth + height: iheight + } + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/Rect120x60.qml b/tests/auto/qtquick2/qquickloader/data/Rect120x60.qml new file mode 100644 index 0000000000..fc9e447e69 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/Rect120x60.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Rectangle { + width: 120 + height:60 +} diff --git a/tests/auto/qtquick2/qquickloader/data/SetSourceComponent.qml b/tests/auto/qtquick2/qquickloader/data/SetSourceComponent.qml new file mode 100644 index 0000000000..83cc358f7d --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/SetSourceComponent.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Item { + function clear() { + loader.sourceComponent = undefined + } + Component { id: comp; Rectangle { width: 100; height: 50 } } + Loader { id: loader; sourceComponent: comp } +} diff --git a/tests/auto/qtquick2/qquickloader/data/SizeGraphicsWidgetToLoader.qml b/tests/auto/qtquick2/qquickloader/data/SizeGraphicsWidgetToLoader.qml new file mode 100644 index 0000000000..2a63b4d34f --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/SizeGraphicsWidgetToLoader.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Loader { + width: 200 + height: 80 + source: "GraphicsWidget250x250.qml" +} diff --git a/tests/auto/qtquick2/qquickloader/data/SizeLoaderToGraphicsWidget.qml b/tests/auto/qtquick2/qquickloader/data/SizeLoaderToGraphicsWidget.qml new file mode 100644 index 0000000000..a9875d8e21 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/SizeLoaderToGraphicsWidget.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Loader { + source: "GraphicsWidget250x250.qml" +} diff --git a/tests/auto/qtquick2/qquickloader/data/SizeToItem.qml b/tests/auto/qtquick2/qquickloader/data/SizeToItem.qml new file mode 100644 index 0000000000..866365754f --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/SizeToItem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Loader { + source: "Rect120x60.qml" +} diff --git a/tests/auto/qtquick2/qquickloader/data/SizeToLoader.qml b/tests/auto/qtquick2/qquickloader/data/SizeToLoader.qml new file mode 100644 index 0000000000..dad18c6939 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/SizeToLoader.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Loader { + width: 200; height: 80 + source: "Rect120x60.qml" +} diff --git a/tests/auto/qtquick2/qquickloader/data/VmeError.qml b/tests/auto/qtquick2/qquickloader/data/VmeError.qml new file mode 100644 index 0000000000..0443aa9054 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/VmeError.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Rectangle { + width: 100; height: 100; color: "red" + signal somethingHappened + onSomethingHappened: QtObject {} +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.1.qml b/tests/auto/qtquick2/qquickloader/data/active.1.qml new file mode 100644 index 0000000000..2dbd1a0887 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.1.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + active: false + } + + Component { + id: inlineTestComponent + Item { + id: inlineTestItem + property int someProperty: 5 + } + } + + function doSetSource() { + loader.source = "ActiveComponent.qml"; + } + + function doSetSourceComponent() { + loader.sourceComponent = inlineTestComponent; + } + + function doSetActive() { + loader.active = true; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.2.qml b/tests/auto/qtquick2/qquickloader/data/active.2.qml new file mode 100644 index 0000000000..e561744c63 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.2.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + source: "ActiveComponent.qml"; + + property int statusChangedCount: 0 + onStatusChanged: statusChangedCount = statusChangedCount + 1 + } + + function doSetInactive() { + loader.active = false; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.3.qml b/tests/auto/qtquick2/qquickloader/data/active.3.qml new file mode 100644 index 0000000000..0fbba959bb --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.3.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + source: "ActiveComponent.qml"; + + property int sourceChangedCount: 0 + onSourceChanged: sourceChangedCount = sourceChangedCount + 1 + } + + function doSetInactive() { + loader.active = false; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.4.qml b/tests/auto/qtquick2/qquickloader/data/active.4.qml new file mode 100644 index 0000000000..63fd46e2da --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.4.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Item { + id: root + + Component { + id: inlineTestComponent + Item { + id: inlineTestItem + property int someProperty: 5 + } + } + + Loader { + id: loader + objectName: "loader" + sourceComponent: inlineTestComponent + + property int sourceComponentChangedCount: 0 + onSourceComponentChanged: sourceComponentChangedCount = sourceComponentChangedCount + 1 + } + + function doSetInactive() { + loader.active = false; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.5.qml b/tests/auto/qtquick2/qquickloader/data/active.5.qml new file mode 100644 index 0000000000..903f458a41 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.5.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + source: "ActiveComponent.qml"; + + property int itemChangedCount: 0 + onItemChanged: itemChangedCount = itemChangedCount + 1 + } + + function doSetInactive() { + loader.active = false; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.6.qml b/tests/auto/qtquick2/qquickloader/data/active.6.qml new file mode 100644 index 0000000000..f769a4e184 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.6.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + + property int activeChangedCount: 0 + onActiveChanged: activeChangedCount = activeChangedCount + 1 + } + + function doSetActive() { + loader.active = true; + } + + function doSetInactive() { + loader.active = false; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.7.qml b/tests/auto/qtquick2/qquickloader/data/active.7.qml new file mode 100644 index 0000000000..a29e932f5e --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.7.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 +Rectangle { + id: root + color: "blue" + width: 100; height: 100 + property bool success: true + + Loader { + active: false + anchors.fill: parent + sourceComponent: Rectangle { color: "red" } + onLoaded: { root.success = false; } // shouldn't be triggered if active is false + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/active.8.qml b/tests/auto/qtquick2/qquickloader/data/active.8.qml new file mode 100644 index 0000000000..3a66d3e99a --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/active.8.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 +Rectangle { + id: root + color: "blue" + width: 100; height: 100 + property bool success: false + + Loader { + anchors.fill: parent + sourceComponent: Rectangle { color: "red" } + onLoaded: { root.success = true; } // should be triggered since active is true by default + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/asynchronous.qml b/tests/auto/qtquick2/qquickloader/data/asynchronous.qml new file mode 100644 index 0000000000..29570525ad --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/asynchronous.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400 + + property string comp + function loadComponent() { + loader.source = comp + } + + Loader { + id: loader + objectName: "loader" + asynchronous: true + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/crash.qml b/tests/auto/qtquick2/qquickloader/data/crash.qml new file mode 100644 index 0000000000..e6ddc33a10 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/crash.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + function setLoaderSource() { + myLoader.source = "GreenRect.qml" + } + + Loader { + id: myLoader + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/creationContext.qml b/tests/auto/qtquick2/qquickloader/data/creationContext.qml new file mode 100644 index 0000000000..17a596cc74 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/creationContext.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +Item { + property bool test: false + + CreationContextLoader { + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/differentorigin.qml b/tests/auto/qtquick2/qquickloader/data/differentorigin.qml new file mode 100644 index 0000000000..56a3034fe0 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/differentorigin.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 + +Loader { source: "http://evil.place/evil.qml" } diff --git a/tests/auto/qtquick2/qquickloader/data/implicitSize.qml b/tests/auto/qtquick2/qquickloader/data/implicitSize.qml new file mode 100644 index 0000000000..5c8c8348ed --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/implicitSize.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Rectangle { + property real implWidth: 0 + property real implHeight: 0 + color: "green" + width: loader.implicitWidth+50 + height: loader.implicitHeight+50 + + Loader { + id: loader + sourceComponent: Item { + anchors.centerIn: parent + + implicitWidth: 100 + implicitHeight: 100 + Rectangle { + color: "red" + anchors.fill: parent + } + } + + anchors.fill: parent + anchors.margins: 50 + onImplicitWidthChanged: implWidth = implicitWidth + onImplicitHeightChanged: implHeight = loader.implicitHeight + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.1.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.1.qml new file mode 100644 index 0000000000..ae371797ce --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.1.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + + onLoaded: { + loader.item.canary = 1; // will trigger the behavior, setting behaviorCount -> 1 + } + } + + Component.onCompleted: { + loader.source = "InitialPropertyValuesComponent.qml"; + root.initialValue = loader.item.canary; // should be one, since onLoaded will have triggered by now + root.behaviorCount = loader.item.behaviorCount; // should be one, since onLoaded will have triggered by now + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.2.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.2.qml new file mode 100644 index 0000000000..76c7bc2fd6 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.2.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + onLoaded: { + root.initialValue = loader.item.canary; // should be two + root.behaviorCount = loader.item.behaviorCount; // should be zero + } + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 2}); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.3.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.3.qml new file mode 100644 index 0000000000..3b08e6ee42 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.3.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + active: false + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 3}); + root.initialValue = loader.item.canary; // error - item should not yet exist. + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.4.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.4.qml new file mode 100644 index 0000000000..e8310044e8 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.4.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + active: false + onLoaded: { + root.initialValue = loader.item.canary; // should be four + root.behaviorCount = loader.item.behaviorCount; // should be zero + } + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": 4}); + loader.active = true + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.5.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.5.qml new file mode 100644 index 0000000000..03ee599aba --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.5.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + onLoaded: { + root.initialValue = loader.item.canary; // should be zero, but no error + root.behaviorCount = loader.item.behaviorCount; // should be zero + } + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml"); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.6.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.6.qml new file mode 100644 index 0000000000..66452b512b --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.6.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + property int behaviorCount: 0 + + Loader { + id: loader + objectName: "loader" + onLoaded: { + root.initialValue = loader.item.canary; // should be six + root.behaviorCount = loader.item.behaviorCount; // should be zero + } + } + + Item { + id: child + property int bindable: 6 + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": child.bindable}); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.7.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.7.qml new file mode 100644 index 0000000000..02349f7ddf --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.7.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Item { + id: root + property int loaderValue: 0 + property int createObjectValue: 0 + + Loader { + id: loader + objectName: "loader" + onLoaded: { + root.loaderValue = loader.item.canary; // should still be one + } + } + + Item { + id: child + property int bindable: 1; + } + + property InitialPropertyValuesComponent ipvc + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": child.bindable}); + var dynComp = Qt.createComponent("InitialPropertyValuesComponent.qml"); + ipvc = dynComp.createObject(root, {"canary": child.bindable}); + child.bindable = 7; // won't cause re-evaluation, since not used in a binding. + root.createObjectValue = ipvc.canary; // should still be one + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.8.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.8.qml new file mode 100644 index 0000000000..79e9264d4a --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.8.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Item { + id: root + property int initialValue: 0 + + Loader { + id: loader + objectName: "loader" + active: false + onLoaded: { + root.initialValue = loader.item.canary; // should be six + } + } + + Component.onCompleted: { + loader.setSource("http://127.0.0.1:14450/InitialPropertyValuesComponent.qml", {"canary": 6}); + loader.active = true; + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.binding.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.binding.qml new file mode 100644 index 0000000000..e0df50a74a --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.binding.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Item { + id: root + + property InitialPropertyValuesComponent testInstance + testInstance: loader.item + + property int bindable: 1 + property int canaryValue: testInstance.canary + property int behaviorCount: testInstance.behaviorCount + + Loader { + id: loader + objectName: "loader" + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", {"canary": (function() { return root.bindable })}); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.1.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.1.qml new file mode 100644 index 0000000000..f324dbddac --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.1.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", 3); // invalid initial properties object + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.2.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.2.qml new file mode 100644 index 0000000000..89aba313c7 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.2.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + } + + Component.onCompleted: { + loader.setSource("NonexistentSourceComponent.qml", {"canary":3}); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.3.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.3.qml new file mode 100644 index 0000000000..c862007402 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.3.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Item { + id: root + + Loader { + id: loader + objectName: "loader" + } + + Component.onCompleted: { + loader.setSource("InvalidSourceComponent.qml", {"canary":3}); + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.4.qml b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.4.qml new file mode 100644 index 0000000000..9a80b2156d --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/initialPropertyValues.error.4.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Item { + id: root + property int canary: loader.item.canary + + Loader { + id: loader + objectName: "loader" + } + + Component.onCompleted: { + loader.setSource("InitialPropertyValuesComponent.qml", 3); // invalid initial properties object + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/nonItem.qml b/tests/auto/qtquick2/qquickloader/data/nonItem.qml new file mode 100644 index 0000000000..8cfa0d8efb --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/nonItem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Loader { + sourceComponent: QtObject {} +} diff --git a/tests/auto/qtquick2/qquickloader/data/parented.qml b/tests/auto/qtquick2/qquickloader/data/parented.qml new file mode 100644 index 0000000000..1c19d4d1a5 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/parented.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +Item { + id: root + width: 300; height: 300 + + Component { + id: comp + Rectangle { + objectName: "comp" + parent: root + anchors.fill: parent + color: "blue" + } + } + + Loader { + width: 200; height: 200 + sourceComponent: comp + } +} diff --git a/tests/auto/qtquick2/qquickloader/data/qmldir b/tests/auto/qtquick2/qquickloader/data/qmldir new file mode 100644 index 0000000000..bf42b507c0 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/qmldir @@ -0,0 +1 @@ +# For tst_QDeclarativeLoader::networkRequestUrl; no types needed though. diff --git a/tests/auto/qtquick2/qquickloader/data/sameorigin-load.qml b/tests/auto/qtquick2/qquickloader/data/sameorigin-load.qml new file mode 100644 index 0000000000..3332500be6 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/sameorigin-load.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 + +Item { } diff --git a/tests/auto/qtquick2/qquickloader/data/sameorigin.qml b/tests/auto/qtquick2/qquickloader/data/sameorigin.qml new file mode 100644 index 0000000000..84846b6aba --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/sameorigin.qml @@ -0,0 +1,3 @@ +import QtQuick 2.0 + +Loader { source: "sameorigin-load.qml" } diff --git a/tests/auto/qtquick2/qquickloader/data/vmeErrors.qml b/tests/auto/qtquick2/qquickloader/data/vmeErrors.qml new file mode 100644 index 0000000000..8e6c89dc8e --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/data/vmeErrors.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Loader { + source: "VmeError.qml" +} + diff --git a/tests/auto/qtquick2/qquickloader/qquickloader.pro b/tests/auto/qtquick2/qquickloader/qquickloader.pro new file mode 100644 index 0000000000..6e372692c2 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/qquickloader.pro @@ -0,0 +1,16 @@ +CONFIG += testcase +TARGET = tst_qquickloader +macx:CONFIG -= app_bundle + +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qquickloader.cpp \ + ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickloader/tst_qquickloader.cpp b/tests/auto/qtquick2/qquickloader/tst_qquickloader.cpp new file mode 100644 index 0000000000..3df692a6a6 --- /dev/null +++ b/tests/auto/qtquick2/qquickloader/tst_qquickloader.cpp @@ -0,0 +1,969 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +#include + +#include +#include +#include +#include +#include "testhttpserver.h" +#include "../../shared/util.h" + +#define SERVER_PORT 14450 + +inline QUrl TEST_FILE(const QString &filename) +{ + return QUrl::fromLocalFile(TESTDATA(filename)); +} + +class PeriodicIncubationController : public QObject, + public QDeclarativeIncubationController +{ +public: + PeriodicIncubationController() { + startTimer(16); + } + +protected: + virtual void timerEvent(QTimerEvent *) { + incubateFor(15); + } +}; + +class tst_QQuickLoader : public QObject + +{ + Q_OBJECT +public: + tst_QQuickLoader(); + +private slots: + void sourceOrComponent(); + void sourceOrComponent_data(); + void clear(); + void urlToComponent(); + void componentToUrl(); + void anchoredLoader(); + void sizeLoaderToItem(); + void sizeItemToLoader(); + void noResize(); + void networkRequestUrl(); + void failNetworkRequest(); +// void networkComponent(); + void active(); + void initialPropertyValues_data(); + void initialPropertyValues(); + void initialPropertyValuesBinding(); + void initialPropertyValuesError_data(); + void initialPropertyValuesError(); + + void deleteComponentCrash(); + void nonItem(); + void vmeErrors(); + void creationContext(); + void QTBUG_16928(); + void implicitSize(); + void QTBUG_17114(); + void asynchronous_data(); + void asynchronous(); + void asynchronous_clear(); + + void parented(); + +private: + QDeclarativeEngine engine; +}; + + +tst_QQuickLoader::tst_QQuickLoader() +{ +} + +void tst_QQuickLoader::sourceOrComponent() +{ + QFETCH(QString, sourceOrComponent); + QFETCH(QString, sourceDefinition); + QFETCH(QUrl, sourceUrl); + QFETCH(QString, errorString); + + bool error = !errorString.isEmpty(); + if (error) + QTest::ignoreMessage(QtWarningMsg, errorString.toUtf8().constData()); + + QDeclarativeComponent component(&engine); + component.setData(QByteArray( + "import QtQuick 2.0\n" + "Loader {\n" + " property int onItemChangedCount: 0\n" + " property int onSourceChangedCount: 0\n" + " property int onSourceComponentChangedCount: 0\n" + " property int onStatusChangedCount: 0\n" + " property int onProgressChangedCount: 0\n" + " property int onLoadedCount: 0\n") + + sourceDefinition.toUtf8() + + QByteArray( + " onItemChanged: onItemChangedCount += 1\n" + " onSourceChanged: onSourceChangedCount += 1\n" + " onSourceComponentChanged: onSourceComponentChangedCount += 1\n" + " onStatusChanged: onStatusChangedCount += 1\n" + " onProgressChanged: onProgressChangedCount += 1\n" + " onLoaded: onLoadedCount += 1\n" + "}") + , TEST_FILE("")); + + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + QCOMPARE(loader->item() == 0, error); + QCOMPARE(loader->source(), sourceUrl); + QCOMPARE(loader->progress(), 1.0); + + QCOMPARE(loader->status(), error ? QQuickLoader::Error : QQuickLoader::Ready); + QCOMPARE(static_cast(loader)->childItems().count(), error ? 0: 1); + + if (!error) { + bool sourceComponentIsChildOfLoader = false; + for (int ii = 0; ii < loader->children().size(); ++ii) { + QDeclarativeComponent *c = qobject_cast(loader->children().at(ii)); + if (c && c == loader->sourceComponent()) { + sourceComponentIsChildOfLoader = true; + } + } + QVERIFY(sourceComponentIsChildOfLoader); + } + + if (sourceOrComponent == "component") { + QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 1); + QCOMPARE(loader->property("onSourceChangedCount").toInt(), 0); + } else { + QCOMPARE(loader->property("onSourceComponentChangedCount").toInt(), 0); + QCOMPARE(loader->property("onSourceChangedCount").toInt(), 1); + } + QCOMPARE(loader->property("onStatusChangedCount").toInt(), 1); + QCOMPARE(loader->property("onProgressChangedCount").toInt(), 1); + + QCOMPARE(loader->property("onItemChangedCount").toInt(), error ? 0 : 1); + QCOMPARE(loader->property("onLoadedCount").toInt(), error ? 0 : 1); + + delete loader; +} + +void tst_QQuickLoader::sourceOrComponent_data() +{ + QTest::addColumn("sourceOrComponent"); + QTest::addColumn("sourceDefinition"); + QTest::addColumn("sourceUrl"); + QTest::addColumn("errorString"); + + QTest::newRow("source") << "source" << "source: 'Rect120x60.qml'\n" << QUrl::fromLocalFile(TESTDATA("Rect120x60.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" << QUrl::fromLocalFile(TESTDATA("IDontExist.qml")) + << QString(QUrl::fromLocalFile(TESTDATA("IDontExist.qml")).toString() + ": File not found"); +} + +void tst_QQuickLoader::clear() +{ + { + QDeclarativeComponent component(&engine); + component.setData(QByteArray( + "import QtQuick 2.0\n" + " Loader { id: loader\n" + " source: 'Rect120x60.qml'\n" + " Timer { interval: 200; running: true; onTriggered: loader.source = '' }\n" + " }") + , TEST_FILE("")); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + + QTRY_VERIFY(loader->item() == 0); + QCOMPARE(loader->progress(), 0.0); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(static_cast(loader)->childItems().count(), 0); + + delete loader; + } + { + QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + + loader->setSourceComponent(0); + + QVERIFY(loader->item() == 0); + QCOMPARE(loader->progress(), 0.0); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(static_cast(loader)->childItems().count(), 0); + + delete item; + } + { + QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + + QMetaObject::invokeMethod(item, "clear"); + + QVERIFY(loader->item() == 0); + QCOMPARE(loader->progress(), 0.0); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(static_cast(loader)->childItems().count(), 0); + + delete item; + } +} + +void tst_QQuickLoader::urlToComponent() +{ + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\n" + "Loader {\n" + " id: loader\n" + " Component { id: myComp; Rectangle { width: 10; height: 10 } }\n" + " source: \"Rect120x60.qml\"\n" + " Timer { interval: 100; running: true; onTriggered: loader.sourceComponent = myComp }\n" + "}" ) + , TEST_FILE("")); + QQuickLoader *loader = qobject_cast(component.create()); + QTest::qWait(200); + QTRY_VERIFY(loader != 0); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + QCOMPARE(loader->width(), 10.0); + QCOMPARE(loader->height(), 10.0); + + delete loader; +} + +void tst_QQuickLoader::componentToUrl() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/SetSourceComponent.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + + loader->setSource(TEST_FILE("/Rect120x60.qml")); + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + QCOMPARE(loader->width(), 120.0); + QCOMPARE(loader->height(), 60.0); + + delete item; +} + +void tst_QQuickLoader::anchoredLoader() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/AnchoredLoader.qml")); + QQuickItem *rootItem = qobject_cast(component.create()); + QVERIFY(rootItem != 0); + QQuickItem *loader = rootItem->findChild("loader"); + QQuickItem *sourceElement = rootItem->findChild("sourceElement"); + + QVERIFY(loader != 0); + QVERIFY(sourceElement != 0); + + QCOMPARE(rootItem->width(), 300.0); + QCOMPARE(rootItem->height(), 200.0); + + QCOMPARE(loader->width(), 300.0); + QCOMPARE(loader->height(), 200.0); + + QCOMPARE(sourceElement->width(), 300.0); + QCOMPARE(sourceElement->height(), 200.0); +} + +void tst_QQuickLoader::sizeLoaderToItem() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/SizeToItem.qml")); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + QCOMPARE(loader->width(), 120.0); + QCOMPARE(loader->height(), 60.0); + + // Check resize + QQuickItem *rect = qobject_cast(loader->item()); + QVERIFY(rect); + rect->setWidth(150); + rect->setHeight(45); + QCOMPARE(loader->width(), 150.0); + QCOMPARE(loader->height(), 45.0); + + // Check explicit width + loader->setWidth(200.0); + QCOMPARE(loader->width(), 200.0); + QCOMPARE(rect->width(), 200.0); + rect->setWidth(100.0); // when rect changes ... + QCOMPARE(rect->width(), 100.0); // ... it changes + QCOMPARE(loader->width(), 200.0); // ... but loader stays the same + + // Check explicit height + loader->setHeight(200.0); + QCOMPARE(loader->height(), 200.0); + QCOMPARE(rect->height(), 200.0); + rect->setHeight(100.0); // when rect changes ... + QCOMPARE(rect->height(), 100.0); // ... it changes + QCOMPARE(loader->height(), 200.0); // ... but loader stays the same + + // Switch mode + loader->setWidth(180); + loader->setHeight(30); + QCOMPARE(rect->width(), 180.0); + QCOMPARE(rect->height(), 30.0); + + delete loader; +} + +void tst_QQuickLoader::sizeItemToLoader() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/SizeToLoader.qml")); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + QCOMPARE(loader->width(), 200.0); + QCOMPARE(loader->height(), 80.0); + + QQuickItem *rect = qobject_cast(loader->item()); + QVERIFY(rect); + QCOMPARE(rect->width(), 200.0); + QCOMPARE(rect->height(), 80.0); + + // Check resize + loader->setWidth(180); + loader->setHeight(30); + QCOMPARE(rect->width(), 180.0); + QCOMPARE(rect->height(), 30.0); + + // Switch mode + loader->resetWidth(); // reset explicit size + loader->resetHeight(); + rect->setWidth(160); + rect->setHeight(45); + QCOMPARE(loader->width(), 160.0); + QCOMPARE(loader->height(), 45.0); + + delete loader; +} + +void tst_QQuickLoader::noResize() +{ + QDeclarativeComponent component(&engine, TEST_FILE("/NoResize.qml")); + QQuickItem* item = qobject_cast(component.create()); + QVERIFY(item != 0); + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 80.0); + + delete item; +} + +void tst_QQuickLoader::networkRequestUrl() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nLoader { property int signalCount : 0; source: \"http://127.0.0.1:14450/Rect120x60.qml\"; onLoaded: signalCount += 1 }"), QUrl::fromLocalFile(TESTDATA("../dummy.qml"))); + if (component.isError()) + qDebug() << component.errors(); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + + QTRY_VERIFY(loader->status() == QQuickLoader::Ready); + + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->property("signalCount").toInt(), 1); + QCOMPARE(static_cast(loader)->childItems().count(), 1); + + delete loader; +} + +/* XXX Component waits until all dependencies are loaded. Is this actually possible? +void tst_QQuickLoader::networkComponent() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory("slowdata", TestHTTPServer::Delay); + + QDeclarativeComponent component(&engine); + component.setData(QByteArray( + "import QtQuick 2.0\n" + "import \"http://127.0.0.1:14450/\" as NW\n" + "Item {\n" + " Component { id: comp; NW.SlowRect {} }\n" + " Loader { sourceComponent: comp } }") + , TEST_FILE("")); + + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QQuickLoader *loader = qobject_cast(item->QQuickItem::children().at(1)); + QVERIFY(loader); + QTRY_VERIFY(loader->status() == QQuickLoader::Ready); + + QVERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + QCOMPARE(static_cast(loader)->children().count(), 1); + + delete loader; +} +*/ + +void tst_QQuickLoader::failNetworkRequest() +{ + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + QTest::ignoreMessage(QtWarningMsg, "http://127.0.0.1:14450/IDontExist.qml: File not found"); + + QDeclarativeComponent component(&engine); + component.setData(QByteArray("import QtQuick 2.0\nLoader { property int did_load: 123; source: \"http://127.0.0.1:14450/IDontExist.qml\"; onLoaded: did_load=456 }"), QUrl::fromLocalFile("http://127.0.0.1:14450/dummy.qml")); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader != 0); + + QTRY_VERIFY(loader->status() == QQuickLoader::Error); + + QVERIFY(loader->item() == 0); + QCOMPARE(loader->progress(), 0.0); + QCOMPARE(loader->property("did_load").toInt(), 123); + QCOMPARE(static_cast(loader)->childItems().count(), 0); + + delete loader; +} + +void tst_QQuickLoader::active() +{ + // check that the item isn't instantiated until active is set to true + { + QDeclarativeComponent component(&engine, TEST_FILE("active.1.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == false); // set manually to false + QVERIFY(loader->item() == 0); + QMetaObject::invokeMethod(object, "doSetSourceComponent"); + QVERIFY(loader->item() == 0); + QMetaObject::invokeMethod(object, "doSetSource"); + QVERIFY(loader->item() == 0); + QMetaObject::invokeMethod(object, "doSetActive"); + QVERIFY(loader->item() != 0); + + delete object; + } + + // check that the status is Null if active is set to false + { + QDeclarativeComponent component(&engine, TEST_FILE("active.2.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == true); // active is true by default + QCOMPARE(loader->status(), QQuickLoader::Ready); + int currStatusChangedCount = loader->property("statusChangedCount").toInt(); + QMetaObject::invokeMethod(object, "doSetInactive"); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(loader->property("statusChangedCount").toInt(), (currStatusChangedCount+1)); + + delete object; + } + + // check that the source is not cleared if active is set to false + { + QDeclarativeComponent component(&engine, TEST_FILE("active.3.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == true); // active is true by default + QVERIFY(!loader->source().isEmpty()); + int currSourceChangedCount = loader->property("sourceChangedCount").toInt(); + QMetaObject::invokeMethod(object, "doSetInactive"); + QVERIFY(!loader->source().isEmpty()); + QCOMPARE(loader->property("sourceChangedCount").toInt(), currSourceChangedCount); + + delete object; + } + + // check that the sourceComponent is not cleared if active is set to false + { + QDeclarativeComponent component(&engine, TEST_FILE("active.4.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == true); // active is true by default + QVERIFY(loader->sourceComponent() != 0); + int currSourceComponentChangedCount = loader->property("sourceComponentChangedCount").toInt(); + QMetaObject::invokeMethod(object, "doSetInactive"); + QVERIFY(loader->sourceComponent() != 0); + QCOMPARE(loader->property("sourceComponentChangedCount").toInt(), currSourceComponentChangedCount); + + delete object; + } + + // check that the item is released if active is set to false + { + QDeclarativeComponent component(&engine, TEST_FILE("active.5.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == true); // active is true by default + QVERIFY(loader->item() != 0); + int currItemChangedCount = loader->property("itemChangedCount").toInt(); + QMetaObject::invokeMethod(object, "doSetInactive"); + QVERIFY(loader->item() == 0); + QCOMPARE(loader->property("itemChangedCount").toInt(), (currItemChangedCount+1)); + + delete object; + } + + // check that the activeChanged signal is emitted correctly + { + QDeclarativeComponent component(&engine, TEST_FILE("active.6.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + + QVERIFY(loader->active() == true); // active is true by default + loader->setActive(true); // no effect + QCOMPARE(loader->property("activeChangedCount").toInt(), 0); + loader->setActive(false); // change signal should be emitted + QCOMPARE(loader->property("activeChangedCount").toInt(), 1); + loader->setActive(false); // no effect + QCOMPARE(loader->property("activeChangedCount").toInt(), 1); + loader->setActive(true); // change signal should be emitted + QCOMPARE(loader->property("activeChangedCount").toInt(), 2); + loader->setActive(false); // change signal should be emitted + QCOMPARE(loader->property("activeChangedCount").toInt(), 3); + QMetaObject::invokeMethod(object, "doSetActive"); + QCOMPARE(loader->property("activeChangedCount").toInt(), 4); + QMetaObject::invokeMethod(object, "doSetActive"); + QCOMPARE(loader->property("activeChangedCount").toInt(), 4); + QMetaObject::invokeMethod(object, "doSetInactive"); + QCOMPARE(loader->property("activeChangedCount").toInt(), 5); + loader->setActive(true); // change signal should be emitted + QCOMPARE(loader->property("activeChangedCount").toInt(), 6); + + delete object; + } + + // check that the component isn't loaded until active is set to true + { + QDeclarativeComponent component(&engine, TEST_FILE("active.7.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("success").toBool(), true); + delete object; + } + + // check that the component is loaded if active is not set (true by default) + { + QDeclarativeComponent component(&engine, TEST_FILE("active.8.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("success").toBool(), true); + delete object; + } +} + +void tst_QQuickLoader::initialPropertyValues_data() +{ + QTest::addColumn("qmlFile"); + QTest::addColumn("expectedWarnings"); + QTest::addColumn("propertyNames"); + QTest::addColumn("propertyValues"); + + QTest::newRow("source url with value set in onLoaded, initially active = true") << TEST_FILE("initialPropertyValues.1.qml") + << QStringList() + << (QStringList() << "initialValue" << "behaviorCount") + << (QVariantList() << 1 << 1); + + QTest::newRow("set source with initial property values specified, active = true") << TEST_FILE("initialPropertyValues.2.qml") + << QStringList() + << (QStringList() << "initialValue" << "behaviorCount") + << (QVariantList() << 2 << 0); + + QTest::newRow("set source with initial property values specified, active = false") << TEST_FILE("initialPropertyValues.3.qml") + << (QStringList() << QString(QLatin1String("file://") + TEST_FILE("initialPropertyValues.3.qml").toLocalFile() + QLatin1String(":16: TypeError: Cannot read property 'canary' of null"))) + << (QStringList()) + << (QVariantList()); + + QTest::newRow("set source with initial property values specified, active = false, with active set true later") << TEST_FILE("initialPropertyValues.4.qml") + << QStringList() + << (QStringList() << "initialValue" << "behaviorCount") + << (QVariantList() << 4 << 0); + + QTest::newRow("set source without initial property values specified, active = true") << TEST_FILE("initialPropertyValues.5.qml") + << QStringList() + << (QStringList() << "initialValue" << "behaviorCount") + << (QVariantList() << 0 << 0); + + QTest::newRow("set source with initial property values specified with binding, active = true") << TEST_FILE("initialPropertyValues.6.qml") + << QStringList() + << (QStringList() << "initialValue" << "behaviorCount") + << (QVariantList() << 6 << 0); + + QTest::newRow("ensure initial property value semantics mimic createObject") << TEST_FILE("initialPropertyValues.7.qml") + << QStringList() + << (QStringList() << "loaderValue" << "createObjectValue") + << (QVariantList() << 1 << 1); + + QTest::newRow("ensure initial property values aren't disposed prior to component completion") << TEST_FILE("initialPropertyValues.8.qml") + << QStringList() + << (QStringList() << "initialValue") + << (QVariantList() << 6); +} + +void tst_QQuickLoader::initialPropertyValues() +{ + QFETCH(QUrl, qmlFile); + QFETCH(QStringList, expectedWarnings); + QFETCH(QStringList, propertyNames); + QFETCH(QVariantList, propertyValues); + + TestHTTPServer server(SERVER_PORT); + QVERIFY(server.isValid()); + server.serveDirectory(TESTDATA("")); + + foreach (const QString &warning, expectedWarnings) + QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData()); + + QDeclarativeComponent component(&engine, qmlFile); + QObject *object = component.create(); + QVERIFY(object != 0); + qApp->processEvents(); + QTest::qWait(50); + + for (int i = 0; i < propertyNames.size(); ++i) + QCOMPARE(object->property(propertyNames.at(i).toAscii().constData()), propertyValues.at(i)); + + delete object; +} + +void tst_QQuickLoader::initialPropertyValuesBinding() +{ + QDeclarativeComponent component(&engine, TEST_FILE("initialPropertyValues.binding.qml")); + QObject *object = component.create(); + QVERIFY(object != 0); + + QVERIFY(object->setProperty("bindable", QVariant(8))); + QCOMPARE(object->property("canaryValue").toInt(), 8); + + delete object; +} + +void tst_QQuickLoader::initialPropertyValuesError_data() +{ + QTest::addColumn("qmlFile"); + QTest::addColumn("expectedWarnings"); + + QTest::newRow("invalid initial property values object") << TEST_FILE("initialPropertyValues.error.1.qml") + << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.1.qml").toString() + ":6:5: QML Loader: setSource: value is not an object")); + + QTest::newRow("nonexistent source url") << TEST_FILE("initialPropertyValues.error.2.qml") + << (QStringList() << QString(TEST_FILE("NonexistentSourceComponent.qml").toString() + ": File not found")); + + QTest::newRow("invalid source url") << TEST_FILE("initialPropertyValues.error.3.qml") + << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); + + QTest::newRow("invalid initial property values object with invalid property access") << TEST_FILE("initialPropertyValues.error.4.qml") + << (QStringList() << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":7:5: QML Loader: setSource: value is not an object") + << QString(TEST_FILE("initialPropertyValues.error.4.qml").toString() + ":5: TypeError: Cannot read property 'canary' of null")); +} + +void tst_QQuickLoader::initialPropertyValuesError() +{ + QFETCH(QUrl, qmlFile); + QFETCH(QStringList, expectedWarnings); + + foreach (const QString &warning, expectedWarnings) + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData()); + + QDeclarativeComponent component(&engine, qmlFile); + QObject *object = component.create(); + QVERIFY(object != 0); + QQuickLoader *loader = object->findChild("loader"); + QVERIFY(loader != 0); + QVERIFY(loader->item() == 0); + delete object; +} + +// QTBUG-9241 +void tst_QQuickLoader::deleteComponentCrash() +{ + QDeclarativeComponent component(&engine, TEST_FILE("crash.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + item->metaObject()->invokeMethod(item, "setLoaderSource"); + + QQuickLoader *loader = qobject_cast(item->QQuickItem::childItems().at(0)); + QVERIFY(loader); + QVERIFY(loader->item()); + QCOMPARE(loader->item()->objectName(), QLatin1String("blue")); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + qApp->processEvents(QEventLoop::DeferredDeletion); + QTRY_COMPARE(static_cast(loader)->childItems().count(), 1); + QVERIFY(loader->source() == QUrl::fromLocalFile(TESTDATA("BlueRect.qml"))); + + delete item; +} + +void tst_QQuickLoader::nonItem() +{ + QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml")); + QString err = QUrl::fromLocalFile(TESTDATA("nonItem.qml")).toString() + ":3:1: QML Loader: Loader does not support loading non-visual elements."; + + QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + +void tst_QQuickLoader::vmeErrors() +{ + QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml")); + QString err = QUrl::fromLocalFile(TESTDATA("VmeError.qml")).toString() + ":6: Cannot assign object type QObject with no default method"; + QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); + QQuickLoader *loader = qobject_cast(component.create()); + QVERIFY(loader); + QVERIFY(loader->item() == 0); + + delete loader; +} + +// QTBUG-13481 +void tst_QQuickLoader::creationContext() +{ + QDeclarativeComponent component(&engine, TEST_FILE("creationContext.qml")); + + QObject *o = component.create(); + QVERIFY(o != 0); + + QCOMPARE(o->property("test").toBool(), true); + + delete o; +} + +void tst_QQuickLoader::QTBUG_16928() +{ + QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_16928.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QCOMPARE(item->width(), 250.); + QCOMPARE(item->height(), 250.); + + delete item; +} + +void tst_QQuickLoader::implicitSize() +{ + QDeclarativeComponent component(&engine, TEST_FILE("implicitSize.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QCOMPARE(item->width(), 150.); + QCOMPARE(item->height(), 150.); + + QCOMPARE(item->property("implHeight").toReal(), 100.); + QCOMPARE(item->property("implWidth").toReal(), 100.); + + delete item; +} + +void tst_QQuickLoader::QTBUG_17114() +{ + QDeclarativeComponent component(&engine, TEST_FILE("QTBUG_17114.qml")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + + QCOMPARE(item->property("loaderWidth").toReal(), 32.); + QCOMPARE(item->property("loaderHeight").toReal(), 32.); + + delete item; +} + +void tst_QQuickLoader::asynchronous_data() +{ + QTest::addColumn("qmlFile"); + QTest::addColumn("expectedWarnings"); + + QTest::newRow("Valid component") << TEST_FILE("BigComponent.qml") + << QStringList(); + + QTest::newRow("Non-existant component") << TEST_FILE("IDoNotExist.qml") + << (QStringList() << QString(TEST_FILE("IDoNotExist.qml").toString() + ": File not found")); + + QTest::newRow("Invalid component") << TEST_FILE("InvalidSourceComponent.qml") + << (QStringList() << QString(TEST_FILE("InvalidSourceComponent.qml").toString() + ":5:1: Syntax error")); +} + +void tst_QQuickLoader::asynchronous() +{ + QFETCH(QUrl, qmlFile); + QFETCH(QStringList, expectedWarnings); + + if (!engine.incubationController()) + engine.setIncubationController(new PeriodicIncubationController); + QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml")); + QQuickItem *root = qobject_cast(component.create()); + QVERIFY(root); + + QQuickLoader *loader = root->findChild("loader"); + QVERIFY(loader); + + foreach (const QString &warning, expectedWarnings) + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8().constData()); + + QVERIFY(!loader->item()); + root->setProperty("comp", qmlFile.toString()); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + + if (expectedWarnings.isEmpty()) { + QCOMPARE(loader->status(), QQuickLoader::Loading); + QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); + + QTRY_VERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + } else { + QCOMPARE(loader->progress(), 1.0); + QTRY_COMPARE(loader->status(), QQuickLoader::Error); + } + + delete root; +} + +void tst_QQuickLoader::asynchronous_clear() +{ + if (!engine.incubationController()) + engine.setIncubationController(new PeriodicIncubationController); + QDeclarativeComponent component(&engine, TEST_FILE("asynchronous.qml")); + QQuickItem *root = qobject_cast(component.create()); + QVERIFY(root); + + QQuickLoader *loader = root->findChild("loader"); + QVERIFY(loader); + + QVERIFY(!loader->item()); + root->setProperty("comp", "BigComponent.qml"); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + + QCOMPARE(loader->status(), QQuickLoader::Loading); + QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); + + // clear before component created + root->setProperty("comp", ""); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + QCOMPARE(engine.incubationController()->incubatingObjectCount(), 0); + + QCOMPARE(loader->progress(), 0.0); + QCOMPARE(loader->status(), QQuickLoader::Null); + QCOMPARE(static_cast(loader)->childItems().count(), 0); + + // check loading component + root->setProperty("comp", "Rect120x60.qml"); + QMetaObject::invokeMethod(root, "loadComponent"); + QVERIFY(!loader->item()); + + QCOMPARE(loader->status(), QQuickLoader::Loading); + QCOMPARE(engine.incubationController()->incubatingObjectCount(), 1); + + QTRY_VERIFY(loader->item()); + QCOMPARE(loader->progress(), 1.0); + QCOMPARE(loader->status(), QQuickLoader::Ready); + QCOMPARE(static_cast(loader)->childItems().count(), 1); +} + +void tst_QQuickLoader::parented() +{ + QDeclarativeComponent component(&engine, TEST_FILE("parented.qml")); + QQuickItem *root = qobject_cast(component.create()); + QVERIFY(root); + + QQuickItem *item = root->findChild("comp"); + QVERIFY(item); + + QVERIFY(item->parentItem() == root); + + QCOMPARE(item->width(), 300.); + QCOMPARE(item->height(), 300.); + + delete root; +} + + +QTEST_MAIN(tst_QQuickLoader) + +#include "tst_qquickloader.moc" diff --git a/tests/auto/qtquick2/qquickmousearea/data/clickThrough.qml b/tests/auto/qtquick2/qquickmousearea/data/clickThrough.qml new file mode 100644 index 0000000000..3c03161faa --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/clickThrough.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Item{ + width: 200 + height: 200 + property int doubleClicks: 0 + property int clicks: 0 + property int pressAndHolds: 0 + property int presses: 0 + MouseArea{ + z: 0 + anchors.fill: parent + propagateComposedEvents: true + onPressed: presses++ + onClicked: clicks++ + onPressAndHold: pressAndHolds++ + onDoubleClicked: doubleClicks++ + } + MouseArea{ + z: 1 + propagateComposedEvents: true + enabled: true + anchors.fill: parent + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/clickThrough2.qml b/tests/auto/qtquick2/qquickmousearea/data/clickThrough2.qml new file mode 100644 index 0000000000..2624108225 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/clickThrough2.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 + +Item{ + width: 300 + height: 300 + property int doubleClicks: 0 + property int clicks: 0 + property int pressAndHolds: 0 + property int presses: 0 + property bool letThrough: false + property bool noPropagation: false + Rectangle{ + z: 0 + color: "lightsteelblue" + width: 150 + height: 150 + MouseArea{ + anchors.fill: parent + propagateComposedEvents: true + onPressed: presses++ + onClicked: clicks++ + onPressAndHold: pressAndHolds++ + onDoubleClicked: doubleClicks++ + } + } + MouseArea{ + z: 1 + enabled: true + anchors.fill: parent + propagateComposedEvents: !noPropagation + onClicked: mouse.accepted = !letThrough; + onDoubleClicked: mouse.accepted = !letThrough; + onPressAndHold: mouse.accepted = !letThrough; + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/clickandhold.qml b/tests/auto/qtquick2/qquickmousearea/data/clickandhold.qml new file mode 100644 index 0000000000..5e4e48f6db --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/clickandhold.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +Item { + id: root + property bool clicked: false + property bool held: false + + MouseArea { + width: 200; height: 200 + onClicked: { root.clicked = true } + onPressAndHold: { root.held = true } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/clicktwice.qml b/tests/auto/qtquick2/qquickmousearea/data/clicktwice.qml new file mode 100644 index 0000000000..002d1b9047 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/clicktwice.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + id: root + property int clicked: 0 + property int pressed: 0 + property int released: 0 + + MouseArea { + width: 200; height: 200 + onPressed: { root.pressed++ } + onClicked: { root.clicked++ } + onReleased: { root.released++ } + } +} + diff --git a/tests/auto/qtquick2/qquickmousearea/data/doubleclick.qml b/tests/auto/qtquick2/qquickmousearea/data/doubleclick.qml new file mode 100644 index 0000000000..1030d0c33e --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/doubleclick.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 + +Item { + id: root + property int clicked: 0 + property int doubleClicked: 0 + property int released: 0 + + MouseArea { + width: 200; height: 200 + onClicked: { root.clicked++ } + onDoubleClicked: { root.doubleClicked++ } + onReleased: { root.released++ } + } +} + diff --git a/tests/auto/qtquick2/qquickmousearea/data/dragging.qml b/tests/auto/qtquick2/qquickmousearea/data/dragging.qml new file mode 100644 index 0000000000..d9b6ac4083 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/dragging.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +Rectangle { + id: whiteRect + width: 200 + height: 200 + color: "white" + Rectangle { + id: blackRect + objectName: "blackrect" + color: "black" + y: 50 + x: 50 + width: 100 + height: 100 + opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 + Text { text: blackRect.opacity} + MouseArea { + objectName: "mouseregion" + anchors.fill: parent + drag.target: blackRect + drag.axis: Drag.XandYAxis + drag.minimumX: 0 + drag.maximumX: whiteRect.width-blackRect.width + drag.minimumY: 0 + drag.maximumY: whiteRect.height-blackRect.height + } + } + } diff --git a/tests/auto/qtquick2/qquickmousearea/data/dragproperties.qml b/tests/auto/qtquick2/qquickmousearea/data/dragproperties.qml new file mode 100644 index 0000000000..421dfe26b7 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/dragproperties.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +Rectangle { + id: whiteRect + width: 200 + height: 200 + color: "white" + Rectangle { + id: blackRect + objectName: "blackrect" + color: "black" + y: 50 + x: 50 + width: 100 + height: 100 + opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 + Text { text: blackRect.opacity} + MouseArea { + objectName: "mouseregion" + anchors.fill: parent + drag.target: blackRect + drag.axis: Drag.XandYAxis + drag.minimumX: 0 + drag.maximumX: whiteRect.width-blackRect.width + drag.minimumY: 0 + drag.maximumY: whiteRect.height-blackRect.height + } + } + } diff --git a/tests/auto/qtquick2/qquickmousearea/data/dragreset.qml b/tests/auto/qtquick2/qquickmousearea/data/dragreset.qml new file mode 100644 index 0000000000..d7949f9139 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/dragreset.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 +Rectangle { + id: whiteRect + width: 200 + height: 200 + color: "white" + Rectangle { + id: blackRect + objectName: "blackrect" + color: "black" + y: 50 + x: 50 + width: 100 + height: 100 + opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 + Text { text: blackRect.opacity} + MouseArea { + objectName: "mouseregion" + anchors.fill: parent + drag.target: haveTarget ? blackRect : undefined + drag.axis: Drag.XandYAxis + drag.minimumX: 0 + drag.maximumX: whiteRect.width-blackRect.width + drag.minimumY: 0 + drag.maximumY: whiteRect.height-blackRect.height + } + } + } diff --git a/tests/auto/qtquick2/qquickmousearea/data/hoverPosition.qml b/tests/auto/qtquick2/qquickmousearea/data/hoverPosition.qml new file mode 100644 index 0000000000..834f91ff29 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/hoverPosition.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +Rectangle { + width: 400; height: 400; + + property real mouseX: mousetracker.mouseX + property real mouseY: mousetracker.mouseY + + Rectangle { + width: 100; height: 100; + MouseArea { + id: mousetracker; + anchors.fill: parent; + hoverEnabled: true + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/hoverPropagation.qml b/tests/auto/qtquick2/qquickmousearea/data/hoverPropagation.qml new file mode 100644 index 0000000000..c47c794132 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/hoverPropagation.qml @@ -0,0 +1,54 @@ +import QtQuick 2.0 + +Item{ + width: 400 + height: 200 + property bool point1: ma2.containsMouse && !ma1.containsMouse + property bool point2: ma3.containsMouse && ma4.containsMouse + Rectangle{ + width: 200 + height: 200 + color: ma1.containsMouse ? "red" : "white" + MouseArea{ + id: ma1 + hoverEnabled: true + anchors.fill: parent + } + Rectangle{ + width: 100 + height: 100 + color: ma2.containsMouse ? "blue" : "white" + MouseArea{ + id: ma2 + hoverEnabled: true + anchors.fill: parent + } + } + } + + Item{ + x:200 + Rectangle{ + width: 200 + height: 200 + color: ma3.containsMouse ? "yellow" : "white" + Rectangle{ + width: 100 + height: 100 + color: ma4.containsMouse ? "green" : "white" + } + } + MouseArea{ + id: ma3 + hoverEnabled: true + width: 200 + height: 200 + MouseArea{ + id: ma4 + width: 100 + height: 100 + hoverEnabled: true + } + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/noclickandhold.qml b/tests/auto/qtquick2/qquickmousearea/data/noclickandhold.qml new file mode 100644 index 0000000000..6647de001d --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/noclickandhold.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Item { + id: root + property bool clicked: false + + MouseArea { + width: 200; height: 200 + onClicked: { root.clicked = true } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/pressedCanceled.qml b/tests/auto/qtquick2/qquickmousearea/data/pressedCanceled.qml new file mode 100644 index 0000000000..231436d0f2 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/pressedCanceled.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + id: root + color: "#ffffff" + width: 320; height: 240 + property bool pressed:mouse.pressed + property bool canceled: false + property bool released: false + + MouseArea { + id: mouse + anchors.fill: parent + onPressed: { root.canceled = false } + onCanceled: {root.canceled = true} + onReleased: {root.released = true; root.canceled = false} + } +} \ No newline at end of file diff --git a/tests/auto/qtquick2/qquickmousearea/data/pressedOrdering.qml b/tests/auto/qtquick2/qquickmousearea/data/pressedOrdering.qml new file mode 100644 index 0000000000..7aa3098100 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/pressedOrdering.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Item { + id: root + property string value: "base" + + MouseArea { + id: mouseArea + width: 200; height: 200 + onClicked: toggleState.state = "toggled" + } + + StateGroup { + states: State { + name: "pressed" + when: mouseArea.pressed + PropertyChanges { target: root; value: "pressed" } + } + } + + StateGroup { + id: toggleState + states: State { + name: "toggled" + PropertyChanges { target: root; value: "toggled" } + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/preventstealing.qml b/tests/auto/qtquick2/qquickmousearea/data/preventstealing.qml new file mode 100644 index 0000000000..fb0d6955c1 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/preventstealing.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Flickable { + property bool stealing: true + width: 200 + height: 200 + contentWidth: 400 + contentHeight: 400 + Rectangle { + color: "black" + width: 400 + height: 400 + Rectangle { + x: 50; y: 50 + width: 100; height: 100 + color: "steelblue" + MouseArea { + objectName: "mousearea" + anchors.fill: parent + preventStealing: stealing + } + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/rejectEvent.qml b/tests/auto/qtquick2/qquickmousearea/data/rejectEvent.qml new file mode 100644 index 0000000000..816fc76fac --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/rejectEvent.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Rectangle { + id: root + color: "#ffffff" + width: 320; height: 240 + property bool mr1_pressed: false + property bool mr1_released: false + property bool mr1_canceled: false + property bool mr2_pressed: false + property bool mr2_released: false + property bool mr2_canceled: false + + MouseArea { + id: mouseRegion1 + anchors.fill: parent + onPressed: { root.mr1_pressed = true } + onReleased: { root.mr1_released = true } + onCanceled: { root.mr1_canceled = true } + } + MouseArea { + id: mouseRegion2 + width: 120; height: 120 + onPressed: { root.mr2_pressed = true; mouse.accepted = false } + onReleased: { root.mr2_released = true } + onCanceled: { root.mr2_canceled = true } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnClick.qml b/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnClick.qml new file mode 100644 index 0000000000..7377a2e86c --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnClick.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +Rectangle { + color: "#ffffff" + width: 320; height: 240 + MouseArea { + id: mouseRegion + objectName: "mouseregion" + anchors.fill: parent + Rectangle { + id: ball + objectName: "ball" + width: 20; height: 20 + radius: 10 + color: "#0000ff" + x: { mouseRegion.mouseX } + y: mouseRegion.mouseY + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnResize.qml b/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnResize.qml new file mode 100644 index 0000000000..55af864060 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/data/updateMousePosOnResize.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 + +Rectangle { + color: "#ffffff" + width: 320; height: 240 + Rectangle { + id: brother + objectName: "brother" + color: "lightgreen" + x: 200; y: 100 + width: 120; height: 120 + } + MouseArea { + id: mouseRegion + objectName: "mouseregion" + + property int x1 + property int y1 + property int x2 + property int y2 + property bool emitPositionChanged: false + property bool mouseMatchesPos: true + + anchors.fill: brother + onPressed: { + if (mouse.x != mouseX || mouse.y != mouseY) + mouseMatchesPos = false + x1 = mouseX; y1 = mouseY + anchors.fill = parent + } + onPositionChanged: { emitPositionChanged = true } + onMouseXChanged: { + if (mouse.x != mouseX || mouse.y != mouseY) + mouseMatchesPos = false + x2 = mouseX; y2 = mouseY + } + onMouseYChanged: { + if (mouse.x != mouseX || mouse.y != mouseY) + mouseMatchesPos = false + x2 = mouseX; y2 = mouseY + } + } +} diff --git a/tests/auto/qtquick2/qquickmousearea/qquickmousearea.pro b/tests/auto/qtquick2/qquickmousearea/qquickmousearea.pro new file mode 100644 index 0000000000..fcf166b0ed --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/qquickmousearea.pro @@ -0,0 +1,14 @@ +CONFIG += testcase +TARGET = tst_qquickmousearea +macx:CONFIG -= app_bundle + +HEADERS += ../../shared/testhttpserver.h +SOURCES += tst_qquickmousearea.cpp ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/qtquick2/qquickmousearea/tst_qquickmousearea.cpp new file mode 100644 index 0000000000..7c9af4ba64 --- /dev/null +++ b/tests/auto/qtquick2/qquickmousearea/tst_qquickmousearea.cpp @@ -0,0 +1,824 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +//#define OLDWAY + +class tst_QQuickMouseArea: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + void dragProperties(); + void resetDrag(); + void dragging(); + void updateMouseAreaPosOnClick(); + void updateMouseAreaPosOnResize(); + void noOnClickedWithPressAndHold(); + void onMousePressRejected(); + void pressedCanceledOnWindowDeactivate(); + void doubleClick(); + void clickTwice(); + void pressedOrdering(); + void preventStealing(); + void clickThrough(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + void hoverPosition(); + void hoverPropagation(); + +private: + QQuickView *createView(); +}; + +void tst_QQuickMouseArea::initTestCase() +{ + +} + +void tst_QQuickMouseArea::cleanupTestCase() +{ + +} + +void tst_QQuickMouseArea::dragProperties() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragproperties.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QQuickDrag *drag = mouseRegion->drag(); + QVERIFY(mouseRegion != 0); + QVERIFY(drag != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == drag->target()); + QQuickItem *rootItem = qobject_cast(canvas->rootObject()); + QVERIFY(rootItem != 0); + QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); + drag->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + drag->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + + // axis + QCOMPARE(drag->axis(), QQuickDrag::XandYAxis); + QSignalSpy axisSpy(drag, SIGNAL(axisChanged())); + drag->setAxis(QQuickDrag::XAxis); + QCOMPARE(drag->axis(), QQuickDrag::XAxis); + QCOMPARE(axisSpy.count(),1); + drag->setAxis(QQuickDrag::XAxis); + QCOMPARE(axisSpy.count(),1); + + // minimum and maximum properties + QSignalSpy xminSpy(drag, SIGNAL(minimumXChanged())); + QSignalSpy xmaxSpy(drag, SIGNAL(maximumXChanged())); + QSignalSpy yminSpy(drag, SIGNAL(minimumYChanged())); + QSignalSpy ymaxSpy(drag, SIGNAL(maximumYChanged())); + + QCOMPARE(drag->xmin(), 0.0); + QCOMPARE(drag->xmax(), rootItem->width()-blackRect->width()); + QCOMPARE(drag->ymin(), 0.0); + QCOMPARE(drag->ymax(), rootItem->height()-blackRect->height()); + + drag->setXmin(10); + drag->setXmax(10); + drag->setYmin(10); + drag->setYmax(10); + + QCOMPARE(drag->xmin(), 10.0); + QCOMPARE(drag->xmax(), 10.0); + QCOMPARE(drag->ymin(), 10.0); + QCOMPARE(drag->ymax(), 10.0); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + drag->setXmin(10); + drag->setXmax(10); + drag->setYmin(10); + drag->setYmax(10); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + // filterChildren + QSignalSpy filterChildrenSpy(drag, SIGNAL(filterChildrenChanged())); + + drag->setFilterChildren(true); + + QVERIFY(drag->filterChildren()); + QCOMPARE(filterChildrenSpy.count(), 1); + + drag->setFilterChildren(true); + QCOMPARE(filterChildrenSpy.count(), 1); + + delete canvas; +} + +void tst_QQuickMouseArea::resetDrag() +{ + QQuickView *canvas = createView(); + + canvas->rootContext()->setContextProperty("haveTarget", QVariant(true)); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragreset.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QQuickDrag *drag = mouseRegion->drag(); + QVERIFY(mouseRegion != 0); + QVERIFY(drag != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == drag->target()); + QQuickItem *rootItem = qobject_cast(canvas->rootObject()); + QVERIFY(rootItem != 0); + QSignalSpy targetSpy(drag, SIGNAL(targetChanged())); + QVERIFY(drag->target() != 0); + canvas->rootContext()->setContextProperty("haveTarget", QVariant(false)); + QCOMPARE(targetSpy.count(),1); + QVERIFY(drag->target() == 0); + + delete canvas; +} + + +void tst_QQuickMouseArea::dragging() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragging.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWait(20); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QQuickDrag *drag = mouseRegion->drag(); + QVERIFY(mouseRegion != 0); + QVERIFY(drag != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == drag->target()); + + QVERIFY(!drag->active()); + +#ifdef OLDWAY + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); +#else + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); +#endif + + QVERIFY(!drag->active()); + QCOMPARE(blackRect->x(), 50.0); + QCOMPARE(blackRect->y(), 50.0); + + // First move event triggers drag, second is acted upon. + // This is due to possibility of higher stacked area taking precedence. + + QTest::mouseMove(canvas, QPoint(111,111)); + QTest::qWait(50); + QTest::mouseMove(canvas, QPoint(122,122)); + QTest::qWait(50); + + QVERIFY(drag->active()); + QCOMPARE(blackRect->x(), 72.0); + QCOMPARE(blackRect->y(), 72.0); + +#ifdef OLDWAY + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); +#else + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(122,122)); + QTest::qWait(50); +#endif + + QVERIFY(!drag->active()); + QCOMPARE(blackRect->x(), 72.0); + QCOMPARE(blackRect->y(), 72.0); + + delete canvas; +} + +QQuickView *tst_QQuickMouseArea::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setBaseSize(QSize(240,320)); + + return canvas; +} + +void tst_QQuickMouseArea::updateMouseAreaPosOnClick() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnClick.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QVERIFY(mouseRegion != 0); + + QQuickRectangle *rect = canvas->rootObject()->findChild("ball"); + QVERIFY(rect != 0); + + QCOMPARE(mouseRegion->mouseX(), rect->x()); + QCOMPARE(mouseRegion->mouseY(), rect->y()); + + QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &event); + + QCOMPARE(mouseRegion->mouseX(), 100.0); + QCOMPARE(mouseRegion->mouseY(), 100.0); + + QCOMPARE(mouseRegion->mouseX(), rect->x()); + QCOMPARE(mouseRegion->mouseY(), rect->y()); + + delete canvas; +} + +void tst_QQuickMouseArea::updateMouseAreaPosOnResize() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("updateMousePosOnResize.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickMouseArea *mouseRegion = canvas->rootObject()->findChild("mouseregion"); + QVERIFY(mouseRegion != 0); + + QQuickRectangle *rect = canvas->rootObject()->findChild("brother"); + QVERIFY(rect != 0); + + QCOMPARE(mouseRegion->mouseX(), 0.0); + QCOMPARE(mouseRegion->mouseY(), 0.0); + + QMouseEvent event(QEvent::MouseButtonPress, rect->pos().toPoint(), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &event); + + QVERIFY(!mouseRegion->property("emitPositionChanged").toBool()); + QVERIFY(mouseRegion->property("mouseMatchesPos").toBool()); + + QCOMPARE(mouseRegion->property("x1").toReal(), 0.0); + QCOMPARE(mouseRegion->property("y1").toReal(), 0.0); + + QCOMPARE(mouseRegion->property("x2").toReal(), rect->x()); + QCOMPARE(mouseRegion->property("y2").toReal(), rect->y()); + + QCOMPARE(mouseRegion->mouseX(), rect->x()); + QCOMPARE(mouseRegion->mouseY(), rect->y()); + + delete canvas; +} + +void tst_QQuickMouseArea::noOnClickedWithPressAndHold() +{ + { + // We handle onPressAndHold, therefore no onClicked + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickandhold.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QVERIFY(!canvas->rootObject()->property("clicked").toBool()); + QVERIFY(!canvas->rootObject()->property("held").toBool()); + + QTest::qWait(1000); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QVERIFY(!canvas->rootObject()->property("clicked").toBool()); + QVERIFY(canvas->rootObject()->property("held").toBool()); + + delete canvas; + } + + { + // We do not handle onPressAndHold, therefore we get onClicked + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("noclickandhold.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QVERIFY(!canvas->rootObject()->property("clicked").toBool()); + + QTest::qWait(1000); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QVERIFY(canvas->rootObject()->property("clicked").toBool()); + + delete canvas; + } +} + +void tst_QQuickMouseArea::onMousePressRejected() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("rejectEvent.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + QVERIFY(canvas->rootObject()->property("enabled").toBool()); + + QVERIFY(!canvas->rootObject()->property("mr1_pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("mr1_released").toBool()); + QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("mr2_pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); + QVERIFY(!canvas->rootObject()->property("mr2_canceled").toBool()); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QVERIFY(canvas->rootObject()->property("mr1_pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("mr1_released").toBool()); + QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); + QVERIFY(canvas->rootObject()->property("mr2_pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); + QVERIFY(canvas->rootObject()->property("mr2_canceled").toBool()); + + QTest::qWait(200); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QVERIFY(canvas->rootObject()->property("mr1_released").toBool()); + QVERIFY(!canvas->rootObject()->property("mr1_canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("mr2_released").toBool()); + + delete canvas; +} +void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedCanceled.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + QVERIFY(!canvas->rootObject()->property("pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("released").toBool()); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QVERIFY(canvas->rootObject()->property("pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("released").toBool()); + + QTest::qWait(200); + + QEvent windowDeactivateEvent(QEvent::WindowDeactivate); + QApplication::sendEvent(canvas, &windowDeactivateEvent); + QVERIFY(!canvas->rootObject()->property("pressed").toBool()); + QVERIFY(canvas->rootObject()->property("canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("released").toBool()); + + QTest::qWait(200); + + //press again + QApplication::sendEvent(canvas, &pressEvent); + QVERIFY(canvas->rootObject()->property("pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("canceled").toBool()); + QVERIFY(!canvas->rootObject()->property("released").toBool()); + + QTest::qWait(200); + + //release + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + QVERIFY(!canvas->rootObject()->property("pressed").toBool()); + QVERIFY(!canvas->rootObject()->property("canceled").toBool()); + QVERIFY(canvas->rootObject()->property("released").toBool()); + + delete canvas; +} +void tst_QQuickMouseArea::doubleClick() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("doubleclick.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("released").toInt(), 1); + + pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QApplication::sendEvent(canvas, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("doubleClicked").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("released").toInt(), 2); + + delete canvas; +} + +// QTBUG-14832 +void tst_QQuickMouseArea::clickTwice() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("clicktwice.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("released").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 1); + + pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QApplication::sendEvent(canvas, &pressEvent); + QApplication::sendEvent(canvas, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("pressed").toInt(), 2); + QCOMPARE(canvas->rootObject()->property("released").toInt(), 2); + QCOMPARE(canvas->rootObject()->property("clicked").toInt(), 2); + + delete canvas; +} + +void tst_QQuickMouseArea::pressedOrdering() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pressedOrdering.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("base")); + + QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &pressEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); + + QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, 0); + QApplication::sendEvent(canvas, &releaseEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("toggled")); + + QApplication::sendEvent(canvas, &pressEvent); + + QCOMPARE(canvas->rootObject()->property("value").toString(), QLatin1String("pressed")); + + delete canvas; +} + +void tst_QQuickMouseArea::preventStealing() +{ + QQuickView *canvas = createView(); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("preventstealing.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QQuickMouseArea *mouseArea = canvas->rootObject()->findChild("mousearea"); + QVERIFY(mouseArea != 0); + + QSignalSpy mousePositionSpy(mouseArea, SIGNAL(positionChanged(QQuickMouseEvent*))); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80)); + + // Without preventStealing, mouse movement over MouseArea would + // cause the Flickable to steal mouse and trigger content movement. + + QTest::mouseMove(canvas,QPoint(69,69)); + QTest::mouseMove(canvas,QPoint(58,58)); + QTest::mouseMove(canvas,QPoint(47,47)); + + // We should have received all three move events + QCOMPARE(mousePositionSpy.count(), 3); + QVERIFY(mouseArea->pressed()); + + // Flickable content should not have moved. + QCOMPARE(flickable->contentX(), 0.); + QCOMPARE(flickable->contentY(), 0.); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(47, 47)); + + // Now allow stealing and confirm Flickable does its thing. + canvas->rootObject()->setProperty("stealing", false); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(80, 80)); + + // Without preventStealing, mouse movement over MouseArea would + // cause the Flickable to steal mouse and trigger content movement. + + QTest::mouseMove(canvas,QPoint(69,69)); + QTest::mouseMove(canvas,QPoint(58,58)); + QTest::mouseMove(canvas,QPoint(47,47)); + + // We should only have received the first move event + QCOMPARE(mousePositionSpy.count(), 4); + // Our press should be taken away + QVERIFY(!mouseArea->pressed()); + + // Flickable content should have moved. + + QCOMPARE(flickable->contentX(), 11.); + QCOMPARE(flickable->contentY(), 11.); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(50, 50)); + + delete canvas; +} + +void tst_QQuickMouseArea::clickThrough() +{ + //With no handlers defined click, doubleClick and PressAndHold should propagate to those with handlers + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); + + QTest::qWait(800); // to avoid generating a double click. + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(1000); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QTRY_COMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); + QTRY_COMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); + + QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); + QTRY_COMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); + + delete canvas; + + //With handlers defined click, doubleClick and PressAndHold should propagate only when explicitly ignored + canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("clickThrough2.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); + + QTest::qWait(800); // to avoid generating a double click. + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(1000); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0); + + QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 0); + + canvas->rootObject()->setProperty("letThrough", QVariant(true)); + + QTest::qWait(800); // to avoid generating a double click. + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 1); + + QTest::qWait(800); // to avoid generating a double click. + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(1000); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("clicks").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); + + QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); + QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); + + canvas->rootObject()->setProperty("noPropagation", QVariant(true)); + + QTest::qWait(800); // to avoid generating a double click. + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + + QTest::qWait(800); // to avoid generating a double click. + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(1000); + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QTest::mouseDClick(canvas, Qt::LeftButton, 0, QPoint(100,100)); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("presses").toInt(), 0); + QTRY_COMPARE(canvas->rootObject()->property("clicks").toInt(), 2); + QCOMPARE(canvas->rootObject()->property("doubleClicks").toInt(), 1); + QCOMPARE(canvas->rootObject()->property("pressAndHolds").toInt(), 1); + + delete canvas; +} + +void tst_QQuickMouseArea::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 1.1; MouseArea { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; MouseArea { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_QQuickMouseArea::testQtQuick11Attributes_data() +{ + QTest::addColumn("code"); + QTest::addColumn("warning"); + QTest::addColumn("error"); + + QTest::newRow("preventStealing") << "preventStealing: true" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n"; +} + +void tst_QQuickMouseArea::hoverPosition() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPosition.qml"))); + + QQuickItem *root = canvas->rootObject(); + QVERIFY(root != 0); + + QCOMPARE(root->property("mouseX").toReal(), qreal(0)); + QCOMPARE(root->property("mouseY").toReal(), qreal(0)); + + QTest::mouseMove(canvas,QPoint(10,32)); + + + QCOMPARE(root->property("mouseX").toReal(), qreal(10)); + QCOMPARE(root->property("mouseY").toReal(), qreal(32)); + + delete canvas; +} + +void tst_QQuickMouseArea::hoverPropagation() +{ + //QTBUG-18175, to behave like GV did. + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("hoverPropagation.qml"))); + + QQuickItem *root = canvas->rootObject(); + QVERIFY(root != 0); + + QCOMPARE(root->property("point1").toBool(), false); + QCOMPARE(root->property("point2").toBool(), false); + + QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, 0); + QApplication::sendEvent(canvas, &moveEvent); + + QCOMPARE(root->property("point1").toBool(), true); + QCOMPARE(root->property("point2").toBool(), false); + + QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, 0); + QApplication::sendEvent(canvas, &moveEvent2); + QCOMPARE(root->property("point1").toBool(), false); + QCOMPARE(root->property("point2").toBool(), true); + + delete canvas; +} + +QTEST_MAIN(tst_QQuickMouseArea) + +#include "tst_qquickmousearea.moc" diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/data/inFlickable.qml b/tests/auto/qtquick2/qquickmultipointtoucharea/data/inFlickable.qml new file mode 100644 index 0000000000..53a2bf87f9 --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/data/inFlickable.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +Flickable { + width: 240 + height: 320 + + contentWidth: width + contentHeight: height * 2 + + MultiPointTouchArea { + anchors.fill: parent + minimumTouchPoints: 2 + maximumTouchPoints: 2 + onGestureStarted: { + if ((Math.abs(point2.x - point2.startX) > gesture.dragThreshold/2) && (Math.abs(point1.x - point1.startX) > gesture.dragThreshold/2)) { + gesture.grab() + } + } + touchPoints: [ + TouchPoint { id: point1; objectName: "point1" }, + TouchPoint { id: point2; objectName: "point2" } + ] + } +} + diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/data/nested.qml b/tests/auto/qtquick2/qquickmultipointtoucharea/data/nested.qml new file mode 100644 index 0000000000..37b8820aa0 --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/data/nested.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +MultiPointTouchArea { + width: 240 + height: 320 + + property bool grabInnerArea: true + + minimumTouchPoints: 2 + maximumTouchPoints: 3 + touchPoints: [ + TouchPoint { objectName: "point11" }, + TouchPoint { objectName: "point12" } + ] + + MultiPointTouchArea { + anchors.fill: parent + minimumTouchPoints: 3 + maximumTouchPoints: 3 + onGestureStarted: if (grabInnerArea) gesture.grab() + touchPoints: [ + TouchPoint { objectName: "point21" }, + TouchPoint { objectName: "point22" }, + TouchPoint { objectName: "point23" } + ] + } +} diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/data/nonOverlapping.qml b/tests/auto/qtquick2/qquickmultipointtoucharea/data/nonOverlapping.qml new file mode 100644 index 0000000000..039607e26c --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/data/nonOverlapping.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + + MultiPointTouchArea { + width: parent.width + height: 160 + minimumTouchPoints: 2 + maximumTouchPoints: 2 + onGestureStarted: gesture.grab() + touchPoints: [ + TouchPoint { objectName: "point11" }, + TouchPoint { objectName: "point12" } + ] + } + + MultiPointTouchArea { + width: parent.width + height: 160 + y: 160 + minimumTouchPoints: 3 + maximumTouchPoints: 3 + onGestureStarted: gesture.grab() + touchPoints: [ + TouchPoint { objectName: "point21" }, + TouchPoint { objectName: "point22" }, + TouchPoint { objectName: "point23" } + ] + } +} diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/data/properties.qml b/tests/auto/qtquick2/qquickmultipointtoucharea/data/properties.qml new file mode 100644 index 0000000000..98ef1a9cbe --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/data/properties.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +MultiPointTouchArea { + width: 240 + height: 320 + + minimumTouchPoints: 2 + maximumTouchPoints: 4 + touchPoints: [ + TouchPoint {}, + TouchPoint {}, + TouchPoint {}, + TouchPoint {} + ] +} diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/data/signalTest.qml b/tests/auto/qtquick2/qquickmultipointtoucharea/data/signalTest.qml new file mode 100644 index 0000000000..3a6aa86a1c --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/data/signalTest.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +MultiPointTouchArea { + width: 240 + height: 320 + + function clearCounts() { + touchPointPressCount = 0; + touchPointUpdateCount = 0; + touchPointReleaseCount = 0; + touchCount = 0; + } + + property int touchPointPressCount: 0 + property int touchPointUpdateCount: 0 + property int touchPointReleaseCount: 0 + property int touchCount: 0 + + maximumTouchPoints: 5 + + onTouchPointsPressed: { touchPointPressCount = touchPoints.length } + onTouchPointsUpdated: { touchPointUpdateCount = touchPoints.length } + onTouchPointsReleased: { touchPointReleaseCount = touchPoints.length } + onTouchUpdated: { touchCount = touchPoints.length } +} diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/qquickmultipointtoucharea.pro b/tests/auto/qtquick2/qquickmultipointtoucharea/qquickmultipointtoucharea.pro new file mode 100644 index 0000000000..38c32099b0 --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/qquickmultipointtoucharea.pro @@ -0,0 +1,11 @@ +TARGET = tst_qquickmultipointtoucharea +CONFIG += testcase +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickmultipointtoucharea.cpp + +importFiles.files = data +importFiles.path = . +DEPLOYMENT += importFiles + +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/qtquick2/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp new file mode 100644 index 0000000000..b4fca9bb9e --- /dev/null +++ b/tests/auto/qtquick2/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp @@ -0,0 +1,586 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +class tst_QQuickMultiPointTouchArea: public QObject +{ + Q_OBJECT +private slots: + void initTestCase() {} + void cleanupTestCase() {} + + void properties(); + void signalTest(); + void nonOverlapping(); + void nested(); + void inFlickable(); + +private: + QQuickView *createAndShowView(const QString &file); +}; + +void tst_QQuickMultiPointTouchArea::properties() +{ + QQuickView *canvas = createAndShowView("properties.qml"); + QVERIFY(canvas->rootObject() != 0); + + QQuickMultiPointTouchArea *area = qobject_cast(canvas->rootObject()); + QVERIFY(area != 0); + + QCOMPARE(area->minimumTouchPoints(), 2); + QCOMPARE(area->maximumTouchPoints(), 4); + + QDeclarativeListReference ref(area, "touchPoints"); + QCOMPARE(ref.count(), 4); + + delete canvas; +} + +void tst_QQuickMultiPointTouchArea::signalTest() +{ + QQuickView *canvas = createAndShowView("signalTest.qml"); + QVERIFY(canvas->rootObject() != 0); + + QQuickMultiPointTouchArea *area = qobject_cast(canvas->rootObject()); + QVERIFY(area != 0); + + QPoint p1(20,100); + QPoint p2(40,100); + QPoint p3(60,100); + QPoint p4(80,100); + QPoint p5(100,100); + + QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); + + sequence.press(0, p1).press(1, p2).commit(); + + QCOMPARE(area->property("touchPointPressCount").toInt(), 2); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchCount").toInt(), 2); + QMetaObject::invokeMethod(area, "clearCounts"); + + sequence.stationary(0).stationary(1).press(2, p3).commit(); + + QCOMPARE(area->property("touchPointPressCount").toInt(), 1); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchCount").toInt(), 3); + QMetaObject::invokeMethod(area, "clearCounts"); + + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + sequence.move(0, p1).move(1, p2).stationary(2).commit(); + + QCOMPARE(area->property("touchPointPressCount").toInt(), 0); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 2); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0); + QCOMPARE(area->property("touchCount").toInt(), 3); + QMetaObject::invokeMethod(area, "clearCounts"); + + p3 += QPoint(10,10); + sequence.release(0, p1).release(1, p2) + .move(2, p3).press(3, p4).press(4, p5).commit(); + + QCOMPARE(area->property("touchPointPressCount").toInt(), 2); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 1); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 2); + QCOMPARE(area->property("touchCount").toInt(), 3); + QMetaObject::invokeMethod(area, "clearCounts"); + + sequence.release(2, p3).release(3, p4).release(4, p5).commit(); + + QCOMPARE(area->property("touchPointPressCount").toInt(), 0); + QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0); + QCOMPARE(area->property("touchPointReleaseCount").toInt(), 3); + QCOMPARE(area->property("touchCount").toInt(), 0); + QMetaObject::invokeMethod(area, "clearCounts"); + + delete canvas; +} + +void tst_QQuickMultiPointTouchArea::nonOverlapping() +{ + QQuickView *canvas = createAndShowView("nonOverlapping.qml"); + QVERIFY(canvas->rootObject() != 0); + + QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point11"); + QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point12"); + QQuickTouchPoint *point21 = canvas->rootObject()->findChild("point21"); + QQuickTouchPoint *point22 = canvas->rootObject()->findChild("point22"); + QQuickTouchPoint *point23 = canvas->rootObject()->findChild("point23"); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QPoint p1(20,100); + QPoint p2(40,100); + QPoint p3(60,180); + QPoint p4(80,180); + QPoint p5(100,180); + + QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); + + sequence.press(0, p1).commit(); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + sequence.stationary(0).press(1, p2).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); + QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); + + p1 += QPoint(0,10); + p2 += QPoint(5,0); + sequence.move(0, p1).move(1, p2).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + + sequence.stationary(0).stationary(1).press(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + sequence.stationary(0).stationary(1).stationary(2).press(3, p4).press(4, p5).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + QCOMPARE(point21->x(), qreal(60)); QCOMPARE(point21->y(), qreal(20)); + QCOMPARE(point22->x(), qreal(80)); QCOMPARE(point22->y(), qreal(20)); + QCOMPARE(point23->x(), qreal(100)); QCOMPARE(point23->y(), qreal(20)); + + p1 += QPoint(4,10); + p2 += QPoint(17,17); + p3 += QPoint(3,0); + p4 += QPoint(1,-1); + p5 += QPoint(-7,10); + sequence.move(0, p1).move(1, p2).move(2, p3).move(3, p4).move(4, p5).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); + QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); + QCOMPARE(point21->x(), qreal(63)); QCOMPARE(point21->y(), qreal(20)); + QCOMPARE(point22->x(), qreal(81)); QCOMPARE(point22->y(), qreal(19)); + QCOMPARE(point23->x(), qreal(93)); QCOMPARE(point23->y(), qreal(30)); + + sequence.release(0, p1).release(1, p2).release(2, p3).release(3, p4).release(4, p5).commit(); + + //points remain valid immediately after release + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + delete canvas; +} + +void tst_QQuickMultiPointTouchArea::nested() +{ + QQuickView *canvas = createAndShowView("nested.qml"); + QVERIFY(canvas->rootObject() != 0); + + QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point11"); + QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point12"); + QQuickTouchPoint *point21 = canvas->rootObject()->findChild("point21"); + QQuickTouchPoint *point22 = canvas->rootObject()->findChild("point22"); + QQuickTouchPoint *point23 = canvas->rootObject()->findChild("point23"); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QPoint p1(20,100); + QPoint p2(40,100); + QPoint p3(60,180); + + QTest::QTouchEventSequence sequence = QTest::touchEvent(canvas); + + sequence.press(0, p1).commit(); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + sequence.stationary(0).press(1, p2).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(100)); + QCOMPARE(point12->x(), qreal(40)); QCOMPARE(point12->y(), qreal(100)); + + p1 += QPoint(0,10); + p2 += QPoint(5,0); + sequence.move(0, p1).move(1, p2).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + + sequence.stationary(0).stationary(1).press(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + //point11 should be same as point21, point12 same as point22 + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); + QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); + QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); + + sequence.stationary(0).stationary(1).stationary(2).press(3, QPoint(80,180)).press(4, QPoint(100,180)).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + //new touch points should be ignored (have no impact on our existing touch points) + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); + QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); + QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); + + sequence.stationary(0).stationary(1).stationary(2).release(3, QPoint(80,180)).release(4, QPoint(100,180)).commit(); + + p1 += QPoint(4,10); + p2 += QPoint(17,17); + p3 += QPoint(3,0); + sequence.move(0, p1).move(1, p2).move(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); + QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); + QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); + QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); + QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); + + p1 += QPoint(4,10); + p2 += QPoint(17,17); + p3 += QPoint(3,0); + sequence.move(0, p1).move(1, p2).move(2, p3).commit(); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + //first two remain the same (touches now grabbed by inner touch area) + QCOMPARE(point11->x(), qreal(24)); QCOMPARE(point11->y(), qreal(120)); + QCOMPARE(point12->x(), qreal(62)); QCOMPARE(point12->y(), qreal(117)); + QCOMPARE(point21->x(), qreal(28)); QCOMPARE(point21->y(), qreal(130)); + QCOMPARE(point22->x(), qreal(79)); QCOMPARE(point22->y(), qreal(134)); + QCOMPARE(point23->x(), qreal(66)); QCOMPARE(point23->y(), qreal(180)); + + sequence.release(0, p1).release(1, p2).release(2, p3).commit(); + + sequence.press(0, p1).commit(); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + QCOMPARE(point21->isValid(), false); + QCOMPARE(point22->isValid(), false); + QCOMPARE(point23->isValid(), false); + + sequence.release(0, p1).commit(); + + //test with grabbing turned off + canvas->rootObject()->setProperty("grabInnerArea", false); + + sequence.press(0, p1).press(1, p2).press(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + p1 -= QPoint(4,10); + p2 -= QPoint(17,17); + p3 -= QPoint(3,0); + sequence.move(0, p1).move(1, p2).move(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); + QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); + QCOMPARE(point21->x(), qreal(24)); QCOMPARE(point21->y(), qreal(120)); + QCOMPARE(point22->x(), qreal(62)); QCOMPARE(point22->y(), qreal(117)); + QCOMPARE(point23->x(), qreal(63)); QCOMPARE(point23->y(), qreal(180)); + + p1 -= QPoint(4,10); + p2 -= QPoint(17,17); + p3 -= QPoint(3,0); + sequence.move(0, p1).move(1, p2).move(2, p3).commit(); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + QCOMPARE(point21->isValid(), true); + QCOMPARE(point22->isValid(), true); + QCOMPARE(point23->isValid(), true); + + //all change (touches not grabbed by inner touch area) + QCOMPARE(point11->x(), qreal(20)); QCOMPARE(point11->y(), qreal(110)); + QCOMPARE(point12->x(), qreal(45)); QCOMPARE(point12->y(), qreal(100)); + QCOMPARE(point21->x(), qreal(20)); QCOMPARE(point21->y(), qreal(110)); + QCOMPARE(point22->x(), qreal(45)); QCOMPARE(point22->y(), qreal(100)); + QCOMPARE(point23->x(), qreal(60)); QCOMPARE(point23->y(), qreal(180)); + + sequence.release(0, p1).release(1, p2).release(2, p3).commit(); + + delete canvas; +} + +void tst_QQuickMultiPointTouchArea::inFlickable() +{ + QQuickView *canvas = createAndShowView("inFlickable.qml"); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlickable *flickable = qobject_cast(canvas->rootObject()); + QVERIFY(flickable != 0); + + QQuickTouchPoint *point11 = canvas->rootObject()->findChild("point1"); + QQuickTouchPoint *point12 = canvas->rootObject()->findChild("point2"); + + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + + QPoint p1(20,100); + QPoint p2(40,100); + + //moving one point vertically + QTest::touchEvent(canvas).press(0, p1); + QTest::mousePress(canvas, Qt::LeftButton, 0, p1); + + p1 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1); + QTest::mouseMove(canvas, p1); + + QVERIFY(flickable->contentY() < 0); + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + + QTest::touchEvent(canvas).release(0, p1); + QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); + QTest::qWait(50); + + QTRY_VERIFY(!flickable->isMoving()); + + //moving two points vertically + p1 = QPoint(20,100); + QTest::touchEvent(canvas).press(0, p1).press(1, p2); + QTest::mousePress(canvas, Qt::LeftButton, 0, p1); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + QVERIFY(flickable->contentY() < 0); + QCOMPARE(point11->isValid(), false); + QCOMPARE(point12->isValid(), false); + + QTest::touchEvent(canvas).release(0, p1).release(1, p2); + QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); + QTest::qWait(50); + + QTRY_VERIFY(!flickable->isMoving()); + + //moving two points horizontally, then one point vertically + p1 = QPoint(20,100); + p2 = QPoint(40,100); + QTest::touchEvent(canvas).press(0, p1).press(1, p2); + QTest::mousePress(canvas, Qt::LeftButton, 0, p1); + + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + + p1 += QPoint(15,0); p2 += QPoint(15,0); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(15,0); p2 += QPoint(15,0); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(15,0); p2 += QPoint(15,0); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(15,0); p2 += QPoint(15,0); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + p1 += QPoint(0,15); p2 += QPoint(0,15); + QTest::touchEvent(canvas).move(0, p1).move(1, p2); + QTest::mouseMove(canvas, p1); + + QVERIFY(flickable->contentY() == 0); + QCOMPARE(point11->isValid(), true); + QCOMPARE(point12->isValid(), true); + + QTest::touchEvent(canvas).release(0, p1).release(1, p2); + QTest::mouseRelease(canvas,Qt::LeftButton, 0, p1); + QTest::qWait(50); + + delete canvas; +} + +QQuickView *tst_QQuickMultiPointTouchArea::createAndShowView(const QString &file) +{ + QQuickView *canvas = new QQuickView(0); + canvas->setSource(QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + QLatin1String("/data/") + file)); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + + return canvas; +} + +QTEST_MAIN(tst_QQuickMultiPointTouchArea) + +#include "tst_qquickmultipointtoucharea.moc" diff --git a/tests/auto/qtquick2/qquickpathview/data/ComponentView.qml b/tests/auto/qtquick2/qquickpathview/data/ComponentView.qml new file mode 100644 index 0000000000..b61033d375 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/ComponentView.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +PathView { + id: view + + property string title + + width: 100; height: 100; + + model: 1 + delegate: Text { objectName: "listItem"; text: view.title } + + path: Path { + startX: 25; startY: 25; + PathLine { x: 75; y: 75 } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/asyncloader.qml b/tests/auto/qtquick2/qquickpathview/data/asyncloader.qml new file mode 100644 index 0000000000..94f560f3e7 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/asyncloader.qml @@ -0,0 +1,71 @@ +import QtQuick 2.0 + +Rectangle { + id: root + property real delegateWidth: 60 + property real delegateHeight: 20 + property real delegateScale: 1.0 + width: 240 + height: 320 + color: "#ffffff" + + Loader { + asynchronous: true + sourceComponent: viewComponent + anchors.fill: parent + } + + Component { + id: adelegate + Rectangle { + objectName: "wrapper" + property bool onPath: PathView.onPath + height: root.delegateHeight + width: root.delegateWidth + scale: root.delegateScale + color: PathView.isCurrentItem ? "lightsteelblue" : "white" + border.color: "black" + Text { + text: index + } + } + } + Component { + id: viewComponent + PathView { + id: view + objectName: "view" + width: 240 + height: 320 + model: 5 + delegate: adelegate + highlight: Rectangle { + width: 60 + height: 20 + color: "yellow" + } + path: Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 0 + control2X: 200 + } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/closedPath.qml b/tests/auto/qtquick2/qquickpathview/data/closedPath.qml new file mode 100644 index 0000000000..3ca34056c8 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/closedPath.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/creationContext.qml b/tests/auto/qtquick2/qquickpathview/data/creationContext.qml new file mode 100644 index 0000000000..79a682788b --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/creationContext.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +ComponentView { + title: "Hello!" +} diff --git a/tests/auto/qtquick2/qquickpathview/data/datamodel.qml b/tests/auto/qtquick2/qquickpathview/data/datamodel.qml new file mode 100644 index 0000000000..44f2aecc0a --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/datamodel.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 + +PathView { + id: pathview + property int viewCount: count + objectName: "pathview" + width: 240; height: 320 + pathItemCount: testObject.pathItemCount + + function checkProperties() { + testObject.error = false; + if (testObject.useModel && pathview.model != testData) { + console.log("model property incorrect"); + testObject.error = true; + } + } + + model: testObject.useModel ? testData : 0 + + delegate: Component { + id: myDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + property bool onPath: PathView.onPath + width: 20; height: 20; color: name + Text { + objectName: "myText" + text: name + } + } + } + + path: Path { + startX: 120; startY: 20; + PathLine { x: 120; y: 300 } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/displaypath.qml b/tests/auto/qtquick2/qquickpathview/data/displaypath.qml new file mode 100644 index 0000000000..af0f381fc4 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/displaypath.qml @@ -0,0 +1,59 @@ +import QtQuick 2.0 + +Rectangle { + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: delegate + Rectangle { + id: wrapper + objectName: "wrapper" + height: 20 + width: 60 + color: "white" + border.color: "black" + Text { + text: index + } + Text { + x: 20 + id: displayText + objectName: "displayText" + text: display + } + } + } + ] + PathView { + id: view + objectName: "view" + width: 240 + height: 320 + model: testModel + delegate: delegate + path: Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/dragpath.qml b/tests/auto/qtquick2/qquickpathview/data/dragpath.qml new file mode 100644 index 0000000000..f9c6615b04 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/dragpath.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +PathView { + width: 400 + height: 200 + model: 100 + pathItemCount: 20 + path: Path { + startX: 0; startY: 100 + PathLine { x: 400; y: 100 } + } + delegate: Rectangle { objectName: "wrapper"; height: 100; width: 2; color: PathView.isCurrentItem?"red" : "black" } + dragMargin: 100 + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + Text { + text: "current index: " + parent.currentIndex + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/emptymodel.qml b/tests/auto/qtquick2/qquickpathview/data/emptymodel.qml new file mode 100644 index 0000000000..eb4d3006f4 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/emptymodel.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +PathView { + model: emptyModel +} diff --git a/tests/auto/qtquick2/qquickpathview/data/missingPercent.qml b/tests/auto/qtquick2/qquickpathview/data/missingPercent.qml new file mode 100644 index 0000000000..97af8e8982 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/missingPercent.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Path { + startY: 0 + startX: 0 + PathLine { x: 0; y: 50 } + PathPercent { value: .5 } + PathLine { x: 50; y: 50 } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/openPath.qml b/tests/auto/qtquick2/qquickpathview/data/openPath.qml new file mode 100644 index 0000000000..1bd8375d9e --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/openPath.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Path { + startY: 120 + startX: 160 + PathLine { + y: 160 + x: 20 + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathUpdate.qml b/tests/auto/qtquick2/qquickpathview/data/pathUpdate.qml new file mode 100644 index 0000000000..e729291025 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathUpdate.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 400 + + PathView { + id: view + objectName: "pathView" + anchors.fill: parent + model: 10 + delegate: Rectangle { objectName: "wrapper"; color: "green"; width: 100; height: 100 } + path: Path { + startX: view.width/2; startY: 0 + PathLine { x: view.width/2; y: view.height } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathUpdateOnStartChanged.qml b/tests/auto/qtquick2/qquickpathview/data/pathUpdateOnStartChanged.qml new file mode 100644 index 0000000000..89084b2a37 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathUpdateOnStartChanged.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 + +Rectangle { + width: 800 + height: 480 + color: "black" + resources: [ + ListModel { + id: appModel + ListElement { color: "green" } + }, + Component { + id: appDelegate + Rectangle { + id: wrapper + objectName: "wrapper" + color: "green" + width: 100 + height: 100 + } + } + ] + PathView { + id: pathView + objectName: "pathView" + model: appModel + anchors.fill: parent + + transformOrigin: "Top" + delegate: appDelegate + path: Path { + objectName: "path" + startX: pathView.width / 2 // startX: 400 <- this works as expected + startY: 300 + PathLine { x: 400; y: 120 } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathline.qml b/tests/auto/qtquick2/qquickpathview/data/pathline.qml new file mode 100644 index 0000000000..4c1c785bce --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathline.qml @@ -0,0 +1,48 @@ +import QtQuick 2.0 + +Rectangle { + id: app + width: 360 + height: 360 + + PathView { + id: pathView + objectName: "view" + x: (app.width-pathView.width)/2 + y: 100 + width: 240 + height: 100 + + model: testModel + + Rectangle { + anchors.fill: parent + color: "white" + border.color: "black" + } + preferredHighlightBegin: 0.5 + preferredHighlightEnd: 0.5 + + delegate: Rectangle { + objectName: "wrapper" + width: 100 + height: 100 + color: PathView.isCurrentItem ? "red" : "yellow" + Text { + text: index + anchors.centerIn: parent + } + z: (PathView.isCurrentItem?1:0) + } + path: Path { + id: path + startX: -100+pathView.width/2 + startY: pathView.height/2 + PathLine { + id: line + x: 100+pathView.width/2 + y: pathView.height/2 + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathtest.qml b/tests/auto/qtquick2/qquickpathview/data/pathtest.qml new file mode 100644 index 0000000000..736d58d2a9 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathtest.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +Path { + startX: 120; startY: 100 + + PathAttribute { name: "scale"; value: 1.0 } + PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 } + PathPercent { value: 0.3 } + PathLine { x: 120; y: 100 } + PathCubic { + x: 180; y: 0; control1X: -10; control1Y: 90 + control2X: 210; control2Y: 90 + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathview0.qml b/tests/auto/qtquick2/qquickpathview/data/pathview0.qml new file mode 100644 index 0000000000..8b9378163f --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathview0.qml @@ -0,0 +1,85 @@ +import QtQuick 2.0 + +Rectangle { + id: root + property int count: view.count + property int currentA: -1 + property int currentB: -1 + property real delegateWidth: 60 + property real delegateHeight: 20 + property real delegateScale: 1.0 + width: 240 + height: 320 + color: "#ffffff" + resources: [ + Component { + id: delegate + Rectangle { + id: wrapper + objectName: "wrapper" + property bool onPath: PathView.onPath + height: root.delegateHeight + width: root.delegateWidth + scale: root.delegateScale + color: PathView.isCurrentItem ? "lightsteelblue" : "white" + border.color: "black" + Text { + text: index + } + Text { + x: 20 + id: textName + objectName: "textName" + text: name + } + Text { + x: 40 + id: textNumber + objectName: "textNumber" + text: number + } + PathView.onCurrentItemChanged: { + if (PathView.isCurrentItem) { + root.currentA = index; + root.currentB = wrapper.PathView.view.currentIndex; + } + } + } + } + ] + PathView { + id: view + objectName: "view" + width: 240 + height: 320 + model: testModel + delegate: delegate + highlight: Rectangle { + width: 60 + height: 20 + color: "yellow" + } + path: Path { + startY: 120 + startX: 160 + PathQuad { + y: 120 + x: 80 + controlY: 330 + controlX: 100 + } + PathLine { + y: 160 + x: 20 + } + PathCubic { + y: 120 + x: 160 + control1Y: 0 + control1X: 100 + control2Y: 000 + control2X: 200 + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathview1.qml b/tests/auto/qtquick2/qquickpathview/data/pathview1.qml new file mode 100644 index 0000000000..53d375e596 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathview1.qml @@ -0,0 +1,4 @@ +import QtQuick 2.0 + +PathView { +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathview2.qml b/tests/auto/qtquick2/qquickpathview/data/pathview2.qml new file mode 100644 index 0000000000..1d279c42a0 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathview2.qml @@ -0,0 +1,57 @@ +import QtQuick 2.0 + +PathView { + id: photoPathView + y: 100; width: 800; height: 330; pathItemCount: 10; z: 1 + + path: Path { + startX: -50; startY: 40; + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: -45 } + + PathCubic { + x: 400; y: 220 + control1X: 140; control1Y: 40 + control2X: 210; control2Y: 220 + } + + PathAttribute { name: "scale"; value: 1.2 } + PathAttribute { name: "angle"; value: 0 } + + PathCubic { + x: 850; y: 40 + control2X: 660; control2Y: 40 + control1X: 590; control1Y: 220 + } + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: 45 } + } + + model: ListModel { + id: rssModel + ListElement { lColor: "red" } + ListElement { lColor: "green" } + ListElement { lColor: "yellow" } + ListElement { lColor: "blue" } + ListElement { lColor: "purple" } + ListElement { lColor: "gray" } + ListElement { lColor: "brown" } + ListElement { lColor: "thistle" } + } + + delegate: Component { + id: photoDelegate + Rectangle { + id: wrapper + width: 85; height: 85; color: lColor + scale: wrapper.PathView.scale + + transform: Rotation { + id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 + axis.y: 1; axis.z: 0; angle: wrapper.PathView.angle + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathview3.qml b/tests/auto/qtquick2/qquickpathview/data/pathview3.qml new file mode 100644 index 0000000000..ded5a3911c --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathview3.qml @@ -0,0 +1,59 @@ +import QtQuick 2.0 + +PathView { + id: photoPathView + y: 100; width: 800; height: 330; pathItemCount: 4; offset: 1 + dragMargin: 24 + preferredHighlightBegin: 0.50 + preferredHighlightEnd: 0.50 + + path: Path { + startX: -50; startY: 40; + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: -45 } + + PathCubic { + x: 400; y: 220 + control1X: 140; control1Y: 40 + control2X: 210; control2Y: 220 + } + + PathAttribute { name: "scale"; value: 1.2 } + PathAttribute { name: "angle"; value: 0 } + + PathCubic { + x: 850; y: 40 + control2X: 660; control2Y: 40 + control1X: 590; control1Y: 220 + } + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: 45 } + } + + model: ListModel { + id: rssModel + ListElement { lColor: "red" } + ListElement { lColor: "green" } + ListElement { lColor: "yellow" } + ListElement { lColor: "blue" } + ListElement { lColor: "purple" } + ListElement { lColor: "gray" } + ListElement { lColor: "brown" } + ListElement { lColor: "thistle" } + } + + delegate: Component { + id: photoDelegate + Rectangle { + id: wrapper + width: 85; height: 85; color: lColor + + transform: Rotation { + id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 + axis.y: 1; axis.z: 0 + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/pathview_package.qml b/tests/auto/qtquick2/qquickpathview/data/pathview_package.qml new file mode 100644 index 0000000000..2af57e6bb1 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/pathview_package.qml @@ -0,0 +1,88 @@ +import QtQuick 2.0 + +Item { + width: 800; height: 600 + Component { + id: photoDelegate + Package { + Item { id: pathItem; objectName: "pathItem"; Package.name: 'path'; width: 85; height: 85; scale: pathItem.PathView.scale } + Item { id: linearItem; Package.name: 'linear'; width: 85; height: 85 } + Rectangle { + id: wrapper + width: 85; height: 85; color: lColor + + transform: Rotation { + id: itemRotation; origin.x: wrapper.width/2; origin.y: wrapper.height/2 + axis.y: 1; axis.z: 0 + } + state: 'path' + states: [ + State { + name: 'path' + ParentChange { target: wrapper; parent: pathItem; x: 0; y: 0 } + PropertyChanges { target: wrapper; opacity: pathItem.PathView.onPath ? 1.0 : 0 } + } + ] + } + } + } + ListModel { + id: rssModel + ListElement { lColor: "red" } + ListElement { lColor: "green" } + ListElement { lColor: "yellow" } + ListElement { lColor: "blue" } + ListElement { lColor: "purple" } + ListElement { lColor: "gray" } + ListElement { lColor: "brown" } + ListElement { lColor: "thistle" } + } + VisualDataModel { id: visualModel; model: rssModel; delegate: photoDelegate } + + PathView { + id: photoPathView + objectName: "photoPathView" + width: 800; height: 330; pathItemCount: 4; offset: 1 + dragMargin: 24 + preferredHighlightBegin: 0.50 + preferredHighlightEnd: 0.50 + + path: Path { + startX: -50; startY: 40; + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: -45 } + + PathCubic { + x: 400; y: 220 + control1X: 140; control1Y: 40 + control2X: 210; control2Y: 220 + } + + PathAttribute { name: "scale"; value: 1.2 } + PathAttribute { name: "angle"; value: 0 } + + PathCubic { + x: 850; y: 40 + control2X: 660; control2Y: 40 + control1X: 590; control1Y: 220 + } + + PathAttribute { name: "scale"; value: 0.5 } + PathAttribute { name: "angle"; value: 45 } + } + + model: visualModel.parts.path + } + + PathView { + y: 400; width: 800; height: 330; pathItemCount: 8 + + path: Path { + startX: 0; startY: 40; + PathLine { x: 800; y: 40 } + } + + model: visualModel.parts.linear + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/propertychanges.qml b/tests/auto/qtquick2/qquickpathview/data/propertychanges.qml new file mode 100644 index 0000000000..09b309f86f --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/propertychanges.qml @@ -0,0 +1,116 @@ +import QtQuick 2.0 + +Rectangle { + width: 350; height: 220; color: "white" + Component { + id: myDelegate + Item { + id: wrapper + width: 180; height: 40; + opacity: PathView.opacity + Column { + x: 5; y: 5 + Text { text: 'Name: ' + name } + Text { text: 'Number: ' + number } + } + } + } + + PathView { + preferredHighlightBegin: 0.1 + preferredHighlightEnd: 0.1 + dragMargin: 5.0 + id: pathView + objectName: "pathView" + anchors.fill: parent + model: listModel + delegate: myDelegate + focus: true + path: Path { + id: myPath + objectName: "path" + startX: 220; startY: 200 + PathAttribute { name: "opacity"; value: 1.0; objectName: "pathAttribute"; } + PathQuad { x: 220; y: 25; controlX: 260; controlY: 75 } + PathAttribute { name: "opacity"; value: 0.3 } + PathQuad { x: 220; y: 200; controlX: -20; controlY: 75 } + } + Timer { + interval: 2000; running: true; repeat: true + onTriggered: { + if (pathView.path == alternatePath) + pathView.path = myPath; + else + pathView.path = alternatePath; + } + } + } + + data:[ + ListModel { + id: listModel + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + ListElement { + name: "Bill Smith" + number: "555 3264" + } + ListElement { + name: "John Brown" + number: "555 8426" + } + ListElement { + name: "Sam Wise" + number: "555 0473" + } + }, + ListModel { + objectName: "alternateModel" + ListElement { + name: "Jack" + number: "555 8426" + } + ListElement { + name: "Mary" + number: "555 3264" + } + }, + Path { + id: alternatePath + objectName: "alternatePath" + startX: 100; startY: 40 + PathAttribute { name: "opacity"; value: 0.0 } + PathLine { x: 100; y: 160 } + PathAttribute { name: "opacity"; value: 0.2 } + PathLine { x: 300; y: 160 } + PathAttribute { name: "opacity"; value: 0.0 } + PathLine { x: 300; y: 40 } + PathAttribute { name: "opacity"; value: 0.2 } + PathLine { x: 100; y: 40 } + } + ] +} + + diff --git a/tests/auto/qtquick2/qquickpathview/data/treemodel.qml b/tests/auto/qtquick2/qquickpathview/data/treemodel.qml new file mode 100644 index 0000000000..fcf6922d00 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/treemodel.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +PathView { + width: 320 + height: 240 + function setRoot(index) { + vdm.rootIndex = vdm.modelIndex(index); + } + model: VisualDataModel { + id: vdm + model: myModel + delegate: Text { objectName: "wrapper"; text: display } + } + + path: Path { + startX: 0; startY: 120 + PathLine { x: 320; y: 120 } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/undefinedpath.qml b/tests/auto/qtquick2/qquickpathview/data/undefinedpath.qml new file mode 100644 index 0000000000..674e7cca8d --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/undefinedpath.qml @@ -0,0 +1,17 @@ +import QtQuick 2.0 + +PathView { + id: pathView + width: 240; height: 200 + path: Path { + startX: pathView.undef/2.0; startY: 0 + PathLine { x: pathView.undef/2.0; y: 0 } + } + + delegate: Text { text: value } + model: ListModel { + ListElement { value: "one" } + ListElement { value: "two" } + ListElement { value: "three" } + } +} diff --git a/tests/auto/qtquick2/qquickpathview/data/vdm.qml b/tests/auto/qtquick2/qquickpathview/data/vdm.qml new file mode 100644 index 0000000000..839393d9bd --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/data/vdm.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +PathView { + id: pathView + width: 240; height: 320 + + pathItemCount: 4 + preferredHighlightBegin : 0.5 + preferredHighlightEnd : 0.5 + + path: Path { + startX: 120; startY: 20; + PathLine { x: 120; y: 300 } + } + + ListModel { + id: mo + ListElement { value: "one" } + ListElement { value: "two" } + ListElement { value: "three" } + } + + model: VisualDataModel { + delegate: Text { text: model.value } + model : mo + } +} + diff --git a/tests/auto/qtquick2/qquickpathview/qquickpathview.pro b/tests/auto/qtquick2/qquickpathview/qquickpathview.pro new file mode 100644 index 0000000000..6e16dd4879 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/qquickpathview.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickpathview +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickpathview.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private v8-private declarative-private quick-private widgets testlib diff --git a/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp b/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp new file mode 100644 index 0000000000..2f1d836c72 --- /dev/null +++ b/tests/auto/qtquick2/qquickpathview/tst_qquickpathview.cpp @@ -0,0 +1,1629 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/util.h" + +static void initStandardTreeModel(QStandardItemModel *model) +{ + QStandardItem *item; + item = new QStandardItem(QLatin1String("Row 1 Item")); + model->insertRow(0, item); + + item = new QStandardItem(QLatin1String("Row 2 Item")); + item->setCheckable(true); + model->insertRow(1, item); + + QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item")); + item->setChild(0, childItem); + + item = new QStandardItem(QLatin1String("Row 3 Item")); + item->setIcon(QIcon()); + model->insertRow(2, item); +} + + +class tst_QQuickPathView : public QObject +{ + Q_OBJECT +public: + tst_QQuickPathView(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void initValues(); + void items(); + void dataModel(); + void pathview2(); + void pathview3(); + void insertModel_data(); + void insertModel(); + void removeModel_data(); + void removeModel(); + void moveModel_data(); + void moveModel(); + void path(); + void pathMoved(); + void setCurrentIndex(); + void resetModel(); + void propertyChanges(); + void pathChanges(); + void componentChanges(); + void modelChanges(); + void pathUpdateOnStartChanged(); + void package(); + void emptyModel(); + void closed(); + void pathUpdate(); + void visualDataModel(); + void undefinedPath(); + void mouseDrag(); + void treeModel(); + void changePreferredHighlight(); + void missingPercent(); + void creationContext(); + void currentOffsetOnInsertion(); + void asynchronous(); + +private: + QQuickView *createView(); + template + T *findItem(QQuickItem *parent, const QString &objectName, int index=-1); + template + QList findItems(QQuickItem *parent, const QString &objectName); +}; + +void tst_QQuickPathView::initTestCase() +{ +} + +void tst_QQuickPathView::cleanupTestCase() +{ + +} + +class TestObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(bool error READ error WRITE setError) + Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged) + Q_PROPERTY(int pathItemCount READ pathItemCount NOTIFY pathItemCountChanged) + +public: + TestObject() : QObject(), mError(true), mUseModel(true), mPathItemCount(-1) {} + + bool error() const { return mError; } + void setError(bool err) { mError = err; } + + bool useModel() const { return mUseModel; } + void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); } + + int pathItemCount() const { return mPathItemCount; } + void setPathItemCount(int count) { mPathItemCount = count; emit pathItemCountChanged(); } + +signals: + void useModelChanged(); + void pathItemCountChanged(); + +private: + bool mError; + bool mUseModel; + int mPathItemCount; +}; + +class TestModel : public QAbstractListModel +{ +public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + TestModel(QObject *parent=0) : QAbstractListModel(parent) { + QHash roles; + roles[Name] = "name"; + roles[Number] = "number"; + setRoleNames(roles); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; + } + + int count() const { return rowCount(); } + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + void addItem(const QString &name, const QString &number) { + beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair(name, number)); + endInsertRows(); + } + + void insertItem(int index, const QString &name, const QString &number) { + beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair(name, number)); + endInsertRows(); + } + + void insertItems(int index, const QList > &items) { + beginInsertRows(QModelIndex(), index, index+items.count()-1); + for (int i=0; i(items[i].first, items[i].second)); + endInsertRows(); + } + + void removeItem(int index) { + beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + endRemoveRows(); + } + + void removeItems(int index, int count) { + emit beginRemoveRows(QModelIndex(), index, index+count-1); + while (count--) + list.removeAt(index); + emit endRemoveRows(); + } + + void moveItem(int from, int to) { + beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); + list.move(from, to); + endMoveRows(); + } + + void moveItems(int from, int to, int count) { + beginMoveRows(QModelIndex(), from, from+count-1, QModelIndex(), to > from ? to+count : to); + move(from, to, count); + endMoveRows(); + } + + void modifyItem(int idx, const QString &name, const QString &number) { + list[idx] = QPair(name, number); + emit dataChanged(index(idx,0), index(idx,0)); + } + + void move(int from, int to, int n) + { + if (from > to) { + // Only move forwards - flip if backwards moving + int tfrom = from; + int tto = to; + from = tto; + to = tto+n; + n = tfrom-tto; + } + if (n == 1) { + list.move(from, to); + } else { + QList > replaced; + int i=0; + QList >::ConstIterator it=list.begin(); it += from+n; + for (; i >::ConstIterator f=replaced.begin(); + QList >::Iterator t=list.begin(); t += from; + for (; f != replaced.end(); ++f, ++t) + *t = *f; + } + } + +private: + QList > list; +}; + + +tst_QQuickPathView::tst_QQuickPathView() +{ +} + +void tst_QQuickPathView::initValues() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview1.qml"))); + QQuickPathView *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QVERIFY(obj->path() == 0); + QVERIFY(obj->delegate() == 0); + QCOMPARE(obj->model(), QVariant()); + QCOMPARE(obj->currentIndex(), 0); + QCOMPARE(obj->offset(), 0.); + QCOMPARE(obj->preferredHighlightBegin(), 0.); + QCOMPARE(obj->dragMargin(), 0.); + QCOMPARE(obj->count(), 0); + QCOMPARE(obj->pathItemCount(), -1); + + delete obj; +} + +void tst_QQuickPathView::items() +{ + QQuickView *canvas = createView(); + + TestModel model; + model.addItem("Fred", "12345"); + model.addItem("John", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + QCOMPARE(pathview->count(), model.count()); + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); + QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight + + for (int i = 0; i < model.count(); ++i) { + QQuickText *name = findItem(pathview, "textName", i); + QVERIFY(name != 0); + QCOMPARE(name->text(), model.name(i)); + QQuickText *number = findItem(pathview, "textNumber", i); + QVERIFY(number != 0); + QCOMPARE(number->text(), model.number(i)); + } + + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + + QVERIFY(pathview->highlightItem()); + QPointF start = path->pointAt(0.0); + QPointF offset; + offset.setX(pathview->highlightItem()->width()/2); + offset.setY(pathview->highlightItem()->height()/2); + QCOMPARE(pathview->highlightItem()->pos() + offset, start); + + delete canvas; +} + +void tst_QQuickPathView::pathview2() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview2.qml"))); + QQuickPathView *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QVERIFY(obj->path() != 0); + QVERIFY(obj->delegate() != 0); + QVERIFY(obj->model() != QVariant()); + QCOMPARE(obj->currentIndex(), 0); + QCOMPARE(obj->offset(), 0.); + QCOMPARE(obj->preferredHighlightBegin(), 0.); + QCOMPARE(obj->dragMargin(), 0.); + QCOMPARE(obj->count(), 8); + QCOMPARE(obj->pathItemCount(), 10); + + delete obj; +} + +void tst_QQuickPathView::pathview3() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathview3.qml"))); + QQuickPathView *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QVERIFY(obj->path() != 0); + QVERIFY(obj->delegate() != 0); + QVERIFY(obj->model() != QVariant()); + QCOMPARE(obj->currentIndex(), 0); + QCOMPARE(obj->offset(), 1.0); + QCOMPARE(obj->preferredHighlightBegin(), 0.5); + QCOMPARE(obj->dragMargin(), 24.); + QCOMPARE(obj->count(), 8); + QCOMPARE(obj->pathItemCount(), 4); + + delete obj; +} + +void tst_QQuickPathView::insertModel_data() +{ + QTest::addColumn("mode"); + QTest::addColumn("idx"); + QTest::addColumn("count"); + QTest::addColumn("offset"); + + // We have 8 items, with currentIndex == 4 + QTest::newRow("insert after current") + << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 5.; + QTest::newRow("insert before current") + << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.; + QTest::newRow("insert multiple after current") + << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 6.; + QTest::newRow("insert multiple before current") + << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.; + QTest::newRow("insert at end") + << int(QQuickPathView::StrictlyEnforceRange) << 8 << 1 << 5.; + QTest::newRow("insert at beginning") + << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.; + QTest::newRow("insert at current") + << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 4.; + + QTest::newRow("no range - insert after current") + << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 5.; + QTest::newRow("no range - insert before current") + << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.; + QTest::newRow("no range - insert multiple after current") + << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 6.; + QTest::newRow("no range - insert multiple before current") + << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.; + QTest::newRow("no range - insert at end") + << int(QQuickPathView::NoHighlightRange) << 8 << 1 << 5.; + QTest::newRow("no range - insert at beginning") + << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.; + QTest::newRow("no range - insert at current") + << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.; +} + +void tst_QQuickPathView::insertModel() +{ + QFETCH(int, mode); + QFETCH(int, idx); + QFETCH(int, count); + QFETCH(qreal, offset); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + model.addItem("Jinny", "679"); + model.addItem("Milly", "73378"); + model.addItem("Jimmy", "3535"); + model.addItem("Barb", "9039"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); + + pathview->setCurrentIndex(4); + if (mode == QQuickPathView::StrictlyEnforceRange) + QTRY_COMPARE(pathview->offset(), 4.0); + else + pathview->setOffset(4); + + QList > items; + for (int i = 0; i < count; ++i) + items.append(qMakePair(QString("New"), QString::number(i))); + + model.insertItems(idx, items); + QTRY_COMPARE(pathview->offset(), offset); + + delete canvas; +} + +void tst_QQuickPathView::removeModel_data() +{ + QTest::addColumn("mode"); + QTest::addColumn("idx"); + QTest::addColumn("count"); + QTest::addColumn("offset"); + + // We have 8 items, with currentIndex == 4 + QTest::newRow("remove after current") + << int(QQuickPathView::StrictlyEnforceRange) << 6 << 1 << 3.; + QTest::newRow("remove before current") + << int(QQuickPathView::StrictlyEnforceRange) << 2 << 1 << 4.; + QTest::newRow("remove multiple after current") + << int(QQuickPathView::StrictlyEnforceRange) << 5 << 2 << 2.; + QTest::newRow("remove multiple before current") + << int(QQuickPathView::StrictlyEnforceRange) << 1 << 2 << 4.; + QTest::newRow("remove last") + << int(QQuickPathView::StrictlyEnforceRange) << 7 << 1 << 3.; + QTest::newRow("remove first") + << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 4.; + QTest::newRow("remove current") + << int(QQuickPathView::StrictlyEnforceRange) << 4 << 1 << 3.; + + QTest::newRow("no range - remove after current") + << int(QQuickPathView::NoHighlightRange) << 6 << 1 << 3.; + QTest::newRow("no range - remove before current") + << int(QQuickPathView::NoHighlightRange) << 2 << 1 << 4.; + QTest::newRow("no range - remove multiple after current") + << int(QQuickPathView::NoHighlightRange) << 5 << 2 << 2.; + QTest::newRow("no range - remove multiple before current") + << int(QQuickPathView::NoHighlightRange) << 1 << 2 << 4.; + QTest::newRow("no range - remove last") + << int(QQuickPathView::NoHighlightRange) << 7 << 1 << 3.; + QTest::newRow("no range - remove first") + << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 4.; + QTest::newRow("no range - remove current offset") + << int(QQuickPathView::NoHighlightRange) << 4 << 1 << 4.; +} + +void tst_QQuickPathView::removeModel() +{ + QFETCH(int, mode); + QFETCH(int, idx); + QFETCH(int, count); + QFETCH(qreal, offset); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + model.addItem("Jinny", "679"); + model.addItem("Milly", "73378"); + model.addItem("Jimmy", "3535"); + model.addItem("Barb", "9039"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); + + pathview->setCurrentIndex(4); + if (mode == QQuickPathView::StrictlyEnforceRange) + QTRY_COMPARE(pathview->offset(), 4.0); + else + pathview->setOffset(4); + + model.removeItems(idx, count); + QTRY_COMPARE(pathview->offset(), offset); + + delete canvas; +} + + +void tst_QQuickPathView::moveModel_data() +{ + QTest::addColumn("mode"); + QTest::addColumn("from"); + QTest::addColumn("to"); + QTest::addColumn("count"); + QTest::addColumn("offset"); + + // We have 8 items, with currentIndex == 4 + QTest::newRow("move after current") + << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 1 << 4.; + QTest::newRow("move before current") + << int(QQuickPathView::StrictlyEnforceRange) << 2 << 3 << 1 << 4.; + QTest::newRow("move before current to after") + << int(QQuickPathView::StrictlyEnforceRange) << 2 << 6 << 1 << 5.; + QTest::newRow("move multiple after current") + << int(QQuickPathView::StrictlyEnforceRange) << 5 << 6 << 2 << 4.; + QTest::newRow("move multiple before current") + << int(QQuickPathView::StrictlyEnforceRange) << 0 << 1 << 2 << 4.; + QTest::newRow("move before current to end") + << int(QQuickPathView::StrictlyEnforceRange) << 2 << 7 << 1 << 5.; + QTest::newRow("move last to beginning") + << int(QQuickPathView::StrictlyEnforceRange) << 7 << 0 << 1 << 3.; + QTest::newRow("move current") + << int(QQuickPathView::StrictlyEnforceRange) << 4 << 6 << 1 << 2.; + + QTest::newRow("no range - move after current") + << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 1 << 4.; + QTest::newRow("no range - move before current") + << int(QQuickPathView::NoHighlightRange) << 2 << 3 << 1 << 4.; + QTest::newRow("no range - move before current to after") + << int(QQuickPathView::NoHighlightRange) << 2 << 6 << 1 << 5.; + QTest::newRow("no range - move multiple after current") + << int(QQuickPathView::NoHighlightRange) << 5 << 6 << 2 << 4.; + QTest::newRow("no range - move multiple before current") + << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 2 << 4.; + QTest::newRow("no range - move before current to end") + << int(QQuickPathView::NoHighlightRange) << 2 << 7 << 1 << 5.; + QTest::newRow("no range - move last to beginning") + << int(QQuickPathView::NoHighlightRange) << 7 << 0 << 1 << 3.; + QTest::newRow("no range - move current") + << int(QQuickPathView::NoHighlightRange) << 4 << 6 << 1 << 4.; + QTest::newRow("no range - move multiple incl. current") + << int(QQuickPathView::NoHighlightRange) << 0 << 1 << 5 << 4.; +} + +void tst_QQuickPathView::moveModel() +{ + QFETCH(int, mode); + QFETCH(int, from); + QFETCH(int, to); + QFETCH(int, count); + QFETCH(qreal, offset); + + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + model.addItem("Jinny", "679"); + model.addItem("Milly", "73378"); + model.addItem("Jimmy", "3535"); + model.addItem("Barb", "9039"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + pathview->setHighlightRangeMode((QQuickPathView::HighlightRangeMode)mode); + + pathview->setCurrentIndex(4); + if (mode == QQuickPathView::StrictlyEnforceRange) + QTRY_COMPARE(pathview->offset(), 4.0); + else + pathview->setOffset(4); + + model.moveItems(from, to, count); + QTRY_COMPARE(pathview->offset(), offset); + + delete canvas; +} + +void tst_QQuickPathView::path() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("pathtest.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + + QVERIFY(obj != 0); + QCOMPARE(obj->startX(), 120.); + QCOMPARE(obj->startY(), 100.); + QVERIFY(obj->path() != QPainterPath()); + + QDeclarativeListReference list(obj, "pathElements"); + QCOMPARE(list.count(), 5); + + QDeclarativePathAttribute* attr = qobject_cast(list.at(0)); + QVERIFY(attr != 0); + QCOMPARE(attr->name(), QString("scale")); + QCOMPARE(attr->value(), 1.0); + + QDeclarativePathQuad* quad = qobject_cast(list.at(1)); + QVERIFY(quad != 0); + QCOMPARE(quad->x(), 120.); + QCOMPARE(quad->y(), 25.); + QCOMPARE(quad->controlX(), 260.); + QCOMPARE(quad->controlY(), 75.); + + QDeclarativePathPercent* perc = qobject_cast(list.at(2)); + QVERIFY(perc != 0); + QCOMPARE(perc->value(), 0.3); + + QDeclarativePathLine* line = qobject_cast(list.at(3)); + QVERIFY(line != 0); + QCOMPARE(line->x(), 120.); + QCOMPARE(line->y(), 100.); + + QDeclarativePathCubic* cubic = qobject_cast(list.at(4)); + QVERIFY(cubic != 0); + QCOMPARE(cubic->x(), 180.); + QCOMPARE(cubic->y(), 0.); + QCOMPARE(cubic->control1X(), -10.); + QCOMPARE(cubic->control1Y(), 90.); + QCOMPARE(cubic->control2X(), 210.); + QCOMPARE(cubic->control2Y(), 90.); + + delete obj; +} + +void tst_QQuickPathView::dataModel() +{ + QQuickView *canvas = createView(); + canvas->show(); + + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + TestModel model; + model.addItem("red", "1"); + model.addItem("green", "2"); + model.addItem("blue", "3"); + model.addItem("purple", "4"); + model.addItem("gray", "5"); + model.addItem("brown", "6"); + model.addItem("yellow", "7"); + model.addItem("thistle", "8"); + model.addItem("cyan", "9"); + model.addItem("peachpuff", "10"); + model.addItem("powderblue", "11"); + model.addItem("gold", "12"); + model.addItem("sandybrown", "13"); + + ctxt->setContextProperty("testData", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("datamodel.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QVERIFY(testObject->error() == false); + + QQuickItem *item = findItem(pathview, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->x(), 110.0); + QCOMPARE(item->y(), 10.0); + + model.insertItem(4, "orange", "10"); + QTest::qWait(100); + + QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); + QTRY_COMPARE(findItems(pathview, "wrapper").count(), 14); + + QVERIFY(pathview->currentIndex() == 0); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); + + QQuickText *text = findItem(pathview, "myText", 4); + QVERIFY(text); + QCOMPARE(text->text(), model.name(4)); + + model.removeItem(2); + QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); + text = findItem(pathview, "myText", 2); + QVERIFY(text); + QCOMPARE(text->text(), model.name(2)); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 0)); + + testObject->setPathItemCount(5); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QVERIFY(testObject->error() == false); + + QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); + + QQuickRectangle *testItem = findItem(pathview, "wrapper", 4); + QVERIFY(testItem != 0); + testItem = findItem(pathview, "wrapper", 5); + QVERIFY(testItem == 0); + + pathview->setCurrentIndex(1); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); + QTest::qWait(100); + + model.insertItem(2, "pink", "2"); + QTest::qWait(100); + + QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); + QVERIFY(pathview->currentIndex() == 1); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); + + text = findItem(pathview, "myText", 2); + QVERIFY(text); + QCOMPARE(text->text(), model.name(2)); + + model.removeItem(3); + QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); + text = findItem(pathview, "myText", 3); + QVERIFY(text); + QCOMPARE(text->text(), model.name(3)); + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); + + model.moveItem(3, 5); + QTRY_COMPARE(findItems(pathview, "wrapper").count(), 5); + QList items = findItems(pathview, "wrapper"); + foreach (QQuickItem *item, items) { + QVERIFY(item->property("onPath").toBool()); + } + QCOMPARE(pathview->currentItem(), findItem(pathview, "wrapper", 1)); + + // QTBUG-14199 + pathview->setOffset(7); + pathview->setOffset(0); + QCOMPARE(findItems(pathview, "wrapper").count(), 5); + + pathview->setCurrentIndex(model.count()-1); + model.removeItem(model.count()-1); + QCOMPARE(pathview->currentIndex(), model.count()-1); + + delete canvas; + delete testObject; +} + +void tst_QQuickPathView::pathMoved() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + QPointF start = path->pointAt(0.0); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(firstItem->width()/2); + offset.setY(firstItem->height()/2); + QTRY_COMPARE(firstItem->pos() + offset, start); + pathview->setOffset(1.0); + + for (int i=0; i(pathview, "wrapper", i); + QPointF itemPos(path->pointAt(0.25 + i*0.25)); + QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y()))); + } + + pathview->setOffset(0.0); + QCOMPARE(firstItem->pos() + offset, start); + + // Change delegate size + pathview->setOffset(0.1); + pathview->setOffset(0.0); + canvas->rootObject()->setProperty("delegateWidth", 30); + QCOMPARE(firstItem->width(), 30.0); + offset.setX(firstItem->width()/2); + QTRY_COMPARE(firstItem->pos() + offset, start); + + // Change delegate scale + pathview->setOffset(0.1); + pathview->setOffset(0.0); + canvas->rootObject()->setProperty("delegateScale", 1.2); + QTRY_COMPARE(firstItem->pos() + offset, start); + + delete canvas; +} + +void tst_QQuickPathView::setCurrentIndex() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + model.addItem("Ben", "12345"); + model.addItem("Bohn", "2345"); + model.addItem("Bob", "54321"); + model.addItem("Bill", "4321"); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview0.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + QPointF start = path->pointAt(0.0); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(firstItem->width()/2); + offset.setY(firstItem->height()/2); + QCOMPARE(firstItem->pos() + offset, start); + QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 0); + QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 0); + + pathview->setCurrentIndex(2); + + firstItem = findItem(pathview, "wrapper", 2); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(canvas->rootObject()->property("currentA").toInt(), 2); + QCOMPARE(canvas->rootObject()->property("currentB").toInt(), 2); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 1); + firstItem = findItem(pathview, "wrapper", 1); + QVERIFY(firstItem); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 3); + firstItem = findItem(pathview, "wrapper", 3); + QVERIFY(firstItem); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->incrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + // move an item, set move duration to 0, and change currentIndex to moved item. QTBUG-22786 + model.moveItem(0, 3); + pathview->setHighlightMoveDuration(0); + pathview->setCurrentIndex(3); + QCOMPARE(pathview->currentIndex(), 3); + firstItem = findItem(pathview, "wrapper", 3); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QTRY_COMPARE(firstItem->pos() + offset, start); + model.moveItem(3, 0); + pathview->setCurrentIndex(0); + pathview->setHighlightMoveDuration(300); + + // Check the current item is still created when outside the bounds of pathItemCount. + pathview->setPathItemCount(2); + pathview->setHighlightRangeMode(QQuickPathView::NoHighlightRange); + QVERIFY(findItem(pathview, "wrapper", 0)); + QVERIFY(findItem(pathview, "wrapper", 1)); + QVERIFY(!findItem(pathview, "wrapper", 2)); + QVERIFY(!findItem(pathview, "wrapper", 3)); + + pathview->setCurrentIndex(2); + firstItem = findItem(pathview, "wrapper", 2); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(false)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 1); + firstItem = findItem(pathview, "wrapper", 1); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + pathview->decrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 3); + firstItem = findItem(pathview, "wrapper", 3); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(false)); + + pathview->incrementCurrentIndex(); + QTRY_COMPARE(pathview->currentIndex(), 0); + firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QCOMPARE(pathview->currentItem(), firstItem); + QCOMPARE(firstItem->property("onPath"), QVariant(true)); + + delete canvas; +} + +void tst_QQuickPathView::resetModel() +{ + QQuickView *canvas = createView(); + + QStringList strings; + strings << "one" << "two" << "three"; + QStringListModel model(strings); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("displaypath.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + QCOMPARE(pathview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(pathview, "displayText", i); + QVERIFY(display != 0); + QCOMPARE(display->text(), strings.at(i)); + } + + strings.clear(); + strings << "four" << "five" << "six" << "seven"; + model.setStringList(strings); + + QCOMPARE(pathview->count(), model.rowCount()); + + for (int i = 0; i < model.rowCount(); ++i) { + QQuickText *display = findItem(pathview, "displayText", i); + QVERIFY(display != 0); + QCOMPARE(display->text(), strings.at(i)); + } + + delete canvas; +} + +void tst_QQuickPathView::propertyChanges() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QSignalSpy snapPositionSpy(pathView, SIGNAL(preferredHighlightBeginChanged())); + QSignalSpy dragMarginSpy(pathView, SIGNAL(dragMarginChanged())); + + QCOMPARE(pathView->preferredHighlightBegin(), 0.1); + QCOMPARE(pathView->dragMargin(), 5.0); + + pathView->setPreferredHighlightBegin(0.4); + pathView->setPreferredHighlightEnd(0.4); + pathView->setDragMargin(20.0); + + QCOMPARE(pathView->preferredHighlightBegin(), 0.4); + QCOMPARE(pathView->preferredHighlightEnd(), 0.4); + QCOMPARE(pathView->dragMargin(), 20.0); + + QCOMPARE(snapPositionSpy.count(), 1); + QCOMPARE(dragMarginSpy.count(), 1); + + pathView->setPreferredHighlightBegin(0.4); + pathView->setPreferredHighlightEnd(0.4); + pathView->setDragMargin(20.0); + + QCOMPARE(snapPositionSpy.count(), 1); + QCOMPARE(dragMarginSpy.count(), 1); + delete canvas; +} + +void tst_QQuickPathView::pathChanges() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QDeclarativePath *path = canvas->rootObject()->findChild("path"); + QVERIFY(path); + + QSignalSpy startXSpy(path, SIGNAL(startXChanged())); + QSignalSpy startYSpy(path, SIGNAL(startYChanged())); + + QCOMPARE(path->startX(), 220.0); + QCOMPARE(path->startY(), 200.0); + + path->setStartX(240.0); + path->setStartY(220.0); + + QCOMPARE(path->startX(), 240.0); + QCOMPARE(path->startY(), 220.0); + + QCOMPARE(startXSpy.count(),1); + QCOMPARE(startYSpy.count(),1); + + path->setStartX(240); + path->setStartY(220); + + QCOMPARE(startXSpy.count(),1); + QCOMPARE(startYSpy.count(),1); + + QDeclarativePath *alternatePath = canvas->rootObject()->findChild("alternatePath"); + QVERIFY(alternatePath); + + QSignalSpy pathSpy(pathView, SIGNAL(pathChanged())); + + QCOMPARE(pathView->path(), path); + + pathView->setPath(alternatePath); + QCOMPARE(pathView->path(), alternatePath); + QCOMPARE(pathSpy.count(),1); + + pathView->setPath(alternatePath); + QCOMPARE(pathSpy.count(),1); + + QDeclarativePathAttribute *pathAttribute = canvas->rootObject()->findChild("pathAttribute"); + QVERIFY(pathAttribute); + + QSignalSpy nameSpy(pathAttribute, SIGNAL(nameChanged())); + QCOMPARE(pathAttribute->name(), QString("opacity")); + + pathAttribute->setName("scale"); + QCOMPARE(pathAttribute->name(), QString("scale")); + QCOMPARE(nameSpy.count(),1); + + pathAttribute->setName("scale"); + QCOMPARE(nameSpy.count(),1); + delete canvas; +} + +void tst_QQuickPathView::componentChanges() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QDeclarativeComponent delegateComponent(canvas->engine()); + delegateComponent.setData("import QtQuick 2.0; Text { text: 'Name: ' + name }", QUrl::fromLocalFile("")); + + QSignalSpy delegateSpy(pathView, SIGNAL(delegateChanged())); + + pathView->setDelegate(&delegateComponent); + QCOMPARE(pathView->delegate(), &delegateComponent); + QCOMPARE(delegateSpy.count(),1); + + pathView->setDelegate(&delegateComponent); + QCOMPARE(delegateSpy.count(),1); + delete canvas; +} + +void tst_QQuickPathView::modelChanges() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("propertychanges.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QDeclarativeListModel *alternateModel = canvas->rootObject()->findChild("alternateModel"); + QVERIFY(alternateModel); + QVariant modelVariant = QVariant::fromValue(alternateModel); + QSignalSpy modelSpy(pathView, SIGNAL(modelChanged())); + + pathView->setModel(modelVariant); + QCOMPARE(pathView->model(), modelVariant); + QCOMPARE(modelSpy.count(),1); + + pathView->setModel(modelVariant); + QCOMPARE(modelSpy.count(),1); + + pathView->setModel(QVariant()); + QCOMPARE(modelSpy.count(),2); + + delete canvas; +} + +void tst_QQuickPathView::pathUpdateOnStartChanged() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdateOnStartChanged.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QDeclarativePath *path = canvas->rootObject()->findChild("path"); + QVERIFY(path); + QCOMPARE(path->startX(), 400.0); + QCOMPARE(path->startY(), 300.0); + + QQuickItem *item = findItem(pathView, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->x(), path->startX() - item->width() / 2.0); + QCOMPARE(item->y(), path->startY() - item->height() / 2.0); + + delete canvas; +} + +void tst_QQuickPathView::package() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathview_package.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("photoPathView"); + QVERIFY(pathView); + + QQuickItem *item = findItem(pathView, "pathItem"); + QVERIFY(item); + QVERIFY(item->scale() != 1.0); + + delete canvas; +} + +//QTBUG-13017 +void tst_QQuickPathView::emptyModel() +{ + QQuickView *canvas = createView(); + + QStringListModel model; + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("emptyModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("emptymodel.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + + QCOMPARE(pathview->offset(), qreal(0.0)); + + delete canvas; +} + +void tst_QQuickPathView::closed() +{ + QDeclarativeEngine engine; + + { + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("openPath.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj); + QCOMPARE(obj->isClosed(), false); + delete obj; + } + + { + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("closedPath.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj); + QCOMPARE(obj->isClosed(), true); + delete obj; + } +} + +// QTBUG-14239 +void tst_QQuickPathView::pathUpdate() +{ + QQuickView *canvas = createView(); + QVERIFY(canvas); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathUpdate.qml"))); + + QQuickPathView *pathView = canvas->rootObject()->findChild("pathView"); + QVERIFY(pathView); + + QQuickItem *item = findItem(pathView, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->x(), 150.0); + + delete canvas; +} + +void tst_QQuickPathView::visualDataModel() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("vdm.qml"))); + + QQuickPathView *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->count(), 3); + + delete obj; +} + +void tst_QQuickPathView::undefinedPath() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("undefinedpath.qml"))); + + QQuickPathView *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QCOMPARE(obj->count(), 3); + + delete obj; +} + +void tst_QQuickPathView::mouseDrag() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(canvas, qGuiApp->focusWindow()); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + + int current = pathview->currentIndex(); + + QTest::mousePress(canvas, Qt::LeftButton, 0, QPoint(10,100)); + QTest::qWait(100); + + { + QMouseEvent mv(QEvent::MouseMove, QPoint(30,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + } + { + QMouseEvent mv(QEvent::MouseMove, QPoint(90,100), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas, &mv); + } + + QVERIFY(pathview->currentIndex() != current); + + QTest::mouseRelease(canvas, Qt::LeftButton, 0, QPoint(40,100)); + + delete canvas; +} + +void tst_QQuickPathView::treeModel() +{ + QQuickView *canvas = createView(); + canvas->show(); + + QStandardItemModel model; + initStandardTreeModel(&model); + canvas->engine()->rootContext()->setContextProperty("myModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("treemodel.qml"))); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + QCOMPARE(pathview->count(), 3); + + QQuickText *item = findItem(pathview, "wrapper", 0); + QVERIFY(item); + QCOMPARE(item->text(), QLatin1String("Row 1 Item")); + + QVERIFY(QMetaObject::invokeMethod(pathview, "setRoot", Q_ARG(QVariant, 1))); + QCOMPARE(pathview->count(), 1); + + QTRY_VERIFY(item = findItem(pathview, "wrapper", 0)); + QTRY_COMPARE(item->text(), QLatin1String("Row 2 Child Item")); + + delete canvas; +} + +void tst_QQuickPathView::changePreferredHighlight() +{ + QQuickView *canvas = createView(); + canvas->setGeometry(0,0,400,200); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("dragpath.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(canvas, qGuiApp->focusWindow()); + + QQuickPathView *pathview = qobject_cast(canvas->rootObject()); + QVERIFY(pathview != 0); + + int current = pathview->currentIndex(); + QCOMPARE(current, 0); + + QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + QPointF start = path->pointAt(0.5); + start.setX(qRound(start.x())); + start.setY(qRound(start.y())); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(firstItem->width()/2); + offset.setY(firstItem->height()/2); + QTRY_COMPARE(firstItem->pos() + offset, start); + + pathview->setPreferredHighlightBegin(0.8); + pathview->setPreferredHighlightEnd(0.8); + start = path->pointAt(0.8); + start.setX(qRound(start.x())); + start.setY(qRound(start.y())); + QTRY_COMPARE(firstItem->pos() + offset, start); + QCOMPARE(pathview->currentIndex(), 0); + + delete canvas; +} + +void tst_QQuickPathView::creationContext() +{ + QQuickView canvas; + canvas.setGeometry(0,0,240,320); + canvas.setSource(QUrl::fromLocalFile(TESTDATA("creationContext.qml"))); + + QQuickItem *rootItem = qobject_cast(canvas.rootObject()); + QVERIFY(rootItem); + QVERIFY(rootItem->property("count").toInt() > 0); + + QQuickItem *item; + QVERIFY(item = findItem(rootItem, "listItem", 0)); + QCOMPARE(item->property("text").toString(), QString("Hello!")); +} + +// QTBUG-21320 +void tst_QQuickPathView::currentOffsetOnInsertion() +{ + QQuickView *canvas = createView(); + canvas->show(); + + TestModel model; + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testModel", &model); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pathline.qml"))); + qApp->processEvents(); + + QQuickPathView *pathview = findItem(canvas->rootObject(), "view"); + QVERIFY(pathview != 0); + + pathview->setPreferredHighlightBegin(0.5); + pathview->setPreferredHighlightEnd(0.5); + + QCOMPARE(pathview->count(), model.count()); + + model.addItem("item0", "0"); + + QCOMPARE(pathview->count(), model.count()); + + QQuickRectangle *item = 0; + QTRY_VERIFY(item = findItem(pathview, "wrapper", 0)); + + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + + QPointF start = path->pointAt(0.5); + start = QPointF(qRound(start.x()), qRound(start.y())); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(item->width()/2); + offset.setY(item->height()/2); + QCOMPARE(item->pos() + offset, start); + + QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged())); + + // insert an item at the beginning + model.insertItem(0, "item1", "1"); + qApp->processEvents(); + + QCOMPARE(currentIndexSpy.count(), 1); + + // currentIndex is now 1 + QVERIFY(item = findItem(pathview, "wrapper", 1)); + + // verify that current item (item 1) is still at offset 0.5 + QCOMPARE(item->pos() + offset, start); + + // insert another item at the beginning + model.insertItem(0, "item2", "2"); + qApp->processEvents(); + + QCOMPARE(currentIndexSpy.count(), 2); + + // currentIndex is now 2 + QVERIFY(item = findItem(pathview, "wrapper", 2)); + + // verify that current item (item 2) is still at offset 0.5 + QCOMPARE(item->pos() + offset, start); + + // verify that remove before current maintains current item + model.removeItem(0); + qApp->processEvents(); + + QCOMPARE(currentIndexSpy.count(), 3); + + // currentIndex is now 1 + QVERIFY(item = findItem(pathview, "wrapper", 1)); + + // verify that current item (item 1) is still at offset 0.5 + QCOMPARE(item->pos() + offset, start); + + delete canvas; +} + +void tst_QQuickPathView::asynchronous() +{ + QQuickView *canvas = createView(); + canvas->show(); + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + canvas->setSource(TESTDATA("asyncloader.qml")); + + QQuickItem *rootObject = qobject_cast(canvas->rootObject()); + QVERIFY(rootObject); + + QQuickPathView *pathview = 0; + while (!pathview) { + bool b = false; + controller.incubateWhile(&b); + pathview = rootObject->findChild("view"); + } + + // items will be created one at a time + for (int i = 0; i < 5; ++i) { + QVERIFY(findItem(pathview, "wrapper", i) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(pathview, "wrapper", i); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + // verify positioning + QQuickRectangle *firstItem = findItem(pathview, "wrapper", 0); + QVERIFY(firstItem); + QDeclarativePath *path = qobject_cast(pathview->path()); + QVERIFY(path); + QPointF start = path->pointAt(0.0); + QPointF offset;//Center of item is at point, but pos is from corner + offset.setX(firstItem->width()/2); + offset.setY(firstItem->height()/2); + QTRY_COMPARE(firstItem->pos() + offset, start); + pathview->setOffset(1.0); + + for (int i=0; i<5; i++) { + QQuickItem *curItem = findItem(pathview, "wrapper", i); + QPointF itemPos(path->pointAt(0.2 + i*0.2)); + QCOMPARE(curItem->pos() + offset, QPointF(qRound(itemPos.x()), qRound(itemPos.y()))); + } + + delete canvas; +} + +QQuickView *tst_QQuickPathView::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + return canvas; +} + +/* + Find an item with the specified objectName. If index is supplied then the + item must also evaluate the {index} expression equal to index + */ +template +T *tst_QQuickPathView::findItem(QQuickItem *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), item, "index"); + if (e.evaluate().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +template +QList tst_QQuickPathView::findItems(QQuickItem *parent, const QString &objectName) +{ + QList items; + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->QQuickItem::children().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) + items.append(static_cast(item)); + items += findItems(item, objectName); + } + + return items; +} + +void tst_QQuickPathView::missingPercent() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("missingPercent.qml"))); + QDeclarativePath *obj = qobject_cast(c.create()); + QVERIFY(obj); + QCOMPARE(obj->attributeAt("_qfx_percent", 1.0), qreal(1.0)); + delete obj; +} + + +QTEST_MAIN(tst_QQuickPathView) + +#include "tst_qquickpathview.moc" diff --git a/tests/auto/qtquick2/qquickpincharea/data/pinchproperties.qml b/tests/auto/qtquick2/qquickpincharea/data/pinchproperties.qml new file mode 100644 index 0000000000..44d116184e --- /dev/null +++ b/tests/auto/qtquick2/qquickpincharea/data/pinchproperties.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 +Rectangle { + id: whiteRect + property variant center + property real scale + property int pointCount: 0 + width: 240; height: 320 + color: "white" + Rectangle { + id: blackRect + objectName: "blackrect" + color: "black" + y: 50 + x: 50 + width: 100 + height: 100 + opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200 + Text { text: blackRect.opacity} + PinchArea { + id: pincharea + objectName: "pincharea" + anchors.fill: parent + pinch.target: blackRect + pinch.dragAxis: Drag.XandYAxis + pinch.minimumX: 0 + pinch.maximumX: whiteRect.width-blackRect.width + pinch.minimumY: 0 + pinch.maximumY: whiteRect.height-blackRect.height + pinch.minimumScale: 1.0 + pinch.maximumScale: 2.0 + pinch.minimumRotation: 0.0 + pinch.maximumRotation: 90.0 + onPinchStarted: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + whiteRect.pointCount = pinch.pointCount; + } + onPinchUpdated: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + whiteRect.pointCount = pinch.pointCount; + } + onPinchFinished: { + whiteRect.center = pinch.center + whiteRect.scale = pinch.scale + whiteRect.pointCount = pinch.pointCount; + } + } + } + } diff --git a/tests/auto/qtquick2/qquickpincharea/qquickpincharea.pro b/tests/auto/qtquick2/qquickpincharea/qquickpincharea.pro new file mode 100644 index 0000000000..6e2ff59512 --- /dev/null +++ b/tests/auto/qtquick2/qquickpincharea/qquickpincharea.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickpincharea +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickpincharea.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickpincharea/tst_qquickpincharea.cpp b/tests/auto/qtquick2/qquickpincharea/tst_qquickpincharea.cpp new file mode 100644 index 0000000000..c4912c46f1 --- /dev/null +++ b/tests/auto/qtquick2/qquickpincharea/tst_qquickpincharea.cpp @@ -0,0 +1,395 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_QQuickPinchArea: public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanupTestCase(); + void pinchProperties(); + void scale(); + void pan(); + void retouch(); + +private: + QQuickView *createView(); +}; +void tst_QQuickPinchArea::initTestCase() +{ +} + +void tst_QQuickPinchArea::cleanupTestCase() +{ + +} +void tst_QQuickPinchArea::pinchProperties() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QVERIFY(canvas->rootObject() != 0); + + QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); + QQuickPinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + QVERIFY(blackRect == pinch->target()); + QQuickItem *rootItem = qobject_cast(canvas->rootObject()); + QVERIFY(rootItem != 0); + QSignalSpy targetSpy(pinch, SIGNAL(targetChanged())); + pinch->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + pinch->setTarget(rootItem); + QCOMPARE(targetSpy.count(),1); + + // axis + QCOMPARE(pinch->axis(), QQuickPinch::XandYAxis); + QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged())); + pinch->setAxis(QQuickPinch::XAxis); + QCOMPARE(pinch->axis(), QQuickPinch::XAxis); + QCOMPARE(axisSpy.count(),1); + pinch->setAxis(QQuickPinch::XAxis); + QCOMPARE(axisSpy.count(),1); + + // minimum and maximum drag properties + QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged())); + QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged())); + QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged())); + QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged())); + + QCOMPARE(pinch->xmin(), 0.0); + QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width()); + QCOMPARE(pinch->ymin(), 0.0); + QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height()); + + pinch->setXmin(10); + pinch->setXmax(10); + pinch->setYmin(10); + pinch->setYmax(10); + + QCOMPARE(pinch->xmin(), 10.0); + QCOMPARE(pinch->xmax(), 10.0); + QCOMPARE(pinch->ymin(), 10.0); + QCOMPARE(pinch->ymax(), 10.0); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + pinch->setXmin(10); + pinch->setXmax(10); + pinch->setYmin(10); + pinch->setYmax(10); + + QCOMPARE(xminSpy.count(),1); + QCOMPARE(xmaxSpy.count(),1); + QCOMPARE(yminSpy.count(),1); + QCOMPARE(ymaxSpy.count(),1); + + // minimum and maximum scale properties + QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged())); + QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged())); + + QCOMPARE(pinch->minimumScale(), 1.0); + QCOMPARE(pinch->maximumScale(), 2.0); + + pinch->setMinimumScale(0.5); + pinch->setMaximumScale(1.5); + + QCOMPARE(pinch->minimumScale(), 0.5); + QCOMPARE(pinch->maximumScale(), 1.5); + + QCOMPARE(scaleMinSpy.count(),1); + QCOMPARE(scaleMaxSpy.count(),1); + + pinch->setMinimumScale(0.5); + pinch->setMaximumScale(1.5); + + QCOMPARE(scaleMinSpy.count(),1); + QCOMPARE(scaleMaxSpy.count(),1); + + // minimum and maximum rotation properties + QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged())); + QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged())); + + QCOMPARE(pinch->minimumRotation(), 0.0); + QCOMPARE(pinch->maximumRotation(), 90.0); + + pinch->setMinimumRotation(-90.0); + pinch->setMaximumRotation(45.0); + + QCOMPARE(pinch->minimumRotation(), -90.0); + QCOMPARE(pinch->maximumRotation(), 45.0); + + QCOMPARE(rotMinSpy.count(),1); + QCOMPARE(rotMaxSpy.count(),1); + + pinch->setMinimumRotation(-90.0); + pinch->setMaximumRotation(45.0); + + QCOMPARE(rotMinSpy.count(),1); + QCOMPARE(rotMaxSpy.count(),1); + + delete canvas; +} + +QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QQuickView *v, QQuickItem *i) +{ + QTouchEvent::TouchPoint touchPoint(id); + touchPoint.setPos(i->mapFromScene(p)); + touchPoint.setScreenPos(v->mapToGlobal(p)); + touchPoint.setScenePos(p); + return touchPoint; +} + +void tst_QQuickPinchArea::scale() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + qApp->processEvents(); + + QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); + QQuickPinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + + QPoint p1(80, 80); + QPoint p2(100, 100); + + QTest::touchEvent(canvas).press(0, p1, canvas); + QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas); + + QCOMPARE(root->property("scale").toReal(), 1.0); + + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1,canvas).move(1, p2,canvas); + + QCOMPARE(root->property("scale").toReal(), 1.5); + QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 + QCOMPARE(blackRect->scale(), 1.5); + + // scale beyond bound + p1 -= QPoint(50,50); + p2 += QPoint(50,50); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(blackRect->scale(), 2.0); + + QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); + + delete canvas; +} + +void tst_QQuickPinchArea::pan() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + qApp->processEvents(); + + QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); + QQuickPinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root != 0); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + + QPoint p1(80, 80); + QPoint p2(100, 100); + + QTest::touchEvent(canvas).press(0, p1, canvas); + QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); + p1 += QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(root->property("scale").toReal(), 1.0); + + p1 += QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(root->property("center").toPointF(), QPointF(60, 60)); // blackrect is at 50,50 + + QCOMPARE(blackRect->x(), 60.0); + QCOMPARE(blackRect->y(), 60.0); + + // pan x beyond bound + p1 += QPoint(100,100); + p2 += QPoint(100,100); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(blackRect->x(), 140.0); + QCOMPARE(blackRect->y(), 160.0); + + QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); + + delete canvas; +} + +// test pinch, release one point, touch again to continue pinch +void tst_QQuickPinchArea::retouch() +{ + QQuickView *canvas = createView(); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("pinchproperties.qml"))); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + QVERIFY(canvas->rootObject() != 0); + qApp->processEvents(); + + QQuickPinchArea *pinchArea = canvas->rootObject()->findChild("pincharea"); + QQuickPinch *pinch = pinchArea->pinch(); + QVERIFY(pinchArea != 0); + QVERIFY(pinch != 0); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root != 0); + + QSignalSpy startedSpy(pinchArea, SIGNAL(pinchStarted(QQuickPinchEvent *))); + QSignalSpy finishedSpy(pinchArea, SIGNAL(pinchFinished(QQuickPinchEvent *))); + + // target + QQuickItem *blackRect = canvas->rootObject()->findChild("blackrect"); + QVERIFY(blackRect != 0); + + QPoint p1(80, 80); + QPoint p2(100, 100); + + QTest::touchEvent(canvas).press(0, p1, canvas); + QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(root->property("scale").toReal(), 1.0); + + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + QCOMPARE(startedSpy.count(), 1); + + QCOMPARE(root->property("scale").toReal(), 1.5); + QCOMPARE(root->property("center").toPointF(), QPointF(40, 40)); // blackrect is at 50,50 + QCOMPARE(blackRect->scale(), 1.5); + + QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2); + + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + QTest::touchEvent(canvas).stationary(0).release(1, p2, canvas); + + QCOMPARE(startedSpy.count(), 1); + QCOMPARE(finishedSpy.count(), 0); + + QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 1); + + QTest::touchEvent(canvas).stationary(0).press(1, p2, canvas); + p1 -= QPoint(10,10); + p2 += QPoint(10,10); + QTest::touchEvent(canvas).move(0, p1, canvas).move(1, p2, canvas); + + // Lifting and retouching results in onPinchStarted being called again + QCOMPARE(startedSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 0); + + QCOMPARE(canvas->rootObject()->property("pointCount").toInt(), 2); + + QTest::touchEvent(canvas).release(0, p1, canvas).release(1, p2, canvas); + + QCOMPARE(startedSpy.count(), 2); + QCOMPARE(finishedSpy.count(), 1); + + delete canvas; +} + + +QQuickView *tst_QQuickPinchArea::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + return canvas; +} + +QTEST_MAIN(tst_QQuickPinchArea) + +#include "tst_qquickpincharea.moc" diff --git a/tests/auto/qtquick2/qquickpositioners/data/allInvisible.qml b/tests/auto/qtquick2/qquickpositioners/data/allInvisible.qml new file mode 100644 index 0000000000..5894171434 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/allInvisible.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +Item{ + width: 400 + height: 400 + Column{ + spacing: 20 + objectName: "column" + Item{ + width: 0 + height: 20 + visible: false + } + Item{ + width: 20 + height: 0 + visible: false + } + Item{ + width: 20 + height: 20 + visible: false + } + } + Row{ + spacing: 20 + objectName: "row" + Item{ + width: 0 + height: 20 + visible: false + } + Item{ + width: 20 + height: 0 + visible: false + } + Item{ + width: 20 + height: 20 + visible: false + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-column.qml b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-column.qml new file mode 100644 index 0000000000..4c667aa205 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-column.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + width: 100 + height: 200 + + Column { + + Rectangle { + width: 100 + height: 100 + color: 'red' + visible: false + } + + Rectangle { + objectName: "greenRect" + width: 100 + height: 100 + color: 'green' + property int posIndex: Positioner.index + property bool isFirstItem: Positioner.isFirstItem + property bool isLastItem: Positioner.isLastItem + } + + Rectangle { + width: 100 + height: 100 + color: 'blue' + visible: false + } + + Rectangle { + objectName: "yellowRect" + width: 100 + height: 100 + color: 'yellow' + + property int posIndex: -1 + property bool isFirstItem: false + property bool isLastItem: false + + function onDemandPositioner() { + posIndex = Positioner.index; + isFirstItem = Positioner.isFirstItem + isLastItem = Positioner.isLastItem + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-dynamic.qml b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-dynamic.qml new file mode 100644 index 0000000000..894749dc16 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-dynamic.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +Rectangle +{ + width: 300 + height: 100 + + Row { + id: pos + objectName: "pos" + anchors.fill: parent + + Rectangle { + objectName: "rect0" + width: 100 + height: 100 + color: 'red' + property int index: Positioner.index + property bool firstItem: Positioner.isFirstItem + property bool lastItem: Positioner.isLastItem + } + + Rectangle { + objectName: "rect1" + width: 100 + height: 100 + color: 'green' + property int index: Positioner.index + property bool firstItem: Positioner.isFirstItem + property bool lastItem: Positioner.isLastItem + } + + property QtObject subRect; + + function createSubRect() { + var component = Qt.createComponent("rectangleComponent.qml"); + subRect = component.createObject(pos, {}); + } + + function destroySubRect() { + subRect.destroy(); + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-flow.qml b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-flow.qml new file mode 100644 index 0000000000..e7f9a63e2a --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-flow.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 100 + + Flow { + + Rectangle { + width: 100 + height: 100 + color: 'red' + visible: false + } + + Rectangle { + objectName: "greenRect" + width: 100 + height: 100 + color: 'green' + property int posIndex: Positioner.index + property bool isFirstItem: Positioner.isFirstItem + property bool isLastItem: Positioner.isLastItem + } + + Rectangle { + width: 100 + height: 100 + color: 'blue' + visible: false + } + + Rectangle { + objectName: "yellowRect" + width: 100 + height: 100 + color: 'yellow' + + property int posIndex: -1 + property bool isFirstItem: false + property bool isLastItem: false + + function onDemandPositioner() { + posIndex = Positioner.index; + isFirstItem = Positioner.isFirstItem + isLastItem = Positioner.isLastItem + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-grid.qml b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-grid.qml new file mode 100644 index 0000000000..2094309b9f --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-grid.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 100 + + Grid { + + Rectangle { + width: 100 + height: 100 + color: 'red' + visible: false + } + + Rectangle { + objectName: "greenRect" + width: 100 + height: 100 + color: 'green' + property int posIndex: Positioner.index + property bool isFirstItem: Positioner.isFirstItem + property bool isLastItem: Positioner.isLastItem + } + + Rectangle { + width: 100 + height: 100 + color: 'blue' + visible: false + } + + Rectangle { + objectName: "yellowRect" + width: 100 + height: 100 + color: 'yellow' + + property int posIndex: -1 + property bool isFirstItem: false + property bool isLastItem: false + + function onDemandPositioner() { + posIndex = Positioner.index; + isFirstItem = Positioner.isFirstItem + isLastItem = Positioner.isLastItem + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-row.qml b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-row.qml new file mode 100644 index 0000000000..212a26b431 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/attachedproperties-row.qml @@ -0,0 +1,50 @@ +import QtQuick 2.0 + +Rectangle { + width: 200 + height: 100 + + Row { + + Rectangle { + width: 100 + height: 100 + color: 'red' + visible: false + } + + Rectangle { + objectName: "greenRect" + width: 100 + height: 100 + color: 'green' + property int posIndex: Positioner.index + property bool isFirstItem: Positioner.isFirstItem + property bool isLastItem: Positioner.isLastItem + } + + Rectangle { + width: 100 + height: 100 + color: 'blue' + visible: false + } + + Rectangle { + objectName: "yellowRect" + width: 100 + height: 100 + color: 'yellow' + + property int posIndex: -1 + property bool isFirstItem: false + property bool isLastItem: false + + function onDemandPositioner() { + posIndex = Positioner.index; + isFirstItem = Positioner.isFirstItem + isLastItem = Positioner.isLastItem + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/flow-testimplicitsize.qml b/tests/auto/qtquick2/qquickpositioners/data/flow-testimplicitsize.qml new file mode 100644 index 0000000000..c32b78676c --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/flow-testimplicitsize.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Rectangle { + width: 300; height: 200; + + property int flowLayout: 1 + + Flow { + objectName: "flow" + layoutDirection: (flowLayout == 2) ? Qt.RightToLeft : Qt.LeftToRight + flow: (flowLayout == 1) ? Flow.TopToBottom : Flow.LeftToRight; + + spacing: 20 + anchors.horizontalCenter: parent.horizontalCenter + Rectangle { color: "red"; width: 100; height: 50 } + Rectangle { color: "blue"; width: 100; height: 50 } + } +} + diff --git a/tests/auto/qtquick2/qquickpositioners/data/flowtest-toptobottom.qml b/tests/auto/qtquick2/qquickpositioners/data/flowtest-toptobottom.qml new file mode 100644 index 0000000000..a7d3ee13c7 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/flowtest-toptobottom.qml @@ -0,0 +1,44 @@ +import QtQuick 2.0 + +Item { + height: 90 + width: 480 + property bool testRightToLeft: false + + Flow { + objectName: "flow" + height: parent.height + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + flow: Flow.TopToBottom + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/flowtest.qml b/tests/auto/qtquick2/qquickpositioners/data/flowtest.qml new file mode 100644 index 0000000000..40b042dd79 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/flowtest.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 + +Item { + width: 90 + height: 480 + property bool testRightToLeft: false + + Flow { + objectName: "flow" + width: parent.width + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/grid-animated.qml b/tests/auto/qtquick2/qquickpositioners/data/grid-animated.qml new file mode 100644 index 0000000000..b8ee8f9a52 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/grid-animated.qml @@ -0,0 +1,64 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: true + + Grid { + objectName: "grid" + columns: 3 + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + add: Transition { + NumberAnimation { + properties: "x,y"; + } + } + move: Transition { + NumberAnimation { + properties: "x,y"; + } + } + Rectangle { + objectName: "one" + color: "red" + x: -100 + y: -100 + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + x: -100 + y: -100 + visible: false + color: "green" + width: 50 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + x: -100 + y: -100 + width: 50 + height: 50 + } + Rectangle { + objectName: "four" + color: "cyan" + x: -100 + y: -100 + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + x: -100 + y: -100 + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/grid-row-column-spacing.qml b/tests/auto/qtquick2/qquickpositioners/data/grid-row-column-spacing.qml new file mode 100644 index 0000000000..49bbd337e7 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/grid-row-column-spacing.qml @@ -0,0 +1,43 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Grid { + objectName: "grid" + columns: 3 + spacing: 4 + rowSpacing: 7 + columnSpacing: 11 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/grid-spacing.qml b/tests/auto/qtquick2/qquickpositioners/data/grid-spacing.qml new file mode 100644 index 0000000000..535a39037f --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/grid-spacing.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Grid { + objectName: "grid" + columns: 3 + spacing: 4 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/grid-toptobottom.qml b/tests/auto/qtquick2/qquickpositioners/data/grid-toptobottom.qml new file mode 100644 index 0000000000..45559aab5d --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/grid-toptobottom.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Grid { + objectName: "grid" + rows: 3 + flow: Grid.TopToBottom + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/gridtest.qml b/tests/auto/qtquick2/qquickpositioners/data/gridtest.qml new file mode 100644 index 0000000000..50bec1377b --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/gridtest.qml @@ -0,0 +1,42 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + Grid { + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + objectName: "grid" + columns: 3 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 30 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/gridzerocolumns.qml b/tests/auto/qtquick2/qquickpositioners/data/gridzerocolumns.qml new file mode 100644 index 0000000000..a252f279c3 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/gridzerocolumns.qml @@ -0,0 +1,40 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Grid { + objectName: "grid" + columns: 0 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "green" + width: 20 + height: 50 + } + Rectangle { + objectName: "three" + color: "blue" + width: 50 + height: 20 + } + Rectangle { + objectName: "four" + color: "cyan" + width: 50 + height: 50 + } + Rectangle { + objectName: "five" + color: "magenta" + width: 10 + height: 10 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated-disabled.qml b/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated-disabled.qml new file mode 100644 index 0000000000..8723ffc78f --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated-disabled.qml @@ -0,0 +1,40 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + + Row { + objectName: "row" + add: Transition { + enabled: false + NumberAnimation { properties: "x" } + } + move: Transition { + enabled: false + NumberAnimation { properties: "x" } + } + Rectangle { + objectName: "one" + color: "red" + x: -100; + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "blue" + x: -100; + visible: false + width: 50 + height: 50 + } + Rectangle { + objectName: "three" + x: -100; + color: "green" + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated.qml b/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated.qml new file mode 100644 index 0000000000..a88c26b66c --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/horizontal-animated.qml @@ -0,0 +1,47 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + property bool testEnabled: false + + Row { + objectName: "row" + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + add: Transition { + enabled: testEnabled ? false : true + NumberAnimation { + properties: "x"; + } + } + move: Transition { + enabled: testEnabled ? false : true + NumberAnimation { + properties: "x"; + } + } + Rectangle { + objectName: "one" + color: "red" + x: -100; + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "blue" + x: -100; + visible: false + width: 50 + height: 50 + } + Rectangle { + objectName: "three" + x: -100; + color: "green" + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/horizontal-spacing.qml b/tests/auto/qtquick2/qquickpositioners/data/horizontal-spacing.qml new file mode 100644 index 0000000000..c6ff75ac6b --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/horizontal-spacing.qml @@ -0,0 +1,31 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + + Row { + objectName: "row" + spacing: 10 + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "red" + width: 20 + height: 10 + } + Rectangle { + objectName: "three" + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/horizontal.qml b/tests/auto/qtquick2/qquickpositioners/data/horizontal.qml new file mode 100644 index 0000000000..235ee78c9b --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/horizontal.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + property bool testRightToLeft: false + Row { + objectName: "row" + layoutDirection: testRightToLeft ? Qt.RightToLeft : Qt.LeftToRight + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "red" + width: 20 + height: 10 + } + Rectangle { + objectName: "three" + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/propertychangestest.qml b/tests/auto/qtquick2/qquickpositioners/data/propertychangestest.qml new file mode 100644 index 0000000000..c9fd62b012 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/propertychangestest.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Grid { + id: myGrid + + width: 270 + height: 270 + x: 3 + y: 3 + columns: 4 + spacing: 3 + + add: columnTransition + move: columnTransition + + Repeater { + model: 20 + Rectangle { color: "black"; width: 50; height: 50 } + } + + data: [ + Transition { + id: rowTransition + objectName: "rowTransition" + NumberAnimation { + properties: "x,y"; + easing.type: "OutInCubic" + } + }, + Transition { + id: columnTransition + objectName: "columnTransition" + NumberAnimation { + properties: "x,y"; + easing.type: "OutInCubic" + } + } + ] +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/rectangleComponent.qml b/tests/auto/qtquick2/qquickpositioners/data/rectangleComponent.qml new file mode 100644 index 0000000000..de1bb99593 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/rectangleComponent.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0; + +Rectangle { + objectName: "rect2" + color: "blue" + width: 100 + height: 100 + property int index: Positioner.index + property bool firstItem: Positioner.isFirstItem + property bool lastItem: Positioner.isLastItem +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/repeatertest.qml b/tests/auto/qtquick2/qquickpositioners/data/repeatertest.qml new file mode 100644 index 0000000000..d90e1cf160 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/repeatertest.qml @@ -0,0 +1,38 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Row { + Repeater{ model: 3; + delegate: Component { + Rectangle { + color: "red" + width: 50 + height: 50 + z: {if(index == 0){2;}else if(index == 1){1;} else{3;}} + objectName: {if(index == 0){"one";}else if(index == 1){"two";} else{"three";}} + } + } + } + } + + //This crashed once (QTBUG-16959) because the repeater ended up on the end of the list + //If this grid just instantiates without crashing, then it has not regressed. + Grid { + id: grid + rows: 2 + flow: Grid.TopToBottom + + Repeater { + model: 13 + Rectangle { + color: "goldenrod" + width: 100 + height: 100 + radius: 10 + border.width: 1 + } + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/vertical-animated.qml b/tests/auto/qtquick2/qquickpositioners/data/vertical-animated.qml new file mode 100644 index 0000000000..ecf593cd70 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/vertical-animated.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Column { + objectName: "column" + add: Transition { + NumberAnimation { + properties: "y"; + } + } + move: Transition { + NumberAnimation { + properties: "y"; + } + } + Rectangle { + objectName: "one" + color: "red" + y: -100 + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "blue" + y: -100 + visible: false + width: 50 + height: 50 + } + Rectangle { + objectName: "three" + color: "red" + y: -100 + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/vertical-spacing.qml b/tests/auto/qtquick2/qquickpositioners/data/vertical-spacing.qml new file mode 100644 index 0000000000..7087961651 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/vertical-spacing.qml @@ -0,0 +1,28 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Column { + objectName: "column" + spacing: 10 + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "red" + width: 20 + height: 10 + } + Rectangle { + objectName: "three" + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/data/vertical.qml b/tests/auto/qtquick2/qquickpositioners/data/vertical.qml new file mode 100644 index 0000000000..0c3a81f008 --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/data/vertical.qml @@ -0,0 +1,27 @@ +import QtQuick 2.0 + +Item { + width: 640 + height: 480 + Column { + objectName: "column" + Rectangle { + objectName: "one" + color: "red" + width: 50 + height: 50 + } + Rectangle { + objectName: "two" + color: "red" + width: 20 + height: 10 + } + Rectangle { + objectName: "three" + color: "red" + width: 40 + height: 20 + } + } +} diff --git a/tests/auto/qtquick2/qquickpositioners/qquickpositioners.pro b/tests/auto/qtquick2/qquickpositioners/qquickpositioners.pro new file mode 100644 index 0000000000..5931b9ba3a --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/qquickpositioners.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TARGET = tst_qquickpositioners +SOURCES += tst_qquickpositioners.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/qtquick2/qquickpositioners/tst_qquickpositioners.cpp new file mode 100644 index 0000000000..867de8cb9e --- /dev/null +++ b/tests/auto/qtquick2/qquickpositioners/tst_qquickpositioners.cpp @@ -0,0 +1,1473 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" + +class tst_qquickpositioners : public QObject +{ + Q_OBJECT +public: + tst_qquickpositioners(); + +private slots: + void test_horizontal(); + void test_horizontal_rtl(); + void test_horizontal_spacing(); + void test_horizontal_spacing_rightToLeft(); + void test_horizontal_animated(); + void test_horizontal_animated_rightToLeft(); + void test_horizontal_animated_disabled(); + void test_vertical(); + void test_vertical_spacing(); + void test_vertical_animated(); + void test_grid(); + void test_grid_topToBottom(); + void test_grid_rightToLeft(); + void test_grid_spacing(); + void test_grid_row_column_spacing(); + void test_grid_animated(); + void test_grid_animated_rightToLeft(); + void test_grid_zero_columns(); + void test_propertychanges(); + void test_repeater(); + void test_flow(); + void test_flow_rightToLeft(); + void test_flow_topToBottom(); + void test_flow_resize(); + void test_flow_resize_rightToLeft(); + void test_flow_implicit_resize(); + void test_conflictinganchors(); + void test_mirroring(); + void test_allInvisible(); + void test_attachedproperties(); + void test_attachedproperties_data(); + void test_attachedproperties_dynamic(); + +private: + QQuickView *createView(const QString &filename, bool wait=true); +}; + +tst_qquickpositioners::tst_qquickpositioners() +{ +} + +void tst_qquickpositioners::test_horizontal() +{ + QQuickView *canvas = createView(TESTDATA("horizontal.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QCOMPARE(row->width(), 110.0); + QCOMPARE(row->height(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_rtl() +{ + QQuickView *canvas = createView(TESTDATA("horizontal.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 60.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 40.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QCOMPARE(row->width(), 110.0); + QCOMPARE(row->height(), 50.0); + + // Change the width of the row and check that items stay to the right + row->setWidth(200); + QTRY_COMPARE(one->x(), 150.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 130.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 90.0); + QCOMPARE(three->y(), 0.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_spacing() +{ + QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 60.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 90.0); + QCOMPARE(three->y(), 0.0); + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QCOMPARE(row->width(), 130.0); + QCOMPARE(row->height(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_spacing_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("horizontal-spacing.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 80.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 00.0); + QCOMPARE(three->y(), 0.0); + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QCOMPARE(row->width(), 130.0); + QCOMPARE(row->height(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_animated() +{ + QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + //Note that they animate in + QCOMPARE(one->x(), -100.0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(three->x(), -100.0); + + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QVERIFY(row); + QCOMPARE(row->width(), 100.0); + QCOMPARE(row->height(), 50.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->x(), 0.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 50.0); + QTRY_COMPARE(three->y(), 0.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + QTRY_COMPARE(row->width(), 150.0); + QTRY_COMPARE(row->height(), 50.0); + + QTest::qWait(0);//Let the animation start + QVERIFY(two->x() >= -100.0 && two->x() < 50.0); + QVERIFY(three->x() >= 50.0 && three->x() < 100.0); + + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(three->x(), 100.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_animated_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("horizontal-animated.qml"), false); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + //Note that they animate in + QCOMPARE(one->x(), -100.0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(three->x(), -100.0); + + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QVERIFY(row); + QCOMPARE(row->width(), 100.0); + QCOMPARE(row->height(), 50.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->x(), 50.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->x(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 0.0); + QTRY_COMPARE(three->y(), 0.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + + // New size should propagate after visible change + QTRY_COMPARE(row->width(), 150.0); + QTRY_COMPARE(row->height(), 50.0); + + QTest::qWait(0);//Let the animation start + QVERIFY(one->x() >= 50.0 && one->x() < 100); + QVERIFY(two->x() >= -100.0 && two->x() < 50.0); + + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(two->x(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_horizontal_animated_disabled() +{ + QQuickView *canvas = createView(TESTDATA("horizontal-animated-disabled.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QQuickItem *row = canvas->rootObject()->findChild("row"); + QVERIFY(row); + + qApp->processEvents(); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->isVisible(), false); + QCOMPARE(two->x(), -100.0);//Not 'in' yet + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 0.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QTRY_COMPARE(row->width(), 150.0); + QTRY_COMPARE(row->height(), 50.0); + + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(three->x(), 100.0); + + delete canvas; +} + +void tst_qquickpositioners::test_vertical() +{ + QQuickView *canvas = createView(TESTDATA("vertical.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 50.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 60.0); + + QQuickItem *column = canvas->rootObject()->findChild("column"); + QVERIFY(column); + QCOMPARE(column->height(), 80.0); + QCOMPARE(column->width(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_vertical_spacing() +{ + QQuickView *canvas = createView(TESTDATA("vertical-spacing.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 60.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 80.0); + + QQuickItem *column = canvas->rootObject()->findChild("column"); + QCOMPARE(column->height(), 100.0); + QCOMPARE(column->width(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_vertical_animated() +{ + QQuickView *canvas = createView(TESTDATA("vertical-animated.qml"), false); + + //Note that they animate in + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QCOMPARE(three->y(), -100.0); + + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *column = canvas->rootObject()->findChild("column"); + QVERIFY(column); + QCOMPARE(column->height(), 100.0); + QCOMPARE(column->width(), 50.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(one->x(), 0.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0);//Not 'in' yet + QTRY_COMPARE(two->x(), 0.0); + QTRY_COMPARE(three->y(), 50.0); + QTRY_COMPARE(three->x(), 0.0); + + //Add 'two' + two->setVisible(true); + QTRY_COMPARE(two->isVisible(), true); + QTRY_COMPARE(column->height(), 150.0); + QTRY_COMPARE(column->width(), 50.0); + QTest::qWait(0);//Let the animation start + QVERIFY(two->y() >= -100.0 && two->y() < 50.0); + QVERIFY(three->y() >= 50.0 && three->y() < 100.0); + + QTRY_COMPARE(two->y(), 50.0); + QTRY_COMPARE(three->y(), 100.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid() +{ + QQuickView *canvas = createView(TESTDATA("gridtest.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 50.0); + + QQuickGrid *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->flow(), QQuickGrid::LeftToRight); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 100.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_topToBottom() +{ + QQuickView *canvas = createView(TESTDATA("grid-toptobottom.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 0.0); + QCOMPARE(two->y(), 50.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 100.0); + QCOMPARE(four->x(), 50.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 50.0); + + QQuickGrid *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->flow(), QQuickGrid::TopToBottom); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 120.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("gridtest.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 50.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 30.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 50.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 40.0); + QCOMPARE(five->y(), 50.0); + + QQuickGrid *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->layoutDirection(), Qt::RightToLeft); + QCOMPARE(grid->width(), 100.0); + QCOMPARE(grid->height(), 100.0); + + // Change the width of the grid and check that items stay to the right + grid->setWidth(200); + QTRY_COMPARE(one->x(), 150.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 130.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 100.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 150.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 140.0); + QCOMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_spacing() +{ + QQuickView *canvas = createView(TESTDATA("grid-spacing.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 54.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 78.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 54.0); + QCOMPARE(five->x(), 54.0); + QCOMPARE(five->y(), 54.0); + + QQuickItem *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->width(), 128.0); + QCOMPARE(grid->height(), 104.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_row_column_spacing() +{ + QQuickView *canvas = createView(TESTDATA("grid-row-column-spacing.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 61.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 92.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 57.0); + QCOMPARE(five->x(), 61.0); + QCOMPARE(five->y(), 57.0); + + QQuickItem *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->width(), 142.0); + QCOMPARE(grid->height(), 107.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_animated() +{ + QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + //Note that all animate in + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QCOMPARE(one->x(), -100.0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QCOMPARE(three->x(), -100.0); + QCOMPARE(three->y(), -100.0); + + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QCOMPARE(four->x(), -100.0); + QCOMPARE(four->y(), -100.0); + + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + QCOMPARE(five->x(), -100.0); + QCOMPARE(five->y(), -100.0); + + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *grid = canvas->rootObject()->findChild("grid"); + QVERIFY(grid); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(one->x(), 0.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0); + QTRY_COMPARE(two->x(), -100.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(three->x(), 50.0); + QTRY_COMPARE(four->y(), 0.0); + QTRY_COMPARE(four->x(), 100.0); + QTRY_COMPARE(five->y(), 50.0); + QTRY_COMPARE(five->x(), 0.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + QTest::qWait(0);//Let the animation start + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 100.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 0.0); + QCOMPARE(five->y(), 50.0); + //Let the animation complete + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(one->x(), 0.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(three->x(), 100.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(four->x(), 0.0); + QTRY_COMPARE(four->y(), 50.0); + QTRY_COMPARE(five->x(), 50.0); + QTRY_COMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_animated_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("grid-animated.qml"), false); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + //Note that all animate in + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QCOMPARE(one->x(), -100.0); + QCOMPARE(one->y(), -100.0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QCOMPARE(three->x(), -100.0); + QCOMPARE(three->y(), -100.0); + + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QCOMPARE(four->x(), -100.0); + QCOMPARE(four->y(), -100.0); + + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + QCOMPARE(five->x(), -100.0); + QCOMPARE(five->y(), -100.0); + + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + QQuickItem *grid = canvas->rootObject()->findChild("grid"); + QVERIFY(grid); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + + //QTRY_COMPARE used instead of waiting for the expected time of animation completion + //Note that this means the duration of the animation is NOT tested + + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(two->isVisible(), false); + QTRY_COMPARE(two->y(), -100.0); + QTRY_COMPARE(two->x(), -100.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(three->x(), 50.0); + QTRY_COMPARE(four->y(), 0.0); + QTRY_COMPARE(four->x(), 0.0); + QTRY_COMPARE(five->y(), 50.0); + QTRY_COMPARE(five->x(), 100.0); + + //Add 'two' + two->setVisible(true); + QCOMPARE(two->isVisible(), true); + QCOMPARE(grid->width(), 150.0); + QCOMPARE(grid->height(), 100.0); + QTest::qWait(0);//Let the animation start + QCOMPARE(two->x(), -100.0); + QCOMPARE(two->y(), -100.0); + QCOMPARE(one->x(), 100.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 100.0); + QCOMPARE(five->y(), 50.0); + //Let the animation complete + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(one->x(), 100.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(three->x(), 0.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(four->x(), 100.0); + QTRY_COMPARE(four->y(), 50.0); + QTRY_COMPARE(five->x(), 50.0); + QTRY_COMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_grid_zero_columns() +{ + QQuickView *canvas = createView(TESTDATA("gridzerocolumns.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 70.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 120.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 0.0); + QCOMPARE(five->y(), 50.0); + + QQuickItem *grid = canvas->rootObject()->findChild("grid"); + QCOMPARE(grid->width(), 170.0); + QCOMPARE(grid->height(), 60.0); + + delete canvas; +} + +void tst_qquickpositioners::test_propertychanges() +{ + QQuickView *canvas = createView(TESTDATA("propertychangestest.qml")); + + QQuickGrid *grid = qobject_cast(canvas->rootObject()); + QVERIFY(grid != 0); + QDeclarativeTransition *rowTransition = canvas->rootObject()->findChild("rowTransition"); + QDeclarativeTransition *columnTransition = canvas->rootObject()->findChild("columnTransition"); + + QSignalSpy addSpy(grid, SIGNAL(addChanged())); + QSignalSpy moveSpy(grid, SIGNAL(moveChanged())); + QSignalSpy columnsSpy(grid, SIGNAL(columnsChanged())); + QSignalSpy rowsSpy(grid, SIGNAL(rowsChanged())); + + QVERIFY(grid); + QVERIFY(rowTransition); + QVERIFY(columnTransition); + QCOMPARE(grid->add(), columnTransition); + QCOMPARE(grid->move(), columnTransition); + QCOMPARE(grid->columns(), 4); + QCOMPARE(grid->rows(), -1); + + grid->setAdd(rowTransition); + grid->setMove(rowTransition); + QCOMPARE(grid->add(), rowTransition); + QCOMPARE(grid->move(), rowTransition); + QCOMPARE(addSpy.count(),1); + QCOMPARE(moveSpy.count(),1); + + grid->setAdd(rowTransition); + grid->setMove(rowTransition); + QCOMPARE(addSpy.count(),1); + QCOMPARE(moveSpy.count(),1); + + grid->setAdd(0); + grid->setMove(0); + QCOMPARE(addSpy.count(),2); + QCOMPARE(moveSpy.count(),2); + + grid->setColumns(-1); + grid->setRows(3); + QCOMPARE(grid->columns(), -1); + QCOMPARE(grid->rows(), 3); + QCOMPARE(columnsSpy.count(),1); + QCOMPARE(rowsSpy.count(),1); + + grid->setColumns(-1); + grid->setRows(3); + QCOMPARE(columnsSpy.count(),1); + QCOMPARE(rowsSpy.count(),1); + + grid->setColumns(2); + grid->setRows(2); + QCOMPARE(columnsSpy.count(),2); + QCOMPARE(rowsSpy.count(),2); + + delete canvas; +} + +void tst_qquickpositioners::test_repeater() +{ + QQuickView *canvas = createView(TESTDATA("repeatertest.qml")); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 100.0); + QCOMPARE(three->y(), 0.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow() +{ + QQuickView *canvas = createView(TESTDATA("flowtest.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 0.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 70.0); + QCOMPARE(five->x(), 50.0); + QCOMPARE(five->y(), 70.0); + + QQuickItem *flow = canvas->rootObject()->findChild("flow"); + QVERIFY(flow); + QCOMPARE(flow->width(), 90.0); + QCOMPARE(flow->height(), 120.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("flowtest.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 40.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 20.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 40.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 40.0); + QCOMPARE(four->y(), 70.0); + QCOMPARE(five->x(), 30.0); + QCOMPARE(five->y(), 70.0); + + QQuickItem *flow = canvas->rootObject()->findChild("flow"); + QVERIFY(flow); + QCOMPARE(flow->width(), 90.0); + QCOMPARE(flow->height(), 120.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow_topToBottom() +{ + QQuickView *canvas = createView(TESTDATA("flowtest-toptobottom.qml")); + + canvas->rootObject()->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 0.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 50.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 100.0); + QCOMPARE(four->y(), 00.0); + QCOMPARE(five->x(), 100.0); + QCOMPARE(five->y(), 50.0); + + QQuickItem *flow = canvas->rootObject()->findChild("flow"); + QVERIFY(flow); + QCOMPARE(flow->height(), 90.0); + QCOMPARE(flow->width(), 150.0); + + canvas->rootObject()->setProperty("testRightToLeft", true); + + QVERIFY(flow); + QCOMPARE(flow->height(), 90.0); + QCOMPARE(flow->width(), 150.0); + + QCOMPARE(one->x(), 100.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 80.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 50.0); + QCOMPARE(three->y(), 50.0); + QCOMPARE(four->x(), 0.0); + QCOMPARE(four->y(), 0.0); + QCOMPARE(five->x(), 40.0); + QCOMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow_resize() +{ + QQuickView *canvas = createView(TESTDATA("flowtest.qml")); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root); + root->setWidth(125); + root->setProperty("testRightToLeft", false); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QVERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QTRY_COMPARE(one->x(), 0.0); + QTRY_COMPARE(one->y(), 0.0); + QTRY_COMPARE(two->x(), 50.0); + QTRY_COMPARE(two->y(), 0.0); + QTRY_COMPARE(three->x(), 70.0); + QTRY_COMPARE(three->y(), 0.0); + QTRY_COMPARE(four->x(), 0.0); + QTRY_COMPARE(four->y(), 50.0); + QTRY_COMPARE(five->x(), 50.0); + QTRY_COMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow_resize_rightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("flowtest.qml")); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root); + root->setWidth(125); + root->setProperty("testRightToLeft", true); + + QQuickRectangle *one = canvas->rootObject()->findChild("one"); + QTRY_VERIFY(one != 0); + QQuickRectangle *two = canvas->rootObject()->findChild("two"); + QVERIFY(two != 0); + QQuickRectangle *three = canvas->rootObject()->findChild("three"); + QVERIFY(three != 0); + QQuickRectangle *four = canvas->rootObject()->findChild("four"); + QVERIFY(four != 0); + QQuickRectangle *five = canvas->rootObject()->findChild("five"); + QVERIFY(five != 0); + + QCOMPARE(one->x(), 75.0); + QCOMPARE(one->y(), 0.0); + QCOMPARE(two->x(), 55.0); + QCOMPARE(two->y(), 0.0); + QCOMPARE(three->x(), 5.0); + QCOMPARE(three->y(), 0.0); + QCOMPARE(four->x(), 75.0); + QCOMPARE(four->y(), 50.0); + QCOMPARE(five->x(), 65.0); + QCOMPARE(five->y(), 50.0); + + delete canvas; +} + +void tst_qquickpositioners::test_flow_implicit_resize() +{ + QQuickView *canvas = createView(TESTDATA("flow-testimplicitsize.qml")); + QVERIFY(canvas->rootObject() != 0); + + QQuickFlow *flow = canvas->rootObject()->findChild("flow"); + QVERIFY(flow != 0); + + QCOMPARE(flow->width(), 100.0); + QCOMPARE(flow->height(), 120.0); + + canvas->rootObject()->setProperty("flowLayout", 0); + QCOMPARE(flow->flow(), QQuickFlow::LeftToRight); + QCOMPARE(flow->width(), 220.0); + QCOMPARE(flow->height(), 50.0); + + canvas->rootObject()->setProperty("flowLayout", 1); + QCOMPARE(flow->flow(), QQuickFlow::TopToBottom); + QCOMPARE(flow->width(), 100.0); + QCOMPARE(flow->height(), 120.0); + + canvas->rootObject()->setProperty("flowLayout", 2); + QCOMPARE(flow->layoutDirection(), Qt::RightToLeft); + QCOMPARE(flow->width(), 220.0); + QCOMPARE(flow->height(), 50.0); + + delete canvas; +} + +QString warningMessage; + +void interceptWarnings(QtMsgType type, const char *msg) +{ + Q_UNUSED( type ); + warningMessage = msg; +} + +void tst_qquickpositioners::test_conflictinganchors() +{ + QtMsgHandler oldMsgHandler = qInstallMsgHandler(interceptWarnings); + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine); + + component.setData("import QtQuick 2.0\nColumn { Item {} }", QUrl::fromLocalFile("")); + QQuickItem *item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + delete item; + + component.setData("import QtQuick 2.0\nRow { Item {} }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + delete item; + + component.setData("import QtQuick 2.0\nGrid { Item {} }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + delete item; + + component.setData("import QtQuick 2.0\nFlow { Item {} }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + delete item; + + component.setData("import QtQuick 2.0\nColumn { Item { anchors.top: parent.top } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nColumn { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Column: Cannot specify top, bottom, verticalCenter, fill or centerIn anchors for items inside Column")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nColumn { Item { anchors.left: parent.left } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nRow { Item { anchors.left: parent.left } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nRow { Item { anchors.fill: parent } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Row: Cannot specify left, right, horizontalCenter, fill or centerIn anchors for items inside Row")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nRow { Item { anchors.top: parent.top } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QVERIFY(warningMessage.isEmpty()); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nGrid { Item { anchors.horizontalCenter: parent.horizontalCenter } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nGrid { Item { anchors.centerIn: parent } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Grid: Cannot specify anchors for items inside Grid")); + warningMessage.clear(); + delete item; + + component.setData("import QtQuick 2.0\nFlow { Item { anchors.verticalCenter: parent.verticalCenter } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow")); + delete item; + + component.setData("import QtQuick 2.0\nFlow { Item { anchors.fill: parent } }", QUrl::fromLocalFile("")); + item = qobject_cast(component.create()); + QVERIFY(item); + QCOMPARE(warningMessage, QString("file::2:1: QML Flow: Cannot specify anchors for items inside Flow")); + qInstallMsgHandler(oldMsgHandler); + delete item; +} + +void tst_qquickpositioners::test_mirroring() +{ + QList qmlFiles; + qmlFiles << "horizontal.qml" << "gridtest.qml" << "flowtest.qml"; + QList objectNames; + objectNames << "one" << "two" << "three" << "four" << "five"; + + foreach (const QString qmlFile, qmlFiles) { + QQuickView *canvasA = createView(TESTDATA(qmlFile)); + QQuickItem *rootA = qobject_cast(canvasA->rootObject()); + + QQuickView *canvasB = createView(TESTDATA(qmlFile)); + QQuickItem *rootB = qobject_cast(canvasB->rootObject()); + + rootA->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft + + // LTR != RTL + foreach (const QString objectName, objectNames) { + // horizontal.qml only has three items + if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + break; + QQuickItem *itemA = rootA->findChild(objectName); + QQuickItem *itemB = rootB->findChild(objectName); + QTRY_VERIFY(itemA->x() != itemB->x()); + } + + QQuickItemPrivate* rootPrivateB = QQuickItemPrivate::get(rootB); + + rootPrivateB->effectiveLayoutMirror = true; // LayoutMirroring.enabled: true + rootPrivateB->isMirrorImplicit = false; + rootPrivateB->inheritMirrorFromItem = true; // LayoutMirroring.childrenInherit: true + rootPrivateB->resolveLayoutMirror(); + + // RTL == mirror + foreach (const QString objectName, objectNames) { + // horizontal.qml only has three items + if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + break; + QQuickItem *itemA = rootA->findChild(objectName); + QQuickItem *itemB = rootB->findChild(objectName); + QTRY_COMPARE(itemA->x(), itemB->x()); + } + + rootA->setProperty("testRightToLeft", false); // layoutDirection: Qt.LeftToRight + rootB->setProperty("testRightToLeft", true); // layoutDirection: Qt.RightToLeft + + // LTR == RTL + mirror + foreach (const QString objectName, objectNames) { + // horizontal.qml only has three items + if (qmlFile == QString("horizontal.qml") && objectName == QString("four")) + break; + QQuickItem *itemA = rootA->findChild(objectName); + QQuickItem *itemB = rootB->findChild(objectName); + QTRY_COMPARE(itemA->x(), itemB->x()); + } + delete canvasA; + delete canvasB; + } +} + +void tst_qquickpositioners::test_allInvisible() +{ + //QTBUG-19361 + QQuickView *canvas = createView(TESTDATA("allInvisible.qml")); + + QQuickItem *root = qobject_cast(canvas->rootObject()); + QVERIFY(root); + + QQuickRow *row = canvas->rootObject()->findChild("row"); + QVERIFY(row != 0); + QVERIFY(row->width() == 0); + QVERIFY(row->height() == 0); + QQuickColumn *column = canvas->rootObject()->findChild("column"); + QVERIFY(column != 0); + QVERIFY(column->width() == 0); + QVERIFY(column->height() == 0); +} + +void tst_qquickpositioners::test_attachedproperties() +{ + QFETCH(QString, filename); + + QQuickView *canvas = createView(filename); + QVERIFY(canvas->rootObject() != 0); + + QQuickRectangle *greenRect = canvas->rootObject()->findChild("greenRect"); + QVERIFY(greenRect != 0); + + int posIndex = greenRect->property("posIndex").toInt(); + QVERIFY(posIndex == 0); + bool isFirst = greenRect->property("isFirstItem").toBool(); + QVERIFY(isFirst == true); + bool isLast = greenRect->property("isLastItem").toBool(); + QVERIFY(isLast == false); + + QQuickRectangle *yellowRect = canvas->rootObject()->findChild("yellowRect"); + QVERIFY(yellowRect != 0); + + posIndex = yellowRect->property("posIndex").toInt(); + QVERIFY(posIndex == -1); + isFirst = yellowRect->property("isFirstItem").toBool(); + QVERIFY(isFirst == false); + isLast = yellowRect->property("isLastItem").toBool(); + QVERIFY(isLast == false); + + yellowRect->metaObject()->invokeMethod(yellowRect, "onDemandPositioner"); + + posIndex = yellowRect->property("posIndex").toInt(); + QVERIFY(posIndex == 1); + isFirst = yellowRect->property("isFirstItem").toBool(); + QVERIFY(isFirst == false); + isLast = yellowRect->property("isLastItem").toBool(); + QVERIFY(isLast == true); + + delete canvas; +} + +void tst_qquickpositioners::test_attachedproperties_data() +{ + QTest::addColumn("filename"); + + QTest::newRow("column") << TESTDATA("attachedproperties-column.qml"); + QTest::newRow("row") << TESTDATA("attachedproperties-row.qml"); + QTest::newRow("grid") << TESTDATA("attachedproperties-grid.qml"); + QTest::newRow("flow") << TESTDATA("attachedproperties-flow.qml"); +} + +void tst_qquickpositioners::test_attachedproperties_dynamic() +{ + QQuickView *canvas = createView(TESTDATA("attachedproperties-dynamic.qml")); + QVERIFY(canvas->rootObject() != 0); + + QQuickRow *row = canvas->rootObject()->findChild("pos"); + QVERIFY(row != 0); + + QQuickRectangle *rect0 = canvas->rootObject()->findChild("rect0"); + QVERIFY(rect0 != 0); + + int posIndex = rect0->property("index").toInt(); + QVERIFY(posIndex == 0); + bool isFirst = rect0->property("firstItem").toBool(); + QVERIFY(isFirst == true); + bool isLast = rect0->property("lastItem").toBool(); + QVERIFY(isLast == false); + + QQuickRectangle *rect1 = canvas->rootObject()->findChild("rect1"); + QVERIFY(rect1 != 0); + + posIndex = rect1->property("index").toInt(); + QVERIFY(posIndex == 1); + isFirst = rect1->property("firstItem").toBool(); + QVERIFY(isFirst == false); + isLast = rect1->property("lastItem").toBool(); + QVERIFY(isLast == true); + + row->metaObject()->invokeMethod(row, "createSubRect"); + + QTRY_VERIFY(rect1->property("index").toInt() == 1); + QTRY_VERIFY(rect1->property("firstItem").toBool() == false); + QTRY_VERIFY(rect1->property("lastItem").toBool() == false); + + QQuickRectangle *rect2 = canvas->rootObject()->findChild("rect2"); + QVERIFY(rect2 != 0); + + posIndex = rect2->property("index").toInt(); + QVERIFY(posIndex == 2); + isFirst = rect2->property("firstItem").toBool(); + QVERIFY(isFirst == false); + isLast = rect2->property("lastItem").toBool(); + QVERIFY(isLast == true); + + row->metaObject()->invokeMethod(row, "destroySubRect"); + + qApp->processEvents(QEventLoop::DeferredDeletion); + + QTRY_VERIFY(rect1->property("index").toInt() == 1); + QTRY_VERIFY(rect1->property("firstItem").toBool() == false); + QTRY_VERIFY(rect1->property("lastItem").toBool() == true); + + delete canvas; +} + +QQuickView *tst_qquickpositioners::createView(const QString &filename, bool wait) +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(QUrl::fromLocalFile(filename)); + canvas->show(); + if (wait) + QTest::qWaitForWindowShown(canvas); //It may not relayout until the next frame, so it needs to be drawn + + return canvas; +} + + +QTEST_MAIN(tst_qquickpositioners) + +#include "tst_qquickpositioners.moc" diff --git a/tests/auto/qtquick2/qquickrepeater/data/asyncloader.qml b/tests/auto/qtquick2/qquickrepeater/data/asyncloader.qml new file mode 100644 index 0000000000..82094e2666 --- /dev/null +++ b/tests/auto/qtquick2/qquickrepeater/data/asyncloader.qml @@ -0,0 +1,32 @@ +import QtQuick 2.0 + +Item { + width: 360 + height: 480 + + Loader { + asynchronous: true + sourceComponent: viewComponent + } + + Component { + id: viewComponent + Column { + objectName: "container" + Repeater { + id: repeater + objectName: "repeater" + + model: 10 + + delegate: Rectangle { + objectName: "delegate" + index + color: "red" + width: 360 + height: 50 + Text { text: index } + } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickrepeater/data/initparent.qml b/tests/auto/qtquick2/qquickrepeater/data/initparent.qml new file mode 100644 index 0000000000..e6571f09d3 --- /dev/null +++ b/tests/auto/qtquick2/qquickrepeater/data/initparent.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + id: root + property Item parentItem: null + Repeater { + model: 1 + Item { + Component.onCompleted: root.parentItem = parent + } + } +} diff --git a/tests/auto/qtquick2/qquickrepeater/data/intmodel.qml b/tests/auto/qtquick2/qquickrepeater/data/intmodel.qml new file mode 100644 index 0000000000..30a650dd52 --- /dev/null +++ b/tests/auto/qtquick2/qquickrepeater/data/intmodel.qml @@ -0,0 +1,29 @@ +import QtQuick 2.0 + +Rectangle { + id: container + objectName: "container" + width: 240 + height: 320 + color: "white" + + function checkProperties() { + testObject.error = false; + if (repeater.delegate != comp) { + console.log("delegate property incorrect"); + testObject.error = true; + } + } + + Component { + id: comp + Item{} + } + + Repeater { + id: repeater + objectName: "repeater" + model: testData + delegate: comp + } +} diff --git a/tests/auto/qtquick2/qquickrepeater/data/itemlist.qml b/tests/auto/qtquick2/qquickrepeater/data/itemlist.qml new file mode 100644 index 0000000000..174bfd4d18 --- /dev/null +++ b/tests/auto/qtquick2/qquickrepeater/data/itemlist.qml @@ -0,0 +1,68 @@ +// This example demonstrates placing items in a view using +// a VisualItemModel + +import QtQuick 2.0 + +Rectangle { + id: root + color: "lightgray" + width: 240 + height: 320 + property variant itemModel: itemModel1 + + function checkProperties() { + testObject.error = false; + if (testObject.useModel && view.model != root.itemModel) { + console.log("model property incorrect"); + testObject.error = true; + } + } + + function switchModel() { + root.itemModel = itemModel2 + } + + VisualItemModel { + id: itemModel1 + objectName: "itemModel1" + Rectangle { + objectName: "item1" + height: 50; width: 100; color: "#FFFEF0" + Text { objectName: "text1"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item2" + height: 50; width: 100; color: "#F0FFF7" + Text { objectName: "text2"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item3" + height: 50; width: 100; color: "#F4F0FF" + Text { objectName: "text3"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + VisualItemModel { + id: itemModel2 + objectName: "itemModel2" + Rectangle { + objectName: "item4" + height: 50; width: 100; color: "#FFFEF0" + Text { objectName: "text4"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + Rectangle { + objectName: "item5" + height: 50; width: 100; color: "#F0FFF7" + Text { objectName: "text5"; text: "index: " + parent.VisualItemModel.index; font.bold: true; anchors.centerIn: parent } + } + } + + Column { + objectName: "container" + Repeater { + id: view + objectName: "repeater" + model: testObject.useModel ? root.itemModel : 0 + } + } +} diff --git a/tests/auto/qtquick2/qquickrepeater/data/modelChanged.qml b/tests/auto/qtquick2/qquickrepeater/data/modelChanged.qml new file mode 100644 index 0000000000..23af127e79 --- /dev/null +++ b/tests/auto/qtquick2/qquickrepeater/data/modelChanged.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 + +Column { + Repeater { + id: repeater + objectName: "repeater" + + property int itemsCount + property variant itemsFound: [] + + delegate: Rectangle { + color: "red" + width: (index+1)*50 + height: 50 + } + + onModelChanged: { + repeater.itemsCount = repeater.count + var items = [] + for (var i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../shared/util.h" + +inline QUrl TEST_FILE(const QString &filename) +{ + return QUrl::fromLocalFile(TESTDATA(filename)); +} + +class tst_QQuickRepeater : public QObject +{ + Q_OBJECT +public: + tst_QQuickRepeater(); + +private slots: + void numberModel(); + void objectList(); + void stringList(); + void dataModel_adding(); + void dataModel_removing(); + void dataModel_changes(); + void itemModel(); + void resetModel(); + void modelChanged(); + void properties(); + void asynchronous(); + void initParent(); + +private: + QQuickView *createView(); + template + T *findItem(QObject *parent, const QString &objectName, int index); + template + T *findItem(QObject *parent, const QString &id); +}; + +class TestObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(bool error READ error WRITE setError) + Q_PROPERTY(bool useModel READ useModel NOTIFY useModelChanged) + +public: + TestObject() : QObject(), mError(true), mUseModel(false) {} + + bool error() const { return mError; } + void setError(bool err) { mError = err; } + + bool useModel() const { return mUseModel; } + void setUseModel(bool use) { mUseModel = use; emit useModelChanged(); } + +signals: + void useModelChanged(); + +private: + bool mError; + bool mUseModel; +}; + +class TestModel : public QAbstractListModel +{ +public: + enum Roles { Name = Qt::UserRole+1, Number = Qt::UserRole+2 }; + + TestModel(QObject *parent=0) : QAbstractListModel(parent) { + QHash roles; + roles[Name] = "name"; + roles[Number] = "number"; + setRoleNames(roles); + } + + int rowCount(const QModelIndex &parent=QModelIndex()) const { Q_UNUSED(parent); return list.count(); } + QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const { + QVariant rv; + if (role == Name) + rv = list.at(index.row()).first; + else if (role == Number) + rv = list.at(index.row()).second; + + return rv; + } + + int count() const { return rowCount(); } + QString name(int index) const { return list.at(index).first; } + QString number(int index) const { return list.at(index).second; } + + void addItem(const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), list.count(), list.count()); + list.append(QPair(name, number)); + emit endInsertRows(); + } + + void insertItem(int index, const QString &name, const QString &number) { + emit beginInsertRows(QModelIndex(), index, index); + list.insert(index, QPair(name, number)); + emit endInsertRows(); + } + + void removeItem(int index) { + emit beginRemoveRows(QModelIndex(), index, index); + list.removeAt(index); + emit endRemoveRows(); + } + + void moveItem(int from, int to) { + emit beginMoveRows(QModelIndex(), from, from, QModelIndex(), to); + list.move(from, to); + emit endMoveRows(); + } + + void modifyItem(int idx, const QString &name, const QString &number) { + list[idx] = QPair(name, number); + emit dataChanged(index(idx,0), index(idx,0)); + } + +private: + QList > list; +}; + + +tst_QQuickRepeater::tst_QQuickRepeater() +{ +} + +void tst_QQuickRepeater::numberModel() +{ + QQuickView *canvas = createView(); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testData", 5); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(TEST_FILE("intmodel.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QCOMPARE(repeater->parentItem()->childItems().count(), 5+1); + + QVERIFY(!repeater->itemAt(-1)); + for (int i=0; icount(); i++) + QCOMPARE(repeater->itemAt(i), repeater->parentItem()->childItems().at(i)); + QVERIFY(!repeater->itemAt(repeater->count())); + + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QVERIFY(testObject->error() == false); + + delete testObject; + delete canvas; +} + +class MyObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(int idx READ idx CONSTANT) +public: + MyObject(int i) : QObject(), m_idx(i) {} + + int idx() const { return m_idx; } + + int m_idx; +}; + +void tst_QQuickRepeater::objectList() +{ + QQuickView *canvas = createView(); + QObjectList data; + for (int i=0; i<100; i++) + data << new MyObject(i); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testData", QVariant::fromValue(data)); + + canvas->setSource(TEST_FILE("objlist.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QCOMPARE(repeater->property("errors").toInt(), 0);//If this fails either they are out of order or can't find the object's data + QCOMPARE(repeater->property("instantiated").toInt(), 100); + + QVERIFY(!repeater->itemAt(-1)); + for (int i=0; iitemAt(i), repeater->parentItem()->childItems().at(i)); + QVERIFY(!repeater->itemAt(data.count())); + + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); + ctxt->setContextProperty("testData", QVariant::fromValue(data)); + QCOMPARE(addedSpy.count(), data.count()); + QCOMPARE(removedSpy.count(), data.count()); + + qDeleteAll(data); + delete canvas; +} + +/* +The Repeater element creates children at its own position in its parent's +stacking order. In this test we insert a repeater between two other Text +elements to test this. +*/ +void tst_QQuickRepeater::stringList() +{ + QQuickView *canvas = createView(); + + QStringList data; + data << "One"; + data << "Two"; + data << "Three"; + data << "Four"; + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testData", data); + + canvas->setSource(TEST_FILE("repeater1.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QCOMPARE(container->childItems().count(), data.count() + 3); + + bool saw_repeater = false; + for (int i = 0; i < container->childItems().count(); ++i) { + + if (i == 0) { + QQuickText *name = qobject_cast(container->childItems().at(i)); + QVERIFY(name != 0); + QCOMPARE(name->text(), QLatin1String("Zero")); + } else if (i == container->childItems().count() - 2) { + // The repeater itself + QQuickRepeater *rep = qobject_cast(container->childItems().at(i)); + QCOMPARE(rep, repeater); + saw_repeater = true; + continue; + } else if (i == container->childItems().count() - 1) { + QQuickText *name = qobject_cast(container->childItems().at(i)); + QVERIFY(name != 0); + QCOMPARE(name->text(), QLatin1String("Last")); + } else { + QQuickText *name = qobject_cast(container->childItems().at(i)); + QVERIFY(name != 0); + QCOMPARE(name->text(), data.at(i-1)); + } + } + QVERIFY(saw_repeater); + + delete canvas; +} + +void tst_QQuickRepeater::dataModel_adding() +{ + QQuickView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + TestModel testModel; + ctxt->setContextProperty("testData", &testModel); + canvas->setSource(TEST_FILE("repeater2.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QVERIFY(!repeater->itemAt(0)); + + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); + + // add to empty model + testModel.addItem("two", "2"); + QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(0)); + addedSpy.clear(); + + // insert at start + testModel.insertItem(0, "one", "1"); + QCOMPARE(repeater->itemAt(0), container->childItems().at(0)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(0)); + addedSpy.clear(); + + // insert at end + testModel.insertItem(2, "four", "4"); + QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); + QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(2)); + addedSpy.clear(); + + // insert in middle + testModel.insertItem(2, "three", "3"); + QCOMPARE(repeater->itemAt(2), container->childItems().at(2)); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(addedSpy.count(), 1); + QCOMPARE(addedSpy.at(0).at(0).toInt(), 2); + QCOMPARE(addedSpy.at(0).at(1).value(), container->childItems().at(2)); + addedSpy.clear(); + + delete testObject; + addedSpy.clear(); + countSpy.clear(); + delete canvas; +} + +void tst_QQuickRepeater::dataModel_removing() +{ + QQuickView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + TestModel testModel; + testModel.addItem("one", "1"); + testModel.addItem("two", "2"); + testModel.addItem("three", "3"); + testModel.addItem("four", "4"); + testModel.addItem("five", "5"); + + ctxt->setContextProperty("testData", &testModel); + canvas->setSource(TEST_FILE("repeater2.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + QCOMPARE(container->childItems().count(), repeater->count()+1); + + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); + + // remove at start + QQuickItem *item = repeater->itemAt(0); + QCOMPARE(item, container->childItems().at(0)); + + testModel.removeItem(0); + QVERIFY(repeater->itemAt(0) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), 0); + QCOMPARE(removedSpy.at(0).at(1).value(), item); + removedSpy.clear(); + + // remove at end + int lastIndex = testModel.count()-1; + item = repeater->itemAt(lastIndex); + QCOMPARE(item, container->childItems().at(lastIndex)); + + testModel.removeItem(lastIndex); + QVERIFY(repeater->itemAt(lastIndex) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), lastIndex); + QCOMPARE(removedSpy.at(0).at(1).value(), item); + removedSpy.clear(); + + // remove from middle + item = repeater->itemAt(1); + QCOMPARE(item, container->childItems().at(1)); + + testModel.removeItem(1); + QVERIFY(repeater->itemAt(lastIndex) != item); + QCOMPARE(countSpy.count(), 1); countSpy.clear(); + QCOMPARE(removedSpy.count(), 1); + QCOMPARE(removedSpy.at(0).at(0).toInt(), 1); + QCOMPARE(removedSpy.at(0).at(1).value(), item); + removedSpy.clear(); + + delete testObject; + delete canvas; +} + +void tst_QQuickRepeater::dataModel_changes() +{ + QQuickView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + TestModel testModel; + testModel.addItem("one", "1"); + testModel.addItem("two", "2"); + testModel.addItem("three", "3"); + + ctxt->setContextProperty("testData", &testModel); + canvas->setSource(TEST_FILE("repeater2.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + QCOMPARE(container->childItems().count(), repeater->count()+1); + + // Check that model changes are propagated + QQuickText *text = findItem(canvas->rootObject(), "myName", 1); + QVERIFY(text); + QCOMPARE(text->text(), QString("two")); + + testModel.modifyItem(1, "Item two", "_2"); + text = findItem(canvas->rootObject(), "myName", 1); + QVERIFY(text); + QCOMPARE(text->text(), QString("Item two")); + + text = findItem(canvas->rootObject(), "myNumber", 1); + QVERIFY(text); + QCOMPARE(text->text(), QString("_2")); + + delete testObject; + delete canvas; +} + +void tst_QQuickRepeater::itemModel() +{ + QQuickView *canvas = createView(); + QDeclarativeContext *ctxt = canvas->rootContext(); + TestObject *testObject = new TestObject; + ctxt->setContextProperty("testObject", testObject); + + canvas->setSource(TEST_FILE("itemlist.qml")); + qApp->processEvents(); + + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QCOMPARE(container->childItems().count(), 1); + + testObject->setUseModel(true); + QMetaObject::invokeMethod(canvas->rootObject(), "checkProperties"); + QVERIFY(testObject->error() == false); + + QCOMPARE(container->childItems().count(), 4); + QVERIFY(qobject_cast(container->childItems().at(0))->objectName() == "item1"); + QVERIFY(qobject_cast(container->childItems().at(1))->objectName() == "item2"); + QVERIFY(qobject_cast(container->childItems().at(2))->objectName() == "item3"); + QVERIFY(container->childItems().at(3) == repeater); + + QMetaObject::invokeMethod(canvas->rootObject(), "switchModel"); + QCOMPARE(container->childItems().count(), 3); + QVERIFY(qobject_cast(container->childItems().at(0))->objectName() == "item4"); + QVERIFY(qobject_cast(container->childItems().at(1))->objectName() == "item5"); + QVERIFY(container->childItems().at(2) == repeater); + + testObject->setUseModel(false); + QCOMPARE(container->childItems().count(), 1); + + delete testObject; + delete canvas; +} + +void tst_QQuickRepeater::resetModel() +{ + QQuickView *canvas = createView(); + + QStringList dataA; + for (int i=0; i<10; i++) + dataA << QString::number(i); + + QDeclarativeContext *ctxt = canvas->rootContext(); + ctxt->setContextProperty("testData", dataA); + canvas->setSource(TEST_FILE("repeater1.qml")); + qApp->processEvents(); + QQuickRepeater *repeater = findItem(canvas->rootObject(), "repeater"); + QVERIFY(repeater != 0); + QQuickItem *container = findItem(canvas->rootObject(), "container"); + QVERIFY(container != 0); + + QCOMPARE(repeater->count(), dataA.count()); + for (int i=0; icount(); i++) + QCOMPARE(repeater->itemAt(i), container->childItems().at(i+1)); // +1 to skip first Text object + + QSignalSpy modelChangedSpy(repeater, SIGNAL(modelChanged())); + QSignalSpy countSpy(repeater, SIGNAL(countChanged())); + QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*))); + QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*))); + + QStringList dataB; + for (int i=0; i<20; i++) + dataB << QString::number(i); + + // reset context property + ctxt->setContextProperty("testData", dataB); + QCOMPARE(repeater->count(), dataB.count()); + + QCOMPARE(modelChangedSpy.count(), 1); + QCOMPARE(countSpy.count(), 1); + QCOMPARE(removedSpy.count(), dataA.count()); + QCOMPARE(addedSpy.count(), dataB.count()); + for (int i=0; i(), repeater->itemAt(i)); + } + modelChangedSpy.clear(); + countSpy.clear(); + removedSpy.clear(); + addedSpy.clear(); + + // reset via setModel() + repeater->setModel(dataA); + QCOMPARE(repeater->count(), dataA.count()); + + QCOMPARE(modelChangedSpy.count(), 1); + QCOMPARE(countSpy.count(), 1); + QCOMPARE(removedSpy.count(), dataB.count()); + QCOMPARE(addedSpy.count(), dataA.count()); + for (int i=0; i(), repeater->itemAt(i)); + } + + modelChangedSpy.clear(); + countSpy.clear(); + removedSpy.clear(); + addedSpy.clear(); + + delete canvas; +} + +// QTBUG-17156 +void tst_QQuickRepeater::modelChanged() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, TEST_FILE("modelChanged.qml")); + + QQuickItem *rootObject = qobject_cast(component.create()); + QVERIFY(rootObject); + QQuickRepeater *repeater = findItem(rootObject, "repeater"); + QVERIFY(repeater); + + repeater->setModel(4); + QCOMPARE(repeater->count(), 4); + QCOMPARE(repeater->property("itemsCount").toInt(), 4); + QCOMPARE(repeater->property("itemsFound").toList().count(), 4); + + repeater->setModel(10); + QCOMPARE(repeater->count(), 10); + QCOMPARE(repeater->property("itemsCount").toInt(), 10); + QCOMPARE(repeater->property("itemsFound").toList().count(), 10); + + delete rootObject; +} + +void tst_QQuickRepeater::properties() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, TEST_FILE("properties.qml")); + + QQuickItem *rootObject = qobject_cast(component.create()); + QVERIFY(rootObject); + + QQuickRepeater *repeater = findItem(rootObject, "repeater"); + QVERIFY(repeater); + + QSignalSpy modelSpy(repeater, SIGNAL(modelChanged())); + repeater->setModel(3); + QCOMPARE(modelSpy.count(),1); + repeater->setModel(3); + QCOMPARE(modelSpy.count(),1); + + QSignalSpy delegateSpy(repeater, SIGNAL(delegateChanged())); + + QDeclarativeComponent rectComponent(&engine); + rectComponent.setData("import QtQuick 2.0; Rectangle {}", QUrl::fromLocalFile("")); + + repeater->setDelegate(&rectComponent); + QCOMPARE(delegateSpy.count(),1); + repeater->setDelegate(&rectComponent); + QCOMPARE(delegateSpy.count(),1); + + delete rootObject; +} + +void tst_QQuickRepeater::asynchronous() +{ + QQuickView *canvas = createView(); + canvas->show(); + QDeclarativeIncubationController controller; + canvas->engine()->setIncubationController(&controller); + + canvas->setSource(TEST_FILE("asyncloader.qml")); + + QQuickItem *rootObject = qobject_cast(canvas->rootObject()); + QVERIFY(rootObject); + + QQuickItem *container = findItem(rootObject, "container"); + QVERIFY(!container); + while (!container) { + bool b = false; + controller.incubateWhile(&b); + container = findItem(rootObject, "container"); + } + + QQuickRepeater *repeater = 0; + while (!repeater) { + bool b = false; + controller.incubateWhile(&b); + repeater = findItem(rootObject, "repeater"); + } + + // items will be created one at a time + for (int i = 0; i < 10; ++i) { + QString name("delegate"); + name += QString::number(i); + QVERIFY(findItem(container, name) == 0); + QQuickItem *item = 0; + while (!item) { + bool b = false; + controller.incubateWhile(&b); + item = findItem(container, name); + } + } + + { + bool b = true; + controller.incubateWhile(&b); + } + + // verify positioning + for (int i = 0; i < 10; ++i) { + QString name("delegate"); + name += QString::number(i); + QQuickItem *item = findItem(container, name); + QTRY_COMPARE(item->y(), i * 50.0); + } + + delete canvas; +} + +void tst_QQuickRepeater::initParent() +{ + QDeclarativeEngine engine; + QDeclarativeComponent component(&engine, TEST_FILE("initparent.qml")); + + QQuickItem *rootObject = qobject_cast(component.create()); + QVERIFY(rootObject); + + QCOMPARE(qvariant_cast(rootObject->property("parentItem")), rootObject); +} + +QQuickView *tst_QQuickRepeater::createView() +{ + QQuickView *canvas = new QQuickView(0); + canvas->setGeometry(0,0,240,320); + + return canvas; +} + +template +T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->children().count() << "children"; + for (int i = 0; i < parent->children().count(); ++i) { + QQuickItem *item = qobject_cast(parent->children().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), item, "index"); + if (e.evaluate().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +template +T *tst_QQuickRepeater::findItem(QObject *parent, const QString &objectName) +{ + const QMetaObject &mo = T::staticMetaObject; + if (mo.cast(parent) && (objectName.isEmpty() || parent->objectName() == objectName)) + return static_cast(parent); + for (int i = 0; i < parent->children().count(); ++i) { + QQuickItem *child = qobject_cast(parent->children().at(i)); + if (!child) + continue; + QQuickItem *item = findItem(child, objectName); + if (item) + return static_cast(item); + } + + return 0; +} + +QTEST_MAIN(tst_QQuickRepeater) + +#include "tst_qquickrepeater.moc" diff --git a/tests/auto/qtquick2/qquickshadereffect/qquickshadereffect.pro b/tests/auto/qtquick2/qquickshadereffect/qquickshadereffect.pro new file mode 100644 index 0000000000..de8b247340 --- /dev/null +++ b/tests/auto/qtquick2/qquickshadereffect/qquickshadereffect.pro @@ -0,0 +1,8 @@ +CONFIG += testcase +TARGET = tst_qquickshadereffect +SOURCES += tst_qquickshadereffect.cpp + +macx:CONFIG -= app_bundle + +CONFIG += parallel_test +QT += core-private gui-private declarative-private quick-private widgets testlib diff --git a/tests/auto/qtquick2/qquickshadereffect/tst_qquickshadereffect.cpp b/tests/auto/qtquick2/qquickshadereffect/tst_qquickshadereffect.cpp new file mode 100644 index 0000000000..327fecf1ab --- /dev/null +++ b/tests/auto/qtquick2/qquickshadereffect/tst_qquickshadereffect.cpp @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include + +class TestShaderEffect : public QQuickShaderEffect +{ + Q_OBJECT + Q_PROPERTY(QVariant source READ dummyRead NOTIFY dummyChanged) + Q_PROPERTY(QVariant _0aA9zZ READ dummyRead NOTIFY dummyChanged) + Q_PROPERTY(QVariant x86 READ dummyRead NOTIFY dummyChanged) + Q_PROPERTY(QVariant X READ dummyRead NOTIFY dummyChanged) + +public: + QVariant dummyRead() const { return QVariant(); } + bool isConnected(const char *signal) const { return m_signals.contains(signal); } + +protected: + void connectNotify(const char *signal) { m_signals.append(signal); } + void disconnectNotify(const char *signal) { m_signals.removeOne(signal); } + +signals: + void dummyChanged(); + +private: + QList m_signals; +}; + +class tst_qquickshadereffect : public QObject +{ + Q_OBJECT +public: + tst_qquickshadereffect(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void lookThroughShaderCode_data(); + void lookThroughShaderCode(); + +private: + enum PresenceFlags { + VertexPresent = 0x01, + TexCoordPresent = 0x02, + MatrixPresent = 0x04, + OpacityPresent = 0x08, + PropertyPresent = 0x10 + }; + + static void installMsgHandler(); + static void uninstallMsgHandler(); + static void msgHandler(QtMsgType type, const char *msg); + static void expectWarning(const char *msg); + + static QtMsgHandler originalMsgHandler; + static QByteArray actualWarnings; + static QByteArray expectedWarnings; +}; + +QtMsgHandler tst_qquickshadereffect::originalMsgHandler = 0; +QByteArray tst_qquickshadereffect::actualWarnings; +QByteArray tst_qquickshadereffect::expectedWarnings; + +void tst_qquickshadereffect::installMsgHandler() +{ + Q_ASSERT(originalMsgHandler == 0); + originalMsgHandler = qInstallMsgHandler(msgHandler); + actualWarnings.clear(); + expectedWarnings.clear(); +} + +void tst_qquickshadereffect::uninstallMsgHandler() +{ + Q_ASSERT(originalMsgHandler != 0); + qInstallMsgHandler(originalMsgHandler); + originalMsgHandler = 0; + QCOMPARE(QString(actualWarnings), QString(expectedWarnings)); // QString for sensible output. +} + +void tst_qquickshadereffect::msgHandler(QtMsgType type, const char *msg) +{ + Q_ASSERT(originalMsgHandler != 0); + if (type == QtWarningMsg) + actualWarnings.append(msg).append('\n'); + originalMsgHandler(type, msg); +} + +void tst_qquickshadereffect::expectWarning(const char *msg) +{ + Q_ASSERT(originalMsgHandler != 0); + expectedWarnings.append(msg).append('\n'); + QTest::ignoreMessage(QtWarningMsg, msg); +} + +tst_qquickshadereffect::tst_qquickshadereffect() +{ +} + +void tst_qquickshadereffect::initTestCase() +{ +} + +void tst_qquickshadereffect::cleanupTestCase() +{ +} + +void tst_qquickshadereffect::lookThroughShaderCode_data() +{ + QTest::addColumn("vertexShader"); + QTest::addColumn("fragmentShader"); + QTest::addColumn("presenceFlags"); + + QTest::newRow("default") + << QByteArray("uniform highp mat4 qt_Matrix; \n" + "attribute highp vec4 qt_Vertex; \n" + "attribute highp vec2 qt_MultiTexCoord0; \n" + "varying highp vec2 qt_TexCoord0; \n" + "void main() { \n" + " qt_TexCoord0 = qt_MultiTexCoord0; \n" + " gl_Position = qt_Matrix * qt_Vertex; \n" + "}") + << QByteArray("varying highp vec2 qt_TexCoord0; \n" + "uniform sampler2D source; \n" + "uniform lowp float qt_Opacity; \n" + "void main() { \n" + " gl_FragColor = texture2D(source, qt_TexCoord0) * qt_Opacity; \n" + "}") + << (VertexPresent | TexCoordPresent | MatrixPresent | OpacityPresent | PropertyPresent); + + QTest::newRow("empty") + << QByteArray(" ") // one space -- if completely empty, default will be used instead. + << QByteArray(" ") + << 0; + + + QTest::newRow("inside line 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); + + 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); + + QTest::newRow("inside preprocessor directive") + << QByteArray("#define uniform\nhighp mat4 qt_Matrix;\n" + "attribute highp vec4 qt_Vertex;\n" + "#if\\\nattribute highp vec2 qt_MultiTexCoord0;") + << QByteArray("uniform int source;\n" + " # undef uniform lowp float qt_Opacity;") + << (VertexPresent | PropertyPresent); + + + QTest::newRow("line comments between") + << QByteArray("uniform//foo\nhighp//bar\nmat4//baz\nqt_Matrix;\n" + "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); + + 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); + + 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); + + QTest::newRow("newline between") + << QByteArray("uniform\nhighp\nmat4\nqt_Matrix\n;\n" + "attribute \t\r\n highp \n vec4 \n\n qt_Vertex ;\n" + " \n attribute \n highp \n vec2 \n qt_Multi\nTexCoord0 \n ;") + << QByteArray("uniform\nsampler2D\nsource;" + "uniform lowp float qt_Opacity;") + << (VertexPresent | MatrixPresent | OpacityPresent | PropertyPresent); + + + QTest::newRow("extra characters #1") + << QByteArray("funiform highp mat4 qt_Matrix;\n" + "attribute highp vec4 qt_Vertex_;\n" + "attribute highp vec2 qqt_MultiTexCoord0;") + << QByteArray("uniformm int source;\n" + "uniform4 lowp float qt_Opacity;") + << 0; + + QTest::newRow("extra characters #2") + << QByteArray("attribute phighp vec4 qt_Vertex;\n" + "attribute highpi vec2 qt_MultiTexCoord0;" + "fattribute highp vec4 qt_Vertex;\n" + "attributed highp vec2 qt_MultiTexCoord0;") + << QByteArray(" ") + << 0; + + QTest::newRow("missing characters #1") + << QByteArray("unifor highp mat4 qt_Matrix;\n" + "attribute highp vec4 qt_Vert;\n" + "attribute highp vec2 MultiTexCoord0;") + << QByteArray("niform int source;\n" + "uniform qt_Opacity;") + << 0; + + QTest::newRow("missing characters #2") + << QByteArray("attribute high vec4 qt_Vertex;\n" + "attribute ighp vec2 qt_MultiTexCoord0;" + "tribute highp vec4 qt_Vertex;\n" + "attrib highp vec2 qt_MultiTexCoord0;") + << QByteArray(" ") + << 0; + + QTest::newRow("precision") + << QByteArray("uniform mat4 qt_Matrix;\n" + "attribute kindofhighp vec4 qt_Vertex;\n" + "attribute highp qt_MultiTexCoord0;\n") + << QByteArray("uniform lowp float qt_Opacity;\n" + "uniform mediump float source;\n") + << (MatrixPresent | OpacityPresent | PropertyPresent); + + + QTest::newRow("property name #1") + << QByteArray("uniform highp vec3 _0aA9zZ;") + << QByteArray(" ") + << int(PropertyPresent); + + QTest::newRow("property name #2") + << QByteArray("uniform mediump vec2 x86;") + << QByteArray(" ") + << int(PropertyPresent); + + QTest::newRow("property name #3") + << QByteArray("uniform lowp float X;") + << QByteArray(" ") + << int(PropertyPresent); +} + +void tst_qquickshadereffect::lookThroughShaderCode() +{ + QFETCH(QByteArray, vertexShader); + QFETCH(QByteArray, fragmentShader); + QFETCH(int, presenceFlags); + + TestShaderEffect item; + QVERIFY(!item.isConnected(SIGNAL(dummyChanged()))); // Nothing connected yet. + + installMsgHandler(); + if ((presenceFlags & VertexPresent) == 0) + expectWarning("QQuickShaderEffect: Missing reference to \'qt_Vertex\'."); + if ((presenceFlags & TexCoordPresent) == 0) + expectWarning("QQuickShaderEffect: Missing reference to \'qt_MultiTexCoord0\'."); + if ((presenceFlags & MatrixPresent) == 0) + expectWarning("QQuickShaderEffect: Missing reference to \'qt_Matrix\'."); + if ((presenceFlags & OpacityPresent) == 0) + expectWarning("QQuickShaderEffect: Missing reference to \'qt_Opacity\'."); + + static_cast(item).classBegin(); + item.setVertexShader(vertexShader); + item.setFragmentShader(fragmentShader); + static_cast(item).componentComplete(); + uninstallMsgHandler(); + + // If the uniform was successfully parsed, the notify signal has been connected to an update slot. + QCOMPARE(item.isConnected(SIGNAL(dummyChanged())), (presenceFlags & PropertyPresent) != 0); +} + +QTEST_MAIN(tst_qquickshadereffect) + +#include "tst_qquickshadereffect.moc" diff --git a/tests/auto/qtquick2/qquickspriteimage/data/basic.qml b/tests/auto/qtquick2/qquickspriteimage/data/basic.qml new file mode 100644 index 0000000000..1fcdfd99c3 --- /dev/null +++ b/tests/auto/qtquick2/qquickspriteimage/data/basic.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + color: "black" + width: 320 + height: 320 + + SpriteImage { + objectName: "sprite" + sprites: Sprite { + name: "happy" + source: "squarefacesprite.png" + frames: 6 + duration: 120 + } + width: 160 + height: 160 + } +} diff --git a/tests/auto/qtquick2/qquickspriteimage/data/squarefacesprite.png b/tests/auto/qtquick2/qquickspriteimage/data/squarefacesprite.png new file mode 100644 index 0000000000..f9a5d5fcce Binary files /dev/null and b/tests/auto/qtquick2/qquickspriteimage/data/squarefacesprite.png differ diff --git a/tests/auto/qtquick2/qquickspriteimage/qquickspriteimage.pro b/tests/auto/qtquick2/qquickspriteimage/qquickspriteimage.pro new file mode 100644 index 0000000000..fe788f5b7b --- /dev/null +++ b/tests/auto/qtquick2/qquickspriteimage/qquickspriteimage.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquickspriteimage +SOURCES += tst_qquickspriteimage.cpp +macx:CONFIG -= app_bundle + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private declarative-private quick-private network testlib diff --git a/tests/auto/qtquick2/qquickspriteimage/tst_qquickspriteimage.cpp b/tests/auto/qtquick2/qquickspriteimage/tst_qquickspriteimage.cpp new file mode 100644 index 0000000000..5c09019b03 --- /dev/null +++ b/tests/auto/qtquick2/qquickspriteimage/tst_qquickspriteimage.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include "../../shared/util.h" +#include +#include + +class tst_qquickspriteimage : public QObject +{ + Q_OBJECT +public: + tst_qquickspriteimage(){} + +private slots: + void test_properties(); +}; + +void tst_qquickspriteimage::test_properties() +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(QUrl::fromLocalFile(TESTDATA("basic.qml"))); + canvas->show(); + QTest::qWaitForWindowShown(canvas); + + QVERIFY(canvas->rootObject()); + QQuickSpriteImage* sprite = canvas->rootObject()->findChild("sprite"); + QVERIFY(sprite); + + QVERIFY(sprite->running()); + QVERIFY(sprite->interpolate()); + + sprite->setRunning(false); + QVERIFY(!sprite->running()); + sprite->setInterpolate(false); + QVERIFY(!sprite->interpolate()); + + delete canvas; +} + +QTEST_MAIN(tst_qquickspriteimage) + +#include "tst_qquickspriteimage.moc" diff --git a/tests/auto/qtquick2/qquicktext/data/alignments.qml b/tests/auto/qtquick2/qquicktext/data/alignments.qml new file mode 100644 index 0000000000..9798d9c736 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/alignments.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 70; height: 70; + + property alias horizontalAlignment: t.horizontalAlignment + property alias verticalAlignment: t.verticalAlignment + property alias wrapMode: t.wrapMode + property alias running: timer.running + property string txt: "Test" + + Rectangle { + anchors.centerIn: parent + width: 40 + height: 40 + color: "green" + + Text { + id: t + + anchors.fill: parent + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignBottom + wrapMode: Text.WordWrap + text: top.txt + } + Timer { + id: timer + + interval: 1 + running: true + repeat: true + onTriggered: { + top.txt = top.txt + "
more " + top.txt.length; + if (top.txt.length > 50) + running = false + } + } + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_cb.png b/tests/auto/qtquick2/qquicktext/data/alignments_cb.png new file mode 100644 index 0000000000..cf6199a418 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_cb.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_cc.png b/tests/auto/qtquick2/qquicktext/data/alignments_cc.png new file mode 100644 index 0000000000..f81ccb4238 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_cc.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_ct.png b/tests/auto/qtquick2/qquicktext/data/alignments_ct.png new file mode 100644 index 0000000000..9ba64125d5 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_ct.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_lb.png b/tests/auto/qtquick2/qquicktext/data/alignments_lb.png new file mode 100644 index 0000000000..1b50a81f3d Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_lb.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_lc.png b/tests/auto/qtquick2/qquicktext/data/alignments_lc.png new file mode 100644 index 0000000000..f041b868f8 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_lc.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_lt.png b/tests/auto/qtquick2/qquicktext/data/alignments_lt.png new file mode 100644 index 0000000000..c75e0d158e Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_lt.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_rb.png b/tests/auto/qtquick2/qquicktext/data/alignments_rb.png new file mode 100644 index 0000000000..b06a5da715 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_rb.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_rc.png b/tests/auto/qtquick2/qquicktext/data/alignments_rc.png new file mode 100644 index 0000000000..e468857cd0 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_rc.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/alignments_rt.png b/tests/auto/qtquick2/qquicktext/data/alignments_rt.png new file mode 100644 index 0000000000..576715ffce Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/alignments_rt.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocal.qml b/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocal.qml new file mode 100644 index 0000000000..74b2ab817a --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocal.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Text { + textFormat: Text.RichText + text: "" +} diff --git a/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocalError.qml b/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocalError.qml new file mode 100644 index 0000000000..a2f7e0c89f --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/embeddedImagesLocalError.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Text { + textFormat: Text.RichText + text: "" +} diff --git a/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemote.qml b/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemote.qml new file mode 100644 index 0000000000..702633c538 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemote.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Text { + textFormat: Text.RichText + text: "" +} diff --git a/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemoteError.qml b/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemoteError.qml new file mode 100644 index 0000000000..5762f3e47d --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/embeddedImagesRemoteError.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Text { + textFormat: Text.RichText + text: "" +} diff --git a/tests/auto/qtquick2/qquicktext/data/horizontalAlignment_RightToLeft.qml b/tests/auto/qtquick2/qquicktext/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000000..5ba4d35684 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,23 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 180 + height: 20 + color: "green" + + Text { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + } + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/http/exists.png b/tests/auto/qtquick2/qquicktext/data/http/exists.png new file mode 100644 index 0000000000..399bd0b1d9 Binary files /dev/null and b/tests/auto/qtquick2/qquicktext/data/http/exists.png differ diff --git a/tests/auto/qtquick2/qquicktext/data/lineCount.qml b/tests/auto/qtquick2/qquicktext/data/lineCount.qml new file mode 100644 index 0000000000..b672863684 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/lineCount.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 200 + wrapMode: Text.WordWrap + maximumLineCount: undefined + text: "Testing that maximumLines, visibleLines, and totalLines works properly in the autotests. The quick brown fox jumped over the lazy anything with the letter 'g'." + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/lineHeight.qml b/tests/auto/qtquick2/qquicktext/data/lineHeight.qml new file mode 100644 index 0000000000..c1f337aa05 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/lineHeight.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Item { + width: 200 + height: 200 + + Text { + id: myText + objectName: "myText" + width: 200 + wrapMode: Text.WordWrap + font.pixelSize: 13 + text: "Lorem ipsum sit amet, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum." + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/lineLayout.qml b/tests/auto/qtquick2/qquicktext/data/lineLayout.qml new file mode 100644 index 0000000000..cb2474791e --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/lineLayout.qml @@ -0,0 +1,35 @@ +import QtQuick 2.0 + +Rectangle { + id: main + width: 800; height: 600 + + property real off: 0 + + Text { + id: myText + objectName: "myText" + wrapMode: Text.WordWrap + font.pixelSize: 14 + textFormat: Text.StyledText + focus: true + + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at ante dui. Sed eu egestas est. +

Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Aenean ultricies lectus ut orci dictum quis convallis nisi ultrices. Nunc elit mi, iaculis a porttitor rutrum, venenatis malesuada nisi. Suspendisse turpis quam, euismod non imperdiet et, rutrum nec ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper tristique metus eu sodales. Integer eget risus ipsum. Quisque ut risus ut nulla tristique volutpat at sit amet nisl. Aliquam pulvinar auctor diam nec bibendum.

Quisque luctus sapien id arcu volutpat pharetra. Praesent pretium imperdiet euismod. Integer fringilla rhoncus condimentum. Quisque sit amet ornare nulla. Cras sapien augue, sagittis a dictum id, suscipit et nunc. Cras vitae augue in enim elementum venenatis sed nec risus. Sed nisi quam, mollis quis auctor ac, vestibulum in neque. Vivamus eu justo risus. Suspendisse vel mollis est. Vestibulum gravida interdum mi, in molestie neque gravida in. Donec nibh odio, mattis facilisis vulputate et, scelerisque ut felis. Sed ornare eros nec odio aliquam eu varius augue adipiscing. Vivamus sit amet massa dapibus sapien pulvinar consectetur a sit amet felis. Cras non mi id libero dictum iaculis id dignissim eros. Praesent eget enim dui, sed bibendum neque. Ut interdum nisl id leo malesuada ornare. Pellentesque id nisl eu odio volutpat posuere et at massa. Pellentesque nec lorem justo. Integer sem urna, pharetra sed sagittis vitae, condimentum ac felis. Ut vitae sapien ac tortor adipiscing pharetra. Cras tristique urna tempus ante volutpat eleifend non eu ligula. Mauris sodales nisl et lorem tristique sodales. Mauris arcu orci, vehicula semper cursus ac, dapibus ut mi." + + onLineLaidOut: { + line.width = line.number * 15 + if (line.number === 30 || line.number === 60) { + main.off = line.y + } + if (line.number >= 30) { + line.x = line.width + 30 + line.y -= main.off + } + if (line.number >= 60) { + line.x = line.width * 2 + 60 + line.height = 20 + } + } + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/multilineelide.qml b/tests/auto/qtquick2/qquicktext/data/multilineelide.qml new file mode 100644 index 0000000000..23398a84a1 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/multilineelide.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Text { + width: 200; height: 200 + wrapMode: Text.WordWrap + elide: Text.ElideRight + maximumLineCount: 3 + text: "the quick brown fox jumped over the lazy dog the quick brown fox jumped over the lazy dog" +} + diff --git a/tests/auto/qtquick2/qquicktext/data/qtbug_14734.qml b/tests/auto/qtquick2/qquicktext/data/qtbug_14734.qml new file mode 100644 index 0000000000..e71a798421 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/qtbug_14734.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +Rectangle { + width: 640 + height: 480 + + Text { + text: "í " + } +} diff --git a/tests/auto/qtquick2/qquicktext/data/rotated.qml b/tests/auto/qtquick2/qquicktext/data/rotated.qml new file mode 100644 index 0000000000..fecf64b249 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/data/rotated.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { + width : 200 + height : 100 + + Text { + objectName: "text" + x: 20 + y: 20 + height : 20 + width : 80 + text : "Something" + rotation : 30 + transformOrigin : Item.TopLeft + } +} + diff --git a/tests/auto/qtquick2/qquicktext/qquicktext.pro b/tests/auto/qtquick2/qquicktext/qquicktext.pro new file mode 100644 index 0000000000..e5bd50afc6 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/qquicktext.pro @@ -0,0 +1,17 @@ +CONFIG += testcase +TARGET = tst_qquicktext +macx:CONFIG -= app_bundle + +SOURCES += tst_qquicktext.cpp + +INCLUDEPATH += ../../shared/ +HEADERS += ../../shared/testhttpserver.h +SOURCES += ../../shared/testhttpserver.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private widgets-private opengl-private network testlib diff --git a/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp new file mode 100644 index 0000000000..60e8571a47 --- /dev/null +++ b/tests/auto/qtquick2/qquicktext/tst_qquicktext.cpp @@ -0,0 +1,1460 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include "testhttpserver.h" + +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + +class tst_qquicktext : public QObject +{ + Q_OBJECT +public: + tst_qquicktext(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void text(); + void width(); + void wrap(); + void elide(); + void multilineElide(); + void textFormat(); + + void alignments_data(); + void alignments(); + + void embeddedImages_data(); + void embeddedImages(); + + void lineCount(); + void lineHeight(); + + // ### these tests may be trivial + void horizontalAlignment(); + void horizontalAlignment_RightToLeft(); + void verticalAlignment(); + void font(); + void style(); + void color(); + void smooth(); + + // QDeclarativeFontValueType + void weight(); + void underline(); + void overline(); + void strikeout(); + void capitalization(); + void letterSpacing(); + void wordSpacing(); + + void clickLink(); + + void implicitSize_data(); + void implicitSize(); + + void lineLaidOut(); + + +private: + QStringList standard; + QStringList richText; + + QStringList horizontalAlignmentmentStrings; + QStringList verticalAlignmentmentStrings; + + QList verticalAlignmentments; + QList horizontalAlignmentments; + + QStringList styleStrings; + QList styles; + + QStringList colorStrings; + + QDeclarativeEngine engine; + + QQuickView *createView(const QString &filename); +}; +void tst_qquicktext::initTestCase() +{ +} + +void tst_qquicktext::cleanupTestCase() +{ + +} +tst_qquicktext::tst_qquicktext() +{ + standard << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox\n jumped over the lazy dog"; + + richText << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox
jumped over the lazy dog
"; + + horizontalAlignmentmentStrings << "AlignLeft" + << "AlignRight" + << "AlignHCenter"; + + verticalAlignmentmentStrings << "AlignTop" + << "AlignBottom" + << "AlignVCenter"; + + horizontalAlignmentments << Qt::AlignLeft + << Qt::AlignRight + << Qt::AlignHCenter; + + verticalAlignmentments << Qt::AlignTop + << Qt::AlignBottom + << Qt::AlignVCenter; + + styleStrings << "Normal" + << "Outline" + << "Raised" + << "Sunken"; + + styles << QQuickText::Normal + << QQuickText::Outline + << QQuickText::Raised + << QQuickText::Sunken; + + colorStrings << "aliceblue" + << "antiquewhite" + << "aqua" + << "darkkhaki" + << "darkolivegreen" + << "dimgray" + << "palevioletred" + << "lightsteelblue" + << "#000000" + << "#AAAAAA" + << "#FFFFFF" + << "#2AC05F"; + // + // need a different test to do alpha channel test + // << "#AA0011DD" + // << "#00F16B11"; + // +} + +QQuickView *tst_qquicktext::createView(const QString &filename) +{ + QQuickView *canvas = new QQuickView(0); + + canvas->setSource(QUrl::fromLocalFile(filename)); + return canvas; +} + +void tst_qquicktext::text() +{ + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->text(), QString("")); + QVERIFY(textObject->width() == 0); + + delete textObject; + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->text(), standard.at(i)); + QVERIFY(textObject->width() > 0); + + delete textObject; + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QString expected = richText.at(i); + QCOMPARE(textObject->text(), expected.replace("\\\"", "\"")); + QVERIFY(textObject->width() > 0); + + delete textObject; + } +} + +void tst_qquicktext::width() +{ + // uses Font metrics to find the width for standard and document to find the width for rich + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->width(), 0.); + + delete textObject; + } + + bool requiresUnhintedMetrics = !qmlDisableDistanceField(); + + for (int i = 0; i < standard.size(); i++) + { + QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test + + QFont f; + qreal metricWidth = 0.0; + + if (requiresUnhintedMetrics) { + QString s = standard.at(i); + s.replace(QLatin1Char('\n'), QChar::LineSeparator); + + QTextLayout layout(s); + layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); + { + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + } + + layout.beginLayout(); + forever { + QTextLine line = layout.createLine(); + if (!line.isValid()) + break; + } + + layout.endLayout(); + + metricWidth = qCeil(layout.boundingRect().width()); + } else { + QFontMetricsF fm(f); + qreal metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width(); + metricWidth = qCeil(metricWidth); + } + + QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->boundingRect().width() > 0); + QCOMPARE(textObject->width(), qreal(metricWidth)); + QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format + + delete textObject; + } + + for (int i = 0; i < richText.size(); i++) + { + QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test + + QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QVERIFY(textObject != 0); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); + QVERIFY(textPrivate != 0); + + QTextDocument *doc = textPrivate->textDocument(); + QVERIFY(doc != 0); + + QCOMPARE(int(textObject->width()), int(doc->idealWidth())); + QVERIFY(textObject->textFormat() == QQuickText::RichText); + + delete textObject; + } +} + +void tst_qquicktext::wrap() +{ + int textHeight = 0; + // for specified width and wrap set true + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + textHeight = textObject->height(); + + QVERIFY(textObject != 0); + QVERIFY(textObject->wrapMode() == QQuickText::WordWrap); + QCOMPARE(textObject->width(), 300.); + + delete textObject; + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->width(), 30.); + QVERIFY(textObject->height() > textHeight); + + int oldHeight = textObject->height(); + textObject->setWidth(100); + QVERIFY(textObject->height() < oldHeight); + + delete textObject; + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->width(), 30.); + QVERIFY(textObject->height() > textHeight); + + qreal oldHeight = textObject->height(); + textObject->setWidth(100); + QVERIFY(textObject->height() < oldHeight); + + delete textObject; + } + + // richtext again with a fixed height + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->width(), 30.); + QVERIFY(textObject->implicitHeight() > textHeight); + + qreal oldHeight = textObject->implicitHeight(); + textObject->setWidth(100); + QVERIFY(textObject->implicitHeight() < oldHeight); + + delete textObject; + } +} + +void tst_qquicktext::elide() +{ + for (QQuickText::TextElideMode m = QQuickText::ElideLeft; m<=QQuickText::ElideNone; m=QQuickText::TextElideMode(int(m)+1)) { + const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"}; + QString elide = "elide: Text." + QString(elidename[int(m)]) + ";"; + + // XXX Poor coverage. + + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->elideMode(), m); + QCOMPARE(textObject->width(), 100.); + + delete textObject; + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->elideMode(), m); + QCOMPARE(textObject->width(), 100.); + + delete textObject; + } + + // richtext - does nothing + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->elideMode(), m); + QCOMPARE(textObject->width(), 100.); + + delete textObject; + } + } +} + +void tst_qquicktext::multilineElide() +{ + QQuickView *canvas = createView(TESTDATA("multilineelide.qml")); + + QQuickText *myText = qobject_cast(canvas->rootObject()); + QVERIFY(myText != 0); + + QCOMPARE(myText->lineCount(), 3); + QCOMPARE(myText->truncated(), true); + + qreal lineHeight = myText->paintedHeight() / 3.; + + // reduce size and ensure fewer lines are drawn + myText->setHeight(lineHeight * 2); + QCOMPARE(myText->lineCount(), 2); + + myText->setHeight(lineHeight); + QCOMPARE(myText->lineCount(), 1); + + myText->setHeight(5); + QCOMPARE(myText->lineCount(), 1); + + myText->setHeight(lineHeight * 3); + QCOMPARE(myText->lineCount(), 3); + + // remove max count and show all lines. + myText->setHeight(1000); + myText->resetMaximumLineCount(); + + QCOMPARE(myText->truncated(), false); + + // reduce size again + myText->setHeight(lineHeight * 2); + QCOMPARE(myText->lineCount(), 2); + QCOMPARE(myText->truncated(), true); + + // change line height + myText->setLineHeight(1.1); + QCOMPARE(myText->lineCount(), 1); + + delete canvas; +} + +void tst_qquicktext::textFormat() +{ + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->textFormat() == QQuickText::RichText); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); + QVERIFY(textPrivate != 0); + QVERIFY(textPrivate->richText == true); + + delete textObject; + } + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\" }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->textFormat() == QQuickText::AutoText); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); + QVERIFY(textPrivate != 0); + QVERIFY(textPrivate->styledText == true); + + delete textObject; + } + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.PlainText }", QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->textFormat() == QQuickText::PlainText); + + delete textObject; + } +} + + +void tst_qquicktext::alignments_data() +{ + QTest::addColumn("hAlign"); + QTest::addColumn("vAlign"); + QTest::addColumn("expectfile"); + + QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << TESTDATA("alignments_lt.png"); + QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << TESTDATA("alignments_rt.png"); + QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << TESTDATA("alignments_ct.png"); + + QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << TESTDATA("alignments_lb.png"); + QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << TESTDATA("alignments_rb.png"); + QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << TESTDATA("alignments_cb.png"); + + QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << TESTDATA("alignments_lc.png"); + QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << TESTDATA("alignments_rc.png"); + QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << TESTDATA("alignments_cc.png"); +} + + +void tst_qquicktext::alignments() +{ + QSKIP("Text alignment pixmap comparison tests will not work with scenegraph"); +#if (0)// No widgets in scenegraph + QFETCH(int, hAlign); + QFETCH(int, vAlign); + QFETCH(QString, expectfile); + + QQuickView *canvas = createView(TESTDATA("alignments.qml")); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWait(50); + QTRY_COMPARE(QApplication::activeWindow(), static_cast(canvas)); + + QObject *ob = canvas->rootObject(); + QVERIFY(ob != 0); + ob->setProperty("horizontalAlignment",hAlign); + ob->setProperty("verticalAlignment",vAlign); + QTRY_COMPARE(ob->property("running").toBool(),false); + QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32); + actual.fill(qRgb(255,255,255)); + QPainter p(&actual); + canvas->render(&p); + + QImage expect(expectfile); + if (QApplicationPrivate::graphics_system_name == "raster" || QApplicationPrivate::graphics_system_name == "") { + QCOMPARE(actual,expect); + } + delete canvas; +#endif +} + +//the alignment tests may be trivial o.oa +void tst_qquicktext::horizontalAlignment() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < horizontalAlignmentmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); + + delete textObject; + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < horizontalAlignmentmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j)); + + delete textObject; + } + } + +} + +void tst_qquicktext::horizontalAlignment_RightToLeft() +{ + QQuickView *canvas = createView(TESTDATA("horizontalAlignment_RightToLeft.qml")); + QQuickText *text = canvas->rootObject()->findChild("text"); + QVERIFY(text != 0); + canvas->show(); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text); + QVERIFY(textPrivate != 0); + + // implicit alignment should follow the reading direction of RTL text + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); + + // explicitly left aligned text + text->setHAlign(QQuickText::AlignLeft); + QCOMPARE(text->hAlign(), QQuickText::AlignLeft); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); + + // explicitly right aligned text + text->setHAlign(QQuickText::AlignRight); + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); + + // change to rich text + QString textString = text->text(); + text->setText(QString("") + textString + QString("")); + text->setTextFormat(QQuickText::RichText); + text->resetHAlign(); + + // implicitly aligned rich text should follow the reading direction of text + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); + + // explicitly left aligned rich text + text->setHAlign(QQuickText::AlignLeft); + QCOMPARE(text->hAlign(), QQuickText::AlignLeft); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignRight); + + // explicitly right aligned rich text + text->setHAlign(QQuickText::AlignRight); + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->textDocument()->defaultTextOption().alignment() & Qt::AlignLeft); + + text->setText(textString); + text->setTextFormat(QQuickText::PlainText); + + // explicitly center aligned + text->setHAlign(QQuickText::AlignHCenter); + QCOMPARE(text->hAlign(), QQuickText::AlignHCenter); + QCOMPARE(text->effectiveHAlign(), text->hAlign()); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2); + + // reseted alignment should go back to following the text reading direction + text->resetHAlign(); + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); + + // mirror the text item + QQuickItemPrivate::get(text)->setLayoutMirror(true); + + // mirrored implicit alignment should continue to follow the reading direction of the text + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); + + // mirrored explicitly right aligned behaves as left aligned + text->setHAlign(QQuickText::AlignRight); + QCOMPARE(text->hAlign(), QQuickText::AlignRight); + QCOMPARE(text->effectiveHAlign(), QQuickText::AlignLeft); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); + + // mirrored explicitly left aligned behaves as right aligned + text->setHAlign(QQuickText::AlignLeft); + QCOMPARE(text->hAlign(), QQuickText::AlignLeft); + QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2); + + // disable mirroring + QQuickItemPrivate::get(text)->setLayoutMirror(false); + text->resetHAlign(); + + // English text should be implicitly left aligned + text->setText("Hello world!"); + QCOMPARE(text->hAlign(), QQuickText::AlignLeft); + QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2); + +#ifndef Q_OS_MAC // QTBUG-18040 + // empty text with implicit alignment follows the system locale-based + // keyboard input direction from QApplication::keyboardInputDirection + text->setText(""); + QCOMPARE(text->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickText::AlignLeft : QQuickText::AlignRight); + text->setHAlign(QQuickText::AlignRight); + QCOMPARE(text->hAlign(), QQuickText::AlignRight); +#endif + + delete canvas; + +#ifndef Q_OS_MAC // QTBUG-18040 + // alignment of Text with no text set to it + QString componentStr = "import QtQuick 2.0\nText {}"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->hAlign(), QApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickText::AlignLeft : QQuickText::AlignRight); + delete textObject; +#endif +} + +void tst_qquicktext::verticalAlignment() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < verticalAlignmentmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); + + delete textObject; + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < verticalAlignmentmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j)); + + delete textObject; + } + } + +} + +void tst_qquicktext::font() +{ + //test size, then bold, then italic, then family + { + QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().pointSize(), 40); + QCOMPARE(textObject->font().bold(), false); + QCOMPARE(textObject->font().italic(), false); + + delete textObject; + } + + { + QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().pixelSize(), 40); + QCOMPARE(textObject->font().bold(), false); + QCOMPARE(textObject->font().italic(), false); + + delete textObject; + } + + { + QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().bold(), true); + QCOMPARE(textObject->font().italic(), false); + + delete textObject; + } + + { + QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().italic(), true); + QCOMPARE(textObject->font().bold(), false); + + delete textObject; + } + + { + QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().family(), QString("Helvetica")); + QCOMPARE(textObject->font().bold(), false); + QCOMPARE(textObject->font().italic(), false); + + delete textObject; + } + + { + QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->font().family(), QString("")); + + delete textObject; + } +} + +void tst_qquicktext::style() +{ + //test style + for (int i = 0; i < styles.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE((int)textObject->style(), (int)styles.at(i)); + QCOMPARE(textObject->styleColor(), QColor("white")); + + delete textObject; + } + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QRectF brPre = textObject->boundingRect(); + textObject->setStyle(QQuickText::Outline); + QRectF brPost = textObject->boundingRect(); + + QVERIFY(brPre.width() < brPost.width()); + QVERIFY(brPre.height() < brPost.height()); + + delete textObject; +} + +void tst_qquicktext::color() +{ + //test style + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); + QCOMPARE(textObject->styleColor(), QColor()); + + delete textObject; + } + + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i))); + // default color to black? + QCOMPARE(textObject->color(), QColor("black")); + + delete textObject; + } + + for (int i = 0; i < colorStrings.size(); i++) + { + for (int j = 0; j < colorStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; styleColor: \"" + colorStrings.at(j) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->color(), QColor(colorStrings.at(i))); + QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j))); + + delete textObject; + } + } + { + QString colorStr = "#AA001234"; + QColor testColor("#001234"); + testColor.setAlpha(170); + + QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QCOMPARE(textObject->color(), testColor); + + delete textObject; + } +} + +void tst_qquicktext::smooth() +{ + for (int i = 0; i < standard.size(); i++) + { + { + QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->smooth(), true); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->smooth(), false); + + delete textObject; + } + } + for (int i = 0; i < richText.size(); i++) + { + { + QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->smooth(), true); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->smooth(), false); + + delete textObject; + } + } +} + +void tst_qquicktext::weight() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Normal); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().weight(), (int)QDeclarativeFontValueType::Bold); + + delete textObject; + } +} + +void tst_qquicktext::underline() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().underline(), false); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().underline(), true); + + delete textObject; + } +} + +void tst_qquicktext::overline() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().overline(), false); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().overline(), true); + + delete textObject; + } +} + +void tst_qquicktext::strikeout() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().strikeOut(), false); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().strikeOut(), true); + + delete textObject; + } +} + +void tst_qquicktext::capitalization() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::MixedCase); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllUppercase); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::AllLowercase); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::SmallCaps); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE((int)textObject->font().capitalization(), (int)QDeclarativeFontValueType::Capitalize); + + delete textObject; + } +} + +void tst_qquicktext::letterSpacing() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().letterSpacing(), 0.0); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().letterSpacing(), -2.); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().letterSpacing(), 3.); + + delete textObject; + } +} + +void tst_qquicktext::wordSpacing() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().wordSpacing(), 0.0); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().wordSpacing(), -50.); + + delete textObject; + } + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QCOMPARE(textObject->font().wordSpacing(), 200.); + + delete textObject; + } +} + + + + +class EventSender : public QQuickItem +{ +public: + void sendEvent(QMouseEvent *event) { + if (event->type() == QEvent::MouseButtonPress) + mousePressEvent(event); + else if (event->type() == QEvent::MouseButtonRelease) + mouseReleaseEvent(event); + else + qWarning() << "Trying to send unsupported event type"; + } +}; + +class LinkTest : public QObject +{ + Q_OBJECT +public: + LinkTest() {} + + QString link; + +public slots: + void linkClicked(QString l) { link = l; } +}; + +void tst_qquicktext::clickLink() +{ + { + QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + + LinkTest test; + QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString))); + + { + QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + static_cast(static_cast(textObject))->sendEvent(&me); + + } + + { + QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + static_cast(static_cast(textObject))->sendEvent(&me); + + } + + + QCOMPARE(test.link, QLatin1String("http://qt.nokia.com")); + + delete textObject; + } +} + +void tst_qquicktext::embeddedImages_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("error"); + QTest::newRow("local") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocal.qml")) << ""; + QTest::newRow("local-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml")) + << QUrl::fromLocalFile(TESTDATA("embeddedImagesLocalError.qml")).toString()+":3:1: QML Text: Cannot open: " + QUrl::fromLocalFile(TESTDATA("http/notexists.png")).toString(); + QTest::newRow("remote") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemote.qml")) << ""; + QTest::newRow("remote-error") << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml")) + << QUrl::fromLocalFile(TESTDATA("embeddedImagesRemoteError.qml")).toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found"; +} + +void tst_qquicktext::embeddedImages() +{ + // Tests QTBUG-9900 + + QFETCH(QUrl, qmlfile); + QFETCH(QString, error); + + TestHTTPServer server(14453); + server.serveDirectory(TESTDATA("http")); + + if (!error.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, error.toLatin1()); + + QDeclarativeComponent textComponent(&engine, qmlfile); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + + QTRY_COMPARE(textObject->resourcesLoading(), 0); + + QPixmap pm(TESTDATA("http/exists.png")); + if (error.isEmpty()) { + QCOMPARE(textObject->width(), double(pm.width())); + QCOMPARE(textObject->height(), double(pm.height())); + } else { + QVERIFY(16 != pm.width()); // check test is effective + QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon + QCOMPARE(textObject->height(), 16.0); + } + + delete textObject; +} + +void tst_qquicktext::lineCount() +{ + QQuickView *canvas = createView(TESTDATA("lineCount.qml")); + + QQuickText *myText = canvas->rootObject()->findChild("myText"); + QVERIFY(myText != 0); + + QVERIFY(myText->lineCount() > 1); + QVERIFY(!myText->truncated()); + QCOMPARE(myText->maximumLineCount(), INT_MAX); + + myText->setMaximumLineCount(2); + QCOMPARE(myText->lineCount(), 2); + QCOMPARE(myText->truncated(), true); + QCOMPARE(myText->maximumLineCount(), 2); + + myText->resetMaximumLineCount(); + QCOMPARE(myText->maximumLineCount(), INT_MAX); + QCOMPARE(myText->truncated(), false); + + myText->setElideMode(QQuickText::ElideRight); + myText->setMaximumLineCount(2); + QCOMPARE(myText->lineCount(), 2); + QCOMPARE(myText->truncated(), true); + QCOMPARE(myText->maximumLineCount(), 2); + + delete canvas; +} + +void tst_qquicktext::lineHeight() +{ + QQuickView *canvas = createView(TESTDATA("lineHeight.qml")); + + QQuickText *myText = canvas->rootObject()->findChild("myText"); + QVERIFY(myText != 0); + + QVERIFY(myText->lineHeight() == 1); + QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight); + + qreal h = myText->height(); + myText->setLineHeight(1.5); + QVERIFY(myText->height() == qCeil(h * 1.5)); + + myText->setLineHeightMode(QQuickText::FixedHeight); + myText->setLineHeight(20); + QCOMPARE(myText->height(), myText->lineCount() * 20.0); + + myText->setText("Lorem ipsum sit amet, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum."); + myText->setLineHeightMode(QQuickText::ProportionalHeight); + myText->setLineHeight(1.0); + + qreal h2 = myText->height(); + myText->setLineHeight(2.0); + QVERIFY(myText->height() == h2 * 2.0); + + myText->setLineHeightMode(QQuickText::FixedHeight); + myText->setLineHeight(10); + QCOMPARE(myText->height(), myText->lineCount() * 10.0); + + delete canvas; +} + +void tst_qquicktext::implicitSize_data() +{ + QTest::addColumn("text"); + QTest::addColumn("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap"; + QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "Text.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap"; + QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "Text.Wrap"; +} + +void tst_qquicktext::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickText *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + delete textObject; +} + +void tst_qquicktext::lineLaidOut() +{ + QQuickView *canvas = createView(TESTDATA("lineLayout.qml")); + + QQuickText *myText = canvas->rootObject()->findChild("myText"); + QVERIFY(myText != 0); + + QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); + QVERIFY(textPrivate != 0); + + QTextDocument *doc = textPrivate->textDocument(); + QVERIFY(doc == 0); + + QVERIFY(myText->lineCount() == textPrivate->linesRects.count()); + + for (int i = 0; i < textPrivate->linesRects.count(); ++i) { + QRectF r = textPrivate->linesRects.at(i); + QVERIFY(r.width() == i * 15); + if (i >= 30) + QVERIFY(r.x() == r.width() + 30); + if (i >= 60) { + QVERIFY(r.x() == r.width() * 2 + 60); + QVERIFY(r.height() == 20); + } + } +} + +QTEST_MAIN(tst_qquicktext) + +#include "tst_qquicktext.moc" diff --git a/tests/auto/qtquick2/qquicktextedit/data/CursorRect.qml b/tests/auto/qtquick2/qquicktextedit/data/CursorRect.qml new file mode 100644 index 0000000000..cae3e63b72 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/CursorRect.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + objectName: "myEdit" + width: 50 + text: "This is a long piece of text" +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments.qml b/tests/auto/qtquick2/qquicktextedit/data/alignments.qml new file mode 100644 index 0000000000..7d365da8cb --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/alignments.qml @@ -0,0 +1,41 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 70; height: 70; + + property alias horizontalAlignment: t.horizontalAlignment + property alias verticalAlignment: t.verticalAlignment + property alias wrapMode: t.wrapMode + property alias running: timer.running + property string txt: "Test" + + Rectangle { + anchors.centerIn: parent + width: 40 + height: 40 + color: "green" + + TextEdit { + id: t + + anchors.fill: parent + horizontalAlignment: TextEdit.AlignRight + verticalAlignment: TextEdit.AlignBottom + wrapMode: TextEdit.WordWrap + text: top.txt + } + Timer { + id: timer + + interval: 1 + running: true + repeat: true + onTriggered: { + top.txt = top.txt + "
more " + top.txt.length; + if (top.txt.length > 50) + running = false + } + } + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_cb.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_cb.png new file mode 100644 index 0000000000..99de2192de Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_cb.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_cc.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_cc.png new file mode 100644 index 0000000000..cb85251180 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_cc.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_ct.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_ct.png new file mode 100644 index 0000000000..ddca549c82 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_ct.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_lb.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_lb.png new file mode 100644 index 0000000000..1b50a81f3d Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_lb.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_lc.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_lc.png new file mode 100644 index 0000000000..f041b868f8 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_lc.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_lt.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_lt.png new file mode 100644 index 0000000000..c75e0d158e Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_lt.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_rb.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_rb.png new file mode 100644 index 0000000000..b06a5da715 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_rb.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_rc.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_rc.png new file mode 100644 index 0000000000..e468857cd0 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_rc.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/alignments_rt.png b/tests/auto/qtquick2/qquicktextedit/data/alignments_rt.png new file mode 100644 index 0000000000..576715ffce Binary files /dev/null and b/tests/auto/qtquick2/qquicktextedit/data/alignments_rt.png differ diff --git a/tests/auto/qtquick2/qquicktextedit/data/cursorTest.qml b/tests/auto/qtquick2/qquicktextedit/data/cursorTest.qml new file mode 100644 index 0000000000..7bfc869403 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/cursorTest.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Rectangle { width: 300; height: 300; color: "white" + property string contextualProperty: "Hello" + TextEdit { text: "Hello world!"; id: textEditObject; objectName: "textEditObject" + resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ] + cursorDelegate: cursor + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/cursorVisible.qml b/tests/auto/qtquick2/qquicktextedit/data/cursorVisible.qml new file mode 100644 index 0000000000..49e9386947 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/cursorVisible.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + width: 100 + height: 20 +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/geometrySignals.qml b/tests/auto/qtquick2/qquicktextedit/data/geometrySignals.qml new file mode 100644 index 0000000000..3dbe61c74b --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/geometrySignals.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + width: 400; height: 500; + property int bindingWidth: text.width + property int bindingHeight: text.height + + TextInput { + id: text + anchors.fill: parent + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/horizontalAlignment_RightToLeft.qml b/tests/auto/qtquick2/qquicktextedit/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000000..4cd92367ec --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 200 + height: 20 + color: "green" + + TextEdit { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + focus: true + } + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/ErrItem.qml b/tests/auto/qtquick2/qquicktextedit/data/http/ErrItem.qml new file mode 100644 index 0000000000..68c0e0c093 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/ErrItem.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +Item{ + Fungus{ + palatable: false; + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/NormItem.qml b/tests/auto/qtquick2/qquicktextedit/data/http/NormItem.qml new file mode 100644 index 0000000000..2e4c1ed440 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/NormItem.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + objectName: "delegateOkay" + Rectangle { } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTest.qml b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTest.qml new file mode 100644 index 0000000000..be4526e22b --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTest.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Rectangle { width: 300; height: 300; color: "white" + resources: [ + Component { id:cursorFail; FailItem { objectName: "delegateFail" } }, + Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, + Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } }, + Component { id:cursorErr; ErrItem { objectName: "delegateErrorA" } } + ] + TextEdit { + cursorDelegate: cursorFail + } + TextEdit { + cursorDelegate: cursorWait + } + TextEdit { + cursorDelegate: cursorNorm + } + TextEdit { + cursorDelegate: cursorErr + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail1.qml b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail1.qml new file mode 100644 index 0000000000..1d7763f913 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail1.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { width: 300; height: 300; color: "white" + resources: [ + Component { id:cursorFail; FailItem { objectName: "delegateFail" } }, + Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, + Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } } + ] + TextEdit { + cursorDelegate: cursorFail + } + TextEdit { + cursorDelegate: cursorWait + } + TextEdit { + cursorDelegate: cursorNorm + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail2.qml b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail2.qml new file mode 100644 index 0000000000..c82ec02e68 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestFail2.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { width: 300; height: 300; color: "white" + resources: [ + Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, + Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } }, + Component { id:cursorErr; ErrItem { objectName: "delegateErrorA" } } + ] + TextEdit { + cursorDelegate: cursorWait + } + TextEdit { + cursorDelegate: cursorNorm + } + TextEdit { + cursorDelegate: cursorErr + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestPass.qml b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestPass.qml new file mode 100644 index 0000000000..96d582c95d --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/cursorHttpTestPass.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +Rectangle { width: 300; height: 300; color: "white" + resources: [ + Component { id:cursorWait; WaitItem { objectName: "delegateSlow" } }, + Component { id:cursorNorm; NormItem { objectName: "delegateOkay" } } + ] + TextEdit { + cursorDelegate: cursorWait + text: "Hello" + } + TextEdit { + objectName: "textEditObject" + cursorDelegate: cursorNorm + focus: true; + text: "Hello" + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/http/qmldir b/tests/auto/qtquick2/qquicktextedit/data/http/qmldir new file mode 100644 index 0000000000..886e6ffec0 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/http/qmldir @@ -0,0 +1,4 @@ +ErrItem ErrItem.qml +NormItem NormItem.qml +FailItem FailItem.qml +WaitItem WaitItem.qml diff --git a/tests/auto/qtquick2/qquicktextedit/data/httpfail/FailItem.qml b/tests/auto/qtquick2/qquicktextedit/data/httpfail/FailItem.qml new file mode 100644 index 0000000000..8161843479 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/httpfail/FailItem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + Rectangle { } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/httpslow/WaitItem.qml b/tests/auto/qtquick2/qquicktextedit/data/httpslow/WaitItem.qml new file mode 100644 index 0000000000..8161843479 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/httpslow/WaitItem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Item { + Rectangle { } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/inputContext.qml b/tests/auto/qtquick2/qquicktextedit/data/inputContext.qml new file mode 100644 index 0000000000..a37c77e3bf --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/inputContext.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + width: 200 + text: "supercalifra" + focus: true +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/inputMethodEvent.qml b/tests/auto/qtquick2/qquicktextedit/data/inputMethodEvent.qml new file mode 100644 index 0000000000..e3f629ce3e --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/inputMethodEvent.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +TextEdit { + focus: true +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/inputmethodhints.qml b/tests/auto/qtquick2/qquicktextedit/data/inputmethodhints.qml new file mode 100644 index 0000000000..dec3b978e7 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/inputmethodhints.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +TextEdit { + text: "Hello world!" + inputMethodHints: Qt.ImhNoPredictiveText +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselection_default.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_default.qml new file mode 100644 index 0000000000..ac32f4ced7 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_default.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false.qml new file mode 100644 index 0000000000..ac32f4ced7 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false_words.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false_words.qml new file mode 100644 index 0000000000..86aea46a85 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_false_words.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false + mouseSelectionMode: TextEdit.SelectWords +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true.qml new file mode 100644 index 0000000000..7c7cb0b6fc --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true_words.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true_words.qml new file mode 100644 index 0000000000..c356999220 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselection_true_words.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectWords +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_characters.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000000..c1fe42fd57 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectCharacters +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_default.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_default.qml new file mode 100644 index 0000000000..7c7cb0b6fc --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_words.qml b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_words.qml new file mode 100644 index 0000000000..0a372bbf83 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextEdit.SelectWords +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/navigation.qml b/tests/auto/qtquick2/qquicktextedit/data/navigation.qml new file mode 100644 index 0000000000..0201c62b3c --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/navigation.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + property variant myInput: input + + width: 800; height: 600; color: "blue" + + Item { + id: firstItem; + KeyNavigation.right: input + } + + TextEdit { id: input; focus: true + KeyNavigation.left: firstItem + KeyNavigation.right: lastItem + KeyNavigation.up: firstItem + KeyNavigation.down: lastItem + text: "a" + } + Item { + id: lastItem + KeyNavigation.left: input + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/openInputPanel.qml b/tests/auto/qtquick2/qquicktextedit/data/openInputPanel.qml new file mode 100644 index 0000000000..d3aecf21be --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/openInputPanel.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextEdit { + width: 100; height: 100 + text: "Hello world" + focus: false +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/positionAt.qml b/tests/auto/qtquick2/qquicktextedit/data/positionAt.qml new file mode 100644 index 0000000000..19093281fe --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/positionAt.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +TextEdit { + focus: true + objectName: "myInput" + width: 50 + height: 25 + text: "This is\n a long piece of text" +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/qtbug-22058.qml b/tests/auto/qtquick2/qquicktextedit/data/qtbug-22058.qml new file mode 100644 index 0000000000..8ad1514fbf --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/qtbug-22058.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 + +Rectangle { + property variant inputField: textedit + height: 200 + width: 200 + + Rectangle { + height: parent.height /2 + width: parent.width + color: "transparent" + border.color: "black" + border.width: 4 + Text { + anchors.centerIn: parent + height: parent.height * .95 + width: parent.width * .95 + text: textedit.text + } + } + + Rectangle { + height: parent.height /2 + width: parent.width + color: "transparent" + border.color: "black" + border.width: 4 + anchors.bottom: parent.bottom + TextEdit { + id: textedit + anchors.centerIn: parent + height: parent.height * .95 + width: parent.width * .95 + focus: true + wrapMode: TextEdit.WordWrap + text: "" + } + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/data/readOnly.qml b/tests/auto/qtquick2/qquicktextedit/data/readOnly.qml new file mode 100644 index 0000000000..085adba5fb --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/data/readOnly.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + property variant myInput: input + + width: 800; height: 600; color: "blue" + + TextEdit { id: input; focus: true + readOnly: true + text: "I am the very model of a modern major general.\n" + } +} diff --git a/tests/auto/qtquick2/qquicktextedit/qquicktextedit.pro b/tests/auto/qtquick2/qquicktextedit/qquicktextedit.pro new file mode 100644 index 0000000000..02a834beab --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/qquicktextedit.pro @@ -0,0 +1,12 @@ +CONFIG += testcase +TARGET = tst_qquicktextedit +macx:CONFIG -= app_bundle + +SOURCES += tst_qquicktextedit.cpp ../../shared/testhttpserver.cpp +HEADERS += ../../shared/testhttpserver.h + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +QT += core-private gui-private v8-private declarative-private quick-private opengl-private network widgets-private testlib diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp new file mode 100644 index 0000000000..97d7531321 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp @@ -0,0 +1,3555 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include "../../shared/testhttpserver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include +#include + +#ifdef Q_OS_MAC +#include +#endif + + +Q_DECLARE_METATYPE(QQuickTextEdit::SelectionMode) +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + +QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) +{ + // XXX This will be replaced by some clever persistent platform image store. + QString persistent_dir = TESTDATA(""); + QString arch = "unknown-architecture"; // QTest needs to help with this. + + QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; + + if (!QFile::exists(expectfile)) { + actual.save(expectfile); + qWarning() << "created" << expectfile; + } + + return expectfile; +} + +typedef QPair Key; + +class tst_qquicktextedit : public QObject + +{ + Q_OBJECT +public: + tst_qquicktextedit(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void text(); + void width(); + void wrap(); + void textFormat(); + void alignments(); + void alignments_data(); + + // ### these tests may be trivial + void hAlign(); + void hAlign_RightToLeft(); + void vAlign(); + void font(); + void color(); + void textMargin(); + void persistentSelection(); + void focusOnPress(); + void selection(); + void isRightToLeft_data(); + void isRightToLeft(); + void keySelection(); + void moveCursorSelection_data(); + void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); + void mouseSelection_data(); + void mouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); + void dragMouseSelection(); + void inputMethodHints(); + + void positionAt(); + + void cursorDelegate(); + void cursorVisible(); + void delegateLoading_data(); + void delegateLoading(); + void navigation(); + void readOnly(); + void copyAndPaste(); + void canPaste(); + void canPasteEmpty(); + void textInput(); + void openInputPanel(); + void geometrySignals(); + void pastingRichText_QTBUG_14003(); + void implicitSize_data(); + void implicitSize(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + + void preeditCursorRectangle(); + void inputMethodComposing(); + void cursorRectangleSize(); + + void getText_data(); + void getText(); + void getFormattedText_data(); + void getFormattedText(); + void insert_data(); + void insert(); + void remove_data(); + void remove(); + + void keySequence_data(); + void keySequence(); + + void undo_data(); + void undo(); + void redo_data(); + void redo(); + void undo_keypressevents_data(); + void undo_keypressevents(); + + void emptytags_QTBUG_22058(); + +private: + void simulateKeys(QWindow *window, const QList &keys); + void simulateKeys(QWindow *window, const QKeySequence &sequence); + + void simulateKey(QQuickView *, int key, Qt::KeyboardModifiers modifiers = 0); + + QStringList standard; + QStringList richText; + + QStringList hAlignmentStrings; + QStringList vAlignmentStrings; + + QList vAlignments; + QList hAlignments; + + QStringList colorStrings; + + QDeclarativeEngine engine; +}; + +typedef QList IntList; +Q_DECLARE_METATYPE(IntList) + +typedef QList KeyList; +Q_DECLARE_METATYPE(KeyList) + +Q_DECLARE_METATYPE(QQuickTextEdit::TextFormat) + +void tst_qquicktextedit::simulateKeys(QWindow *window, const QList &keys) +{ + for (int i = 0; i < keys.count(); ++i) { + const int key = keys.at(i).first; + const int modifiers = key & Qt::KeyboardModifierMask; + const QString text = !keys.at(i).second.isNull() ? QString(keys.at(i).second) : QString(); + + QKeyEvent press(QEvent::KeyPress, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); + QKeyEvent release(QEvent::KeyRelease, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); + + QGuiApplication::sendEvent(window, &press); + QGuiApplication::sendEvent(window, &release); + } +} + +void tst_qquicktextedit::simulateKeys(QWindow *window, const QKeySequence &sequence) +{ + for (uint i = 0; i < sequence.count(); ++i) { + const int key = sequence[i]; + const int modifiers = key & Qt::KeyboardModifierMask; + + QTest::keyClick(window, Qt::Key(key & ~modifiers), Qt::KeyboardModifiers(modifiers)); + } +} + +QList &operator <<(QList &keys, const QKeySequence &sequence) +{ + for (uint i = 0; i < sequence.count(); ++i) + keys << Key(sequence[i], QChar()); + return keys; +} + +template QList &operator <<(QList &keys, const char (&characters)[N]) +{ + for (int i = 0; i < N - 1; ++i) { + int key = QTest::asciiToKey(characters[i]); + QChar character = QLatin1Char(characters[i]); + keys << Key(key, character); + } + return keys; +} + +QList &operator <<(QList &keys, Qt::Key key) +{ + keys << Key(key, QChar()); + return keys; +} + + +void tst_qquicktextedit::initTestCase() +{ +} + +void tst_qquicktextedit::cleanupTestCase() +{ + +} +tst_qquicktextedit::tst_qquicktextedit() +{ + standard << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox\n jumped over the lazy dog" + << "Hello, world!" + << "!dlrow ,olleH"; + + richText << "the quick brown fox jumped over the lazy dog" + << "the quick brown fox
jumped over the lazy dog
"; + + hAlignmentStrings << "AlignLeft" + << "AlignRight" + << "AlignHCenter"; + + vAlignmentStrings << "AlignTop" + << "AlignBottom" + << "AlignVCenter"; + + hAlignments << Qt::AlignLeft + << Qt::AlignRight + << Qt::AlignHCenter; + + vAlignments << Qt::AlignTop + << Qt::AlignBottom + << Qt::AlignVCenter; + + colorStrings << "aliceblue" + << "antiquewhite" + << "aqua" + << "darkkhaki" + << "darkolivegreen" + << "dimgray" + << "palevioletred" + << "lightsteelblue" + << "#000000" + << "#AAAAAA" + << "#FFFFFF" + << "#2AC05F"; + // + // need a different test to do alpha channel test + // << "#AA0011DD" + // << "#00F16B11"; + // +} + +void tst_qquicktextedit::text() +{ + { + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\" }", QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->text(), QString("")); + QCOMPARE(textEditObject->length(), 0); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->text(), standard.at(i)); + QCOMPARE(textEditObject->length(), standard.at(i).length()); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QString actual = textEditObject->text(); + QString expected = richText.at(i); + actual.replace(QRegExp(".*]*>"),""); + actual.replace(QRegExp("(<[^>]*>)+"),"<>"); + expected.replace(QRegExp("(<[^>]*>)+"),"<>"); + QCOMPARE(actual.simplified(),expected.simplified()); + + expected.replace("<>", " "); + QCOMPARE(textEditObject->length(), expected.simplified().length()); + } +} + +void tst_qquicktextedit::width() +{ + // uses Font metrics to find the width for standard and document to find the width for rich + { + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\" }", QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), 0.0); + } + + bool requiresUnhintedMetrics = !qmlDisableDistanceField(); + + for (int i = 0; i < standard.size(); i++) + { + QFont f; + qreal metricWidth = 0.0; + + if (requiresUnhintedMetrics) { + QString s = standard.at(i); + s.replace(QLatin1Char('\n'), QChar::LineSeparator); + + QTextLayout layout(s); + layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); + { + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + } + + layout.beginLayout(); + forever { + QTextLine line = layout.createLine(); + if (!line.isValid()) + break; + } + + layout.endLayout(); + + metricWidth = ceil(layout.boundingRect().width()); + } else { + QFontMetricsF fm(f); + metricWidth = fm.size(Qt::TextExpandTabs | Qt::TextShowMnemonic, standard.at(i)).width(); + metricWidth = ceil(metricWidth); + } + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), qreal(metricWidth)); + } + + for (int i = 0; i < richText.size(); i++) + { + QTextDocument document; + document.setHtml(richText.at(i)); + document.setDocumentMargin(0); + if (requiresUnhintedMetrics) + document.setUseDesignMetrics(true); + + int documentWidth = ceil(document.idealWidth()); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), qreal(documentWidth)); + } +} + +void tst_qquicktextedit::wrap() +{ + // for specified width and wrap set true + { + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData("import QtQuick 2.0\nTextEdit { text: \"\"; wrapMode: TextEdit.WordWrap; width: 300 }", QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), 300.); + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), 300.); + } + + for (int i = 0; i < richText.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { wrapMode: TextEdit.WordWrap; width: 300; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->width(), 300.); + } + +} + +void tst_qquicktextedit::textFormat() +{ + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile("")); + QQuickTextEdit *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->textFormat() == QQuickTextEdit::RichText); + } + { + QDeclarativeComponent textComponent(&engine); + textComponent.setData("import QtQuick 2.0\nTextEdit { text: \"Hello\"; textFormat: Text.PlainText }", QUrl::fromLocalFile("")); + QQuickTextEdit *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject != 0); + QVERIFY(textObject->textFormat() == QQuickTextEdit::PlainText); + } +} + +void tst_qquicktextedit::alignments_data() +{ + QTest::addColumn("hAlign"); + QTest::addColumn("vAlign"); + QTest::addColumn("expectfile"); + + QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << "alignments_lt"; + QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << "alignments_rt"; + QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << "alignments_ct"; + + QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << "alignments_lb"; + QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << "alignments_rb"; + QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << "alignments_cb"; + + QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << "alignments_lc"; + QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << "alignments_rc"; + QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << "alignments_cc"; +} + + +void tst_qquicktextedit::alignments() +{ + QSKIP("Image comparison of text is almost guaranteed to fail during development"); + + QFETCH(int, hAlign); + QFETCH(int, vAlign); + QFETCH(QString, expectfile); + + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("alignments.qml"))); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QObject *ob = canvas.rootObject(); + QVERIFY(ob != 0); + ob->setProperty("horizontalAlignment",hAlign); + ob->setProperty("verticalAlignment",vAlign); + QTRY_COMPARE(ob->property("running").toBool(),false); + QImage actual = canvas.grabFrameBuffer(); + + expectfile = createExpectedFileIfNotFound(expectfile, actual); + + QImage expect(expectfile); + + QCOMPARE(actual,expect); +} + + +//the alignment tests may be trivial o.oa +void tst_qquicktextedit::hAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < hAlignmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { horizontalAlignment: \"" + hAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); + } + } + +} + +void tst_qquicktextedit::hAlign_RightToLeft() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml"))); + QQuickTextEdit *textEdit = canvas.rootObject()->findChild("text"); + QVERIFY(textEdit != 0); + canvas.show(); + + const QString rtlText = textEdit->text(); + + // implicit alignment should follow the reading direction of text + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // explicitly left aligned + textEdit->setHAlign(QQuickTextEdit::AlignLeft); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); + + // explicitly right aligned + textEdit->setHAlign(QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + QString textString = textEdit->text(); + textEdit->setText(QString("") + textString + QString("")); + textEdit->resetHAlign(); + + // implicitly aligned rich text should follow the reading direction of RTL text + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // explicitly left aligned rich text + textEdit->setHAlign(QQuickTextEdit::AlignLeft); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); + QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); + + // explicitly right aligned rich text + textEdit->setHAlign(QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->effectiveHAlign(), textEdit->hAlign()); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + textEdit->setText(textString); + + // explicitly center aligned + textEdit->setHAlign(QQuickTextEdit::AlignHCenter); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignHCenter); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // reseted alignment should go back to following the text reading direction + textEdit->resetHAlign(); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // mirror the text item + QQuickItemPrivate::get(textEdit)->setLayoutMirror(true); + + // mirrored implicit alignment should continue to follow the reading direction of the text + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // mirrored explicitly right aligned behaves as left aligned + textEdit->setHAlign(QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignLeft); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); + + // mirrored explicitly left aligned behaves as right aligned + textEdit->setHAlign(QQuickTextEdit::AlignLeft); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); + QCOMPARE(textEdit->effectiveHAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + + // disable mirroring + QQuickItemPrivate::get(textEdit)->setLayoutMirror(false); + textEdit->resetHAlign(); + + // English text should be implicitly left aligned + textEdit->setText("Hello world!"); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); + QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); + + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + textEdit->setText(QString()); + { QInputMethodEvent ev(rtlText, QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + { QInputMethodEvent ev("Hello world!", QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignLeft); + + // Clear pre-edit text. TextEdit should maybe do this itself on setText, but that may be + // redundant as an actual input method may take care of it. + { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + +#ifndef Q_OS_MAC // QTBUG-18040 + // empty text with implicit alignment follows the system locale-based + // keyboard input direction from QGuiApplication::keyboardInputDirection + textEdit->setText(""); + QCOMPARE(textEdit->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight); + if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight) + QVERIFY(textEdit->positionToRectangle(0).x() < canvas.width()/2); + else + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); + textEdit->setHAlign(QQuickTextEdit::AlignRight); + QCOMPARE(textEdit->hAlign(), QQuickTextEdit::AlignRight); + QVERIFY(textEdit->positionToRectangle(0).x() > canvas.width()/2); +#endif + +#ifndef Q_OS_MAC // QTBUG-18040 + // alignment of TextEdit with no text set to it + QString componentStr = "import QtQuick 2.0\nTextEdit {}"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickTextEdit *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickTextEdit::AlignLeft : QQuickTextEdit::AlignRight); + delete textObject; +#endif +} + +void tst_qquicktextedit::vAlign() +{ + //test one align each, and then test if two align fails. + + for (int i = 0; i < standard.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); + } + } + + for (int i = 0; i < richText.size(); i++) + { + for (int j=0; j < vAlignmentStrings.size(); j++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { verticalAlignment: \"" + vAlignmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); + } + } + +} + +void tst_qquicktextedit::font() +{ + //test size, then bold, then italic, then family + { + QString componentStr = "import QtQuick 2.0\nTextEdit { font.pointSize: 40; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->font().pointSize(), 40); + QCOMPARE(textEditObject->font().bold(), false); + QCOMPARE(textEditObject->font().italic(), false); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { font.bold: true; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->font().bold(), true); + QCOMPARE(textEditObject->font().italic(), false); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { font.italic: true; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->font().italic(), true); + QCOMPARE(textEditObject->font().bold(), false); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"Helvetica\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->font().family(), QString("Helvetica")); + QCOMPARE(textEditObject->font().bold(), false); + QCOMPARE(textEditObject->font().italic(), false); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { font.family: \"\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->font().family(), QString("")); + } +} + +void tst_qquicktextedit::color() +{ + //test initial color + { + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QQuickTextEditPrivate *textEditPrivate = static_cast(QQuickItemPrivate::get(textEditObject)); + + QVERIFY(textEditObject); + QVERIFY(textEditPrivate); + QVERIFY(textEditPrivate->control); + + QPalette pal = textEditPrivate->control->palette(); + QCOMPARE(textEditPrivate->color, QColor("black")); + QCOMPARE(textEditPrivate->color, pal.color(QPalette::Text)); + } + //test normal + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i)); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i))); + } + + //test selection + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->selectionColor(), QColor(colorStrings.at(i))); + } + + //test selected text + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextEdit { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->selectedTextColor(), QColor(colorStrings.at(i))); + } + + { + QString colorStr = "#AA001234"; + QColor testColor("#001234"); + testColor.setAlpha(170); + + QString componentStr = "import QtQuick 2.0\nTextEdit { color: \"" + colorStr + "\"; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->color(), testColor); + } +} + +void tst_qquicktextedit::textMargin() +{ + for (qreal i=0; i<=10; i+=0.3) { + QString componentStr = "import QtQuick 2.0\nTextEdit { textMargin: " + QString::number(i) + "; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->textMargin(), i); + } +} + +void tst_qquicktextedit::persistentSelection() +{ + { + QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: true; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->persistentSelection(), true); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { persistentSelection: false; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->persistentSelection(), false); + } +} + +void tst_qquicktextedit::focusOnPress() +{ + { + QString componentStr = "import QtQuick 2.0\nTextEdit { activeFocusOnPress: true; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->focusOnPress(), true); + } + + { + QString componentStr = "import QtQuick 2.0\nTextEdit { activeFocusOnPress: false; text: \"Hello World\" }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QCOMPARE(textEditObject->focusOnPress(), false); + } +} + +void tst_qquicktextedit::selection() +{ + QString testStr = standard[0];//TODO: What should happen for multiline/rich text? + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); + QVERIFY(textEditObject != 0); + + + //Test selection follows cursor + for (int i=0; i<= testStr.size(); i++) { + textEditObject->setCursorPosition(i); + QCOMPARE(textEditObject->cursorPosition(), i); + QCOMPARE(textEditObject->selectionStart(), i); + QCOMPARE(textEditObject->selectionEnd(), i); + QVERIFY(textEditObject->selectedText().isNull()); + } + + textEditObject->setCursorPosition(0); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + + // Verify invalid positions are ignored. + textEditObject->setCursorPosition(-1); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + + textEditObject->setCursorPosition(textEditObject->text().count()+1); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + + //Test selection + for (int i=0; i<= testStr.size(); i++) { + textEditObject->select(0,i); + QCOMPARE(testStr.mid(0,i), textEditObject->selectedText()); + } + for (int i=0; i<= testStr.size(); i++) { + textEditObject->select(i,testStr.size()); + QCOMPARE(testStr.mid(i,testStr.size()-i), textEditObject->selectedText()); + } + + textEditObject->setCursorPosition(0); + QVERIFY(textEditObject->cursorPosition() == 0); + QVERIFY(textEditObject->selectionStart() == 0); + QVERIFY(textEditObject->selectionEnd() == 0); + QVERIFY(textEditObject->selectedText().isNull()); + + //Test Error Ignoring behaviour + textEditObject->setCursorPosition(0); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(-10,0); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(100,101); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,-10); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,100); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,10); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->select(-10,0); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->select(100,101); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->select(0,-10); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->select(0,100); + QVERIFY(textEditObject->selectedText().size() == 10); + + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); + textEditObject->select(0,10); + QVERIFY(textEditObject->selectedText().size() == 10); + textEditObject->deselect(); + QVERIFY(textEditObject->selectedText().isNull()); +} + +void tst_qquicktextedit::isRightToLeft_data() +{ + QTest::addColumn("text"); + QTest::addColumn("emptyString"); + QTest::addColumn("firstCharacter"); + QTest::addColumn("lastCharacter"); + QTest::addColumn("middleCharacter"); + QTest::addColumn("startString"); + QTest::addColumn("midString"); + QTest::addColumn("endString"); + + const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; + QTest::newRow("Empty") << "" << false << false << false << false << false << false << false; + QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false; + QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false; + QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true; + QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true; + QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false; +} + +void tst_qquicktextedit::isRightToLeft() +{ + QFETCH(QString, text); + QFETCH(bool, emptyString); + QFETCH(bool, firstCharacter); + QFETCH(bool, lastCharacter); + QFETCH(bool, middleCharacter); + QFETCH(bool, startString); + QFETCH(bool, midString); + QFETCH(bool, endString); + + QQuickTextEdit textEdit; + textEdit.setText(text); + + // first test that the right string is delivered to the QString::isRightToLeft() + QCOMPARE(textEdit.isRightToLeft(0,0), text.mid(0,0).isRightToLeft()); + QCOMPARE(textEdit.isRightToLeft(0,1), text.mid(0,1).isRightToLeft()); + QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft()); + QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft()); + QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft()); + QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft()); + if (text.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ": QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start."); + QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft()); + + // then test that the feature actually works + QCOMPARE(textEdit.isRightToLeft(0,0), emptyString); + QCOMPARE(textEdit.isRightToLeft(0,1), firstCharacter); + QCOMPARE(textEdit.isRightToLeft(text.count()-2, text.count()-1), lastCharacter); + QCOMPARE(textEdit.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter); + QCOMPARE(textEdit.isRightToLeft(0,text.count()/4), startString); + QCOMPARE(textEdit.isRightToLeft(text.count()/4,3*text.count()/4), midString); + if (text.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ": QML TextEdit: isRightToLeft(start, end) called with the end property being smaller than the start."); + QCOMPARE(textEdit.isRightToLeft(3*text.count()/4,text.count()-1), endString); +} + +void tst_qquicktextedit::keySelection() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextEdit *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + QTRY_VERIFY(input->hasActiveFocus() == true); + + QSignalSpy spy(input, SIGNAL(selectionChanged())); + + simulateKey(&canvas, Qt::Key_Right, Qt::ShiftModifier); + QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(input->selectedText(), QString("a")); + QCOMPARE(spy.count(), 1); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(input->selectedText(), QString()); + QCOMPARE(spy.count(), 2); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == false); + QCOMPARE(input->selectedText(), QString()); + QCOMPARE(spy.count(), 2); + + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(spy.count(), 2); + simulateKey(&canvas, Qt::Key_Left, Qt::ShiftModifier); + QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(input->selectedText(), QString("a")); + QCOMPARE(spy.count(), 3); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == true); + QCOMPARE(input->selectedText(), QString()); + QCOMPARE(spy.count(), 4); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == false); + QCOMPARE(input->selectedText(), QString()); + QCOMPARE(spy.count(), 4); +} + +void tst_qquicktextedit::moveCursorSelection_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition"); + QTest::addColumn("mode"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("reversible"); + + QTest::newRow("(t)he|characters") + << standard[0] << 0 << 1 << QQuickTextEdit::SelectCharacters << 0 << 1 << true; + QTest::newRow("do(g)|characters") + << standard[0] << 43 << 44 << QQuickTextEdit::SelectCharacters << 43 << 44 << true; + QTest::newRow("jum(p)ed|characters") + << standard[0] << 23 << 24 << QQuickTextEdit::SelectCharacters << 23 << 24 << true; + QTest::newRow("jumped( )over|characters") + << standard[0] << 26 << 27 << QQuickTextEdit::SelectCharacters << 26 << 27 << true; + QTest::newRow("(the )|characters") + << standard[0] << 0 << 4 << QQuickTextEdit::SelectCharacters << 0 << 4 << true; + QTest::newRow("( dog)|characters") + << standard[0] << 40 << 44 << QQuickTextEdit::SelectCharacters << 40 << 44 << true; + QTest::newRow("( jumped )|characters") + << standard[0] << 19 << 27 << QQuickTextEdit::SelectCharacters << 19 << 27 << true; + QTest::newRow("th(e qu)ick|characters") + << standard[0] << 2 << 6 << QQuickTextEdit::SelectCharacters << 2 << 6 << true; + QTest::newRow("la(zy d)og|characters") + << standard[0] << 38 << 42 << QQuickTextEdit::SelectCharacters << 38 << 42 << true; + QTest::newRow("jum(ped ov)er|characters") + << standard[0] << 23 << 29 << QQuickTextEdit::SelectCharacters << 23 << 29 << true; + QTest::newRow("()the|characters") + << standard[0] << 0 << 0 << QQuickTextEdit::SelectCharacters << 0 << 0 << true; + QTest::newRow("dog()|characters") + << standard[0] << 44 << 44 << QQuickTextEdit::SelectCharacters << 44 << 44 << true; + QTest::newRow("jum()ped|characters") + << standard[0] << 23 << 23 << QQuickTextEdit::SelectCharacters << 23 << 23 << true; + + QTest::newRow("<(t)he>|words") + << standard[0] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 3 << true; + QTest::newRow("|words") + << standard[0] << 43 << 44 << QQuickTextEdit::SelectWords << 41 << 44 << true; + QTest::newRow("|words") + << standard[0] << 23 << 24 << QQuickTextEdit::SelectWords << 20 << 26 << true; + QTest::newRow("over|words") + << standard[0] << 26 << 27 << QQuickTextEdit::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,reversed") + << standard[0] << 27 << 26 << QQuickTextEdit::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words") + << standard[0] << 0 << 4 << QQuickTextEdit::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,reversed") + << standard[0] << 4 << 0 << QQuickTextEdit::SelectWords << 0 << 9 << false; + QTest::newRow("|words") + << standard[0] << 40 << 44 << QQuickTextEdit::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,reversed") + << standard[0] << 44 << 40 << QQuickTextEdit::SelectWords << 40 << 44 << false; + QTest::newRow("over|words") + << standard[0] << 19 << 27 << QQuickTextEdit::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,reversed") + << standard[0] << 27 << 19 << QQuickTextEdit::SelectWords << 19 << 31 << false; + QTest::newRow("|words") + << standard[0] << 2 << 6 << QQuickTextEdit::SelectWords << 0 << 9 << true; + QTest::newRow("") + << standard[0] << 38 << 42 << QQuickTextEdit::SelectWords << 36 << 44 << true; + QTest::newRow("|words") + << standard[0] << 23 << 29 << QQuickTextEdit::SelectWords << 20 << 31 << true; + QTest::newRow("<()>the|words") + << standard[0] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("dog<()>|words") + << standard[0] << 44 << 44 << QQuickTextEdit::SelectWords << 44 << 44 << true; + QTest::newRow("jum<()>ped|words") + << standard[0] << 23 << 23 << QQuickTextEdit::SelectWords << 23 << 23 << true; + + QTest::newRow("Hello<(,)> |words") + << standard[2] << 5 << 6 << QQuickTextEdit::SelectWords << 5 << 6 << true; + QTest::newRow("Hello<(, )>world|words") + << standard[2] << 5 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,reversed") + << standard[2] << 7 << 5 << QQuickTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("world|words") + << standard[2] << 3 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("|words,reversed") + << standard[2] << 7 << 3 << QQuickTextEdit::SelectWords << 0 << 12 << false; + QTest::newRow(",|words") + << standard[2] << 3 << 5 << QQuickTextEdit::SelectWords << 0 << 5 << true; + QTest::newRow("Hello<()>,|words") + << standard[2] << 5 << 5 << QQuickTextEdit::SelectWords << 5 << 5 << true; + QTest::newRow("Hello,<()>|words") + << standard[2] << 6 << 6 << QQuickTextEdit::SelectWords << 6 << 6 << true; + QTest::newRow("Hello<,( )>world|words") + << standard[2] << 6 << 7 << QQuickTextEdit::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,reversed") + << standard[2] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words") + << standard[2] << 6 << 12 << QQuickTextEdit::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,reversed") + << standard[2] << 12 << 6 << QQuickTextEdit::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words") + << standard[2] << 6 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,reversed") + << standard[2] << 13 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") + << standard[2] << 5 << 13 << QQuickTextEdit::SelectWords << 5 << 13 << true; + QTest::newRow("world<(!)>|words") + << standard[2] << 12 << 13 << QQuickTextEdit::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") + << standard[2] << 13 << 13 << QQuickTextEdit::SelectWords << 13 << 13 << true; + QTest::newRow("world<()>!)|words") + << standard[2] << 12 << 12 << QQuickTextEdit::SelectWords << 12 << 12 << true; + + QTest::newRow("<(,)>olleH |words") + << standard[3] << 7 << 8 << QQuickTextEdit::SelectWords << 7 << 8 << true; + QTest::newRow("olleH|words") + << standard[3] << 6 << 8 << QQuickTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,reversed") + << standard[3] << 8 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("|words") + << standard[3] << 6 << 10 << QQuickTextEdit::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,reversed") + << standard[3] << 10 << 6 << QQuickTextEdit::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") + << standard[3] << 8 << 10 << QQuickTextEdit::SelectWords << 8 << 13 << true; + QTest::newRow(",<()>olleH|words") + << standard[3] << 8 << 8 << QQuickTextEdit::SelectWords << 8 << 8 << true; + QTest::newRow("<()>,olleH|words") + << standard[3] << 7 << 7 << QQuickTextEdit::SelectWords << 7 << 7 << true; + QTest::newRow(",olleH|words") + << standard[3] << 6 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,reversed") + << standard[3] << 7 << 6 << QQuickTextEdit::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words") + << standard[3] << 1 << 7 << QQuickTextEdit::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 1 << QQuickTextEdit::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words") + << standard[3] << 0 << 7 << QQuickTextEdit::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,reversed") + << standard[3] << 7 << 0 << QQuickTextEdit::SelectWords << 0 << 8 << false; + QTest::newRow("(!dlrow ,)olleH|words") + << standard[3] << 0 << 8 << QQuickTextEdit::SelectWords << 0 << 8 << true; + QTest::newRow("<(!)>dlrow|words") + << standard[3] << 0 << 1 << QQuickTextEdit::SelectWords << 0 << 1 << true; + QTest::newRow("<()>!dlrow|words") + << standard[3] << 0 << 0 << QQuickTextEdit::SelectWords << 0 << 0 << true; + QTest::newRow("!<()>dlrow|words") + << standard[3] << 1 << 1 << QQuickTextEdit::SelectWords << 1 << 1 << true; +} + +void tst_qquicktextedit::moveCursorSelection() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition); + QFETCH(QQuickTextEdit::SelectionMode, mode); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(bool, reversible); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *texteditObject = qobject_cast(textinputComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + texteditObject->moveCursorSelection(movePosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + + if (reversible) { + texteditObject->setCursorPosition(movePosition); + texteditObject->moveCursorSelection(cursorPosition, mode); + + QCOMPARE(texteditObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(texteditObject->selectionStart(), selectionStart); + QCOMPARE(texteditObject->selectionEnd(), selectionEnd); + } +} + +void tst_qquicktextedit::moveCursorSelectionSequence_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition1"); + QTest::addColumn("movePosition2"); + QTest::addColumn("selection1Start"); + QTest::addColumn("selection1End"); + QTest::addColumn("selection2Start"); + QTest::addColumn("selection2End"); + + QTest::newRow("the { f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the { ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<(^ {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the { fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; +} + +void tst_qquicktextedit::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \""+ testStr +"\"; }"; + QDeclarativeComponent texteditComponent(&engine); + texteditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *texteditObject = qobject_cast(texteditComponent.create()); + QVERIFY(texteditObject != 0); + + texteditObject->setCursorPosition(cursorPosition); + + texteditObject->moveCursorSelection(movePosition1, QQuickTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(texteditObject->selectionStart(), selection1Start); + QCOMPARE(texteditObject->selectionEnd(), selection1End); + + texteditObject->moveCursorSelection(movePosition2, QQuickTextEdit::SelectWords); + QCOMPARE(texteditObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(texteditObject->selectionStart(), selection2Start); + QCOMPARE(texteditObject->selectionEnd(), selection2End); +} + + +void tst_qquicktextedit::mouseSelection_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("from"); + QTest::addColumn("to"); + QTest::addColumn("selectedText"); + + // import installed + QTest::newRow("on") << TESTDATA("mouseselection_true.qml") << 4 << 9 << "45678"; + QTest::newRow("off") << TESTDATA("mouseselection_false.qml") << 4 << 9 << QString(); + QTest::newRow("default") << TESTDATA("mouseselection_default.qml") << 4 << 9 << QString(); + QTest::newRow("off word selection") << TESTDATA("mouseselection_false_words.qml") << 4 << 9 << QString(); + QTest::newRow("on word selection (4,9)") << TESTDATA("mouseselection_true_words.qml") << 4 << 9 << "0123456789"; + QTest::newRow("on word selection (2,13)") << TESTDATA("mouseselection_true_words.qml") << 2 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (2,30)") << TESTDATA("mouseselection_true_words.qml") << 2 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (9,13)") << TESTDATA("mouseselection_true_words.qml") << 9 << 13 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (9,30)") << TESTDATA("mouseselection_true_words.qml") << 9 << 30 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (13,2)") << TESTDATA("mouseselection_true_words.qml") << 13 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (20,2)") << TESTDATA("mouseselection_true_words.qml") << 20 << 2 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (12,9)") << TESTDATA("mouseselection_true_words.qml") << 12 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QTest::newRow("on word selection (30,9)") << TESTDATA("mouseselection_true_words.qml") << 30 << 9 << "0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +} + +void tst_qquicktextedit::mouseSelection() +{ + QFETCH(QString, qmlfile); + QFETCH(int, from); + QFETCH(int, to); + QFETCH(QString, selectedText); + + QQuickView canvas(QUrl::fromLocalFile(qmlfile)); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint(); + QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint(); + QTest::mousePress(&canvas, Qt::LeftButton, 0, p1); + QTest::mouseMove(&canvas, p2); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, p2); + QTest::qWait(50); + QTRY_COMPARE(textEditObject->selectedText(), selectedText); + + // Clicking and shift to clicking between the same points should select the same text. + textEditObject->setCursorPosition(0); + QTest::mouseClick(&canvas, Qt::LeftButton, Qt::NoModifier, p1); + QTest::mouseClick(&canvas, Qt::LeftButton, Qt::ShiftModifier, p2); + QTest::qWait(50); + QTRY_COMPARE(textEditObject->selectedText(), selectedText); +} + +void tst_qquicktextedit::dragMouseSelection() +{ + QString qmlfile = TESTDATA("mouseselection_true.qml"); + + QQuickView canvas(QUrl::fromLocalFile(qmlfile)); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2, y)); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QTest::qWait(300); + QString str1; + QTRY_VERIFY((str1 = textEditObject->selectedText()).length() > 3); + + // press and drag the current selection. + x1 = 40; + x2 = 100; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2, y)); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QTest::qWait(300); + QString str2; + QTRY_VERIFY((str2 = textEditObject->selectedText()).length() > 3); + + QVERIFY(str1 != str2); // Verify the second press and drag is a new selection and not the first moved. +} + +void tst_qquicktextedit::mouseSelectionMode_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("selectWords"); + + // import installed + QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true; + QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false; + QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false; +} + +void tst_qquicktextedit::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QQuickView canvas(QUrl::fromLocalFile(qmlfile)); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2, y)); + //QTest::mouseMove(canvas, QPoint(x2,y)); // doesn't work +// QMouseEvent mv(QEvent::MouseMove, QPoint(x2,y), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); +// QGuiApplication::sendEvent(&canvas, &mv); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QString str = textEditObject->selectedText(); + if (selectWords) { + QTRY_COMPARE(textEditObject->selectedText(), text); + } else { + QTRY_VERIFY(textEditObject->selectedText().length() > 3); + QVERIFY(str != text); + } +} + +void tst_qquicktextedit::inputMethodHints() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethodhints.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextEdit *textEditObject = qobject_cast(canvas.rootObject()); + QVERIFY(textEditObject != 0); + QVERIFY(textEditObject->inputMethodHints() & Qt::ImhNoPredictiveText); + textEditObject->setInputMethodHints(Qt::ImhUppercaseOnly); + QVERIFY(textEditObject->inputMethodHints() & Qt::ImhUppercaseOnly); +} + +void tst_qquicktextedit::positionAt() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); + QVERIFY(canvas.rootObject() != 0); + canvas.show(); + canvas.requestActivateWindow(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + QQuickTextEdit *texteditObject = qobject_cast(canvas.rootObject()); + QVERIFY(texteditObject != 0); + + QFontMetrics fm(texteditObject->font()); + const int y0 = fm.height() / 2; + const int y1 = fm.height() * 3 / 2; + + int pos = texteditObject->positionAt(texteditObject->width()/2, y0); + int widthBegin = 0; + int widthEnd = 0; + if (!qmlDisableDistanceField()) { + QTextLayout layout(texteditObject->text()); + + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + widthBegin = floor(line.cursorToX(pos - 1)); + widthEnd = ceil(line.cursorToX(pos + 1)); + } else { + widthBegin = fm.width(texteditObject->text().left(pos - 1)); + widthEnd = fm.width(texteditObject->text().left(pos + 1)); + } + + QVERIFY(widthBegin <= texteditObject->width() / 2); + QVERIFY(widthEnd >= texteditObject->width() / 2); + + const qreal x0 = texteditObject->positionToRectangle(pos).x(); + const qreal x1 = texteditObject->positionToRectangle(pos + 1).x(); + + QString preeditText = texteditObject->text().mid(0, pos); + texteditObject->setText(texteditObject->text().mid(pos)); + texteditObject->setCursorPosition(0); + + QInputMethodEvent inputEvent(preeditText, QList()); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent); + + // Check all points within the preedit text return the same position. + QCOMPARE(texteditObject->positionAt(0, y0), 0); + QCOMPARE(texteditObject->positionAt(x0 / 2, y0), 0); + QCOMPARE(texteditObject->positionAt(x0, y0), 0); + + // Verify positioning returns to normal after the preedit text. + QCOMPARE(texteditObject->positionAt(x1, y0), 1); + QCOMPARE(texteditObject->positionToRectangle(1).x(), x1); + + QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0); +} + +void tst_qquicktextedit::cursorDelegate() +{ + QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml"))); + view.show(); + view.requestActivateWindow(); + QQuickTextEdit *textEditObject = view.rootObject()->findChild("textEditObject"); + QVERIFY(textEditObject != 0); + QVERIFY(textEditObject->findChild("cursorInstance")); + //Test Delegate gets created + textEditObject->setFocus(true); + QQuickItem* delegateObject = textEditObject->findChild("cursorInstance"); + QVERIFY(delegateObject); + QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello")); + //Test Delegate gets moved + for (int i=0; i<= textEditObject->text().length(); i++) { + textEditObject->setCursorPosition(i); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + } + // Clear preedit text; + QInputMethodEvent event; + QGuiApplication::sendEvent(&view, &event); + + + // Test delegate gets moved on mouse press. + textEditObject->setSelectByMouse(true); + textEditObject->setCursorPosition(0); + const QPoint point1 = textEditObject->positionToRectangle(5).center().toPoint(); + QTest::mouseClick(&view, Qt::LeftButton, 0, point1); + QTest::qWait(50); + QTRY_VERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + // Test delegate gets moved on mouse drag + textEditObject->setCursorPosition(0); + const QPoint point2 = textEditObject->positionToRectangle(10).center().toPoint(); + QTest::mousePress(&view, Qt::LeftButton, 0, point1); + QMouseEvent mv(QEvent::MouseMove, point2, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QGuiApplication::sendEvent(&view, &mv); + QTest::mouseRelease(&view, Qt::LeftButton, 0, point2); + QTest::qWait(50); + QTRY_COMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + textEditObject->setReadOnly(true); + textEditObject->setCursorPosition(0); + QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); + QTest::qWait(50); + QTRY_VERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + textEditObject->setCursorPosition(0); + QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); + QTest::qWait(50); + QTRY_VERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + textEditObject->setCursorPosition(0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + //Test Delegate gets deleted + textEditObject->setCursorDelegate(0); + QVERIFY(!textEditObject->findChild("cursorInstance")); +} + +void tst_qquicktextedit::cursorVisible() +{ + QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QQuickTextEdit edit; + QSignalSpy spy(&edit, SIGNAL(cursorVisibleChanged(bool))); + + QCOMPARE(edit.isCursorVisible(), false); + + edit.setCursorVisible(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 1); + + edit.setCursorVisible(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + edit.setParentItem(view.rootObject()); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 3); + + edit.setFocus(false); + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 4); + + edit.setFocus(true); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 5); + + QQuickView alternateView; + alternateView.show(); + alternateView.requestActivateWindow(); + QTest::qWaitForWindowShown(&alternateView); + + QCOMPARE(edit.isCursorVisible(), false); + QCOMPARE(spy.count(), 6); + + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QCOMPARE(edit.isCursorVisible(), true); + QCOMPARE(spy.count(), 7); +} + +void tst_qquicktextedit::delegateLoading_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("error"); + + // import installed + QTest::newRow("pass") << "cursorHttpTestPass.qml" << ""; + QTest::newRow("fail1") << "cursorHttpTestFail1.qml" << "http://localhost:42332/FailItem.qml: Remote host closed the connection "; + QTest::newRow("fail2") << "cursorHttpTestFail2.qml" << "http://localhost:42332/ErrItem.qml:4:5: Fungus is not a type "; +} + +void tst_qquicktextedit::delegateLoading() +{ + QFETCH(QString, qmlfile); + QFETCH(QString, error); + + TestHTTPServer server(42332); + server.serveDirectory(TESTDATA("httpfail"), TestHTTPServer::Disconnect); + server.serveDirectory(TESTDATA("httpslow"), TestHTTPServer::Delay); + server.serveDirectory(TESTDATA("http")); + + QQuickView view(QUrl(QLatin1String("http://localhost:42332/") + qmlfile)); + view.show(); + view.requestActivateWindow(); + + if (!error.isEmpty()) { + QTest::ignoreMessage(QtWarningMsg, error.toUtf8()); + QTRY_VERIFY(view.status()==QQuickView::Error); + QTRY_VERIFY(!view.rootObject()); // there is fail item inside this test + } else { + QTRY_VERIFY(view.rootObject());//Wait for loading to finish. + QQuickTextEdit *textEditObject = view.rootObject()->findChild("textEditObject"); + // view.rootObject()->dumpObjectTree(); + QVERIFY(textEditObject != 0); + textEditObject->setFocus(true); + QQuickItem *delegate; + delegate = view.rootObject()->findChild("delegateOkay"); + QVERIFY(delegate); + delegate = view.rootObject()->findChild("delegateSlow"); + QVERIFY(delegate); + + delete delegate; + } + + + //A test should be added here with a component which is ready but component.create() returns null + //Not sure how to accomplish this with QQuickTextEdits cursor delegate + //###This was only needed for code coverage, and could be a case of overzealous defensive programming + //delegate = view.rootObject()->findChild("delegateErrorB"); + //QVERIFY(!delegate); +} + +/* +TextEdit element should only handle left/right keys until the cursor reaches +the extent of the text, then they should ignore the keys. +*/ +void tst_qquicktextedit::navigation() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickItem *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + QTRY_VERIFY(input->hasActiveFocus() == true); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == false); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == true); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == true); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == false); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == true); +} + +void tst_qquicktextedit::copyAndPaste() { +#ifndef QT_NO_CLIPBOARD + +#ifdef Q_OS_MAC + { + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate(0, &pasteboard); + if (status == noErr) + CFRelease(pasteboard); + else + QSKIP("This machine doesn't support the clipboard"); + } +#endif + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + // copy and paste + QCOMPARE(textEdit->text().length(), 12); + textEdit->select(0, textEdit->text().length());; + textEdit->copy(); + QCOMPARE(textEdit->selectedText(), QString("Hello world!")); + QCOMPARE(textEdit->selectedText().length(), 12); + textEdit->setCursorPosition(0); + QVERIFY(textEdit->canPaste()); + textEdit->paste(); + QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); + QCOMPARE(textEdit->text().length(), 24); + + // canPaste + QVERIFY(textEdit->canPaste()); + textEdit->setReadOnly(true); + QVERIFY(!textEdit->canPaste()); + textEdit->setReadOnly(false); + QVERIFY(textEdit->canPaste()); + + // QTBUG-12339 + // test that document and internal text attribute are in sync + QQuickItemPrivate* pri = QQuickItemPrivate::get(textEdit); + QQuickTextEditPrivate *editPrivate = static_cast(pri); + QCOMPARE(textEdit->text(), editPrivate->text); + + // select word + textEdit->setCursorPosition(0); + textEdit->selectWord(); + QCOMPARE(textEdit->selectedText(), QString("Hello")); + + // select all and cut + textEdit->selectAll(); + textEdit->cut(); + QCOMPARE(textEdit->text().length(), 0); + textEdit->paste(); + QCOMPARE(textEdit->text(), QString("Hello world!Hello world!")); + QCOMPARE(textEdit->text().length(), 24); +#endif +} + +void tst_qquicktextedit::canPaste() { +#ifndef QT_NO_CLIPBOARD + + QGuiApplication::clipboard()->setText("Some text"); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + // check initial value - QTBUG-17765 + QTextControl tc; + QCOMPARE(textEdit->canPaste(), tc.canPaste()); + +#endif +} + +void tst_qquicktextedit::canPasteEmpty() { +#ifndef QT_NO_CLIPBOARD + + QGuiApplication::clipboard()->clear(); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"Hello world!\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + // check initial value - QTBUG-17765 + QTextControl tc; + QCOMPARE(textEdit->canPaste(), tc.canPaste()); + +#endif +} + +void tst_qquicktextedit::readOnly() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextEdit *edit = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(edit != 0); + QTRY_VERIFY(edit->hasActiveFocus() == true); + QVERIFY(edit->isReadOnly() == true); + QString initial = edit->text(); + for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) + simulateKey(&canvas, k); + simulateKey(&canvas, Qt::Key_Return); + simulateKey(&canvas, Qt::Key_Space); + simulateKey(&canvas, Qt::Key_Escape); + QCOMPARE(edit->text(), initial); + + edit->setCursorPosition(3); + edit->setReadOnly(false); + QCOMPARE(edit->isReadOnly(), false); + QCOMPARE(edit->cursorPosition(), edit->text().length()); +} + +void tst_qquicktextedit::simulateKey(QQuickView *view, int key, Qt::KeyboardModifiers modifiers) +{ + QKeyEvent press(QKeyEvent::KeyPress, key, modifiers); + QKeyEvent release(QKeyEvent::KeyRelease, key, modifiers); + + QGuiApplication::sendEvent(view, &press); + QGuiApplication::sendEvent(view, &release); +} + +void tst_qquicktextedit::textInput() +{ + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextEdit *edit = qobject_cast(view.rootObject()); + QVERIFY(edit); + QVERIFY(edit->hasActiveFocus() == true); + + // test that input method event is committed + QInputMethodEvent event; + event.setCommitString( "Hello world!", 0, 0); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); + QCOMPARE(edit->text(), QString("Hello world!")); + + // QTBUG-12339 + // test that document and internal text attribute are in sync + QQuickTextEditPrivate *editPrivate = static_cast(QQuickItemPrivate::get(edit)); + QCOMPARE(editPrivate->text, QString("Hello world!")); +} + +class PlatformInputContext : public QPlatformInputContext +{ +public: + PlatformInputContext() : m_visible(false) {} + + virtual void showInputPanel() + { + m_visible = true; + } + virtual void hideInputPanel() + { + m_visible = false; + } + virtual bool isInputPanelVisible() const + { + return m_visible; + } + + bool m_visible; +}; + +void tst_qquicktextedit::openInputPanel() +{ + PlatformInputContext platformInputContext; + QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); + inputPanelPrivate->testContext = &platformInputContext; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QQuickTextEdit *edit = qobject_cast(view.rootObject()); + QVERIFY(edit); + + // check default values + QVERIFY(edit->focusOnPress()); + QVERIFY(!edit->hasActiveFocus()); + qDebug() << &edit << qApp->inputPanel()->inputItem(); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open on focus + QPoint centerPoint(view.width()/2, view.height()/2); + Qt::KeyboardModifiers noModifiers = 0; + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QVERIFY(edit->hasActiveFocus()); + QCOMPARE(qApp->inputPanel()->inputItem(), edit); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + + // input panel should be re-opened when pressing already focused TextEdit + qApp->inputPanel()->hide(); + QCOMPARE(qApp->inputPanel()->visible(), false); + QVERIFY(edit->hasActiveFocus()); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + + // input panel should stay visible if focus is lost to another text editor + QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); + QQuickTextEdit anotherEdit; + anotherEdit.setParentItem(view.rootObject()); + anotherEdit.setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), true); + QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherEdit)); + QCOMPARE(inputPanelVisibilitySpy.count(), 0); + + anotherEdit.setFocus(false); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), view.rootItem()); + anotherEdit.setFocus(true); + + // input item should be null if focus is lost to an item that doesn't accept inputs + QQuickItem item; + item.setParentItem(view.rootObject()); + item.setFocus(true); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), &item); + + qApp->inputPanel()->hide(); + + // input panel should not be opened if TextEdit is read only + edit->setReadOnly(true); + edit->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should not be opened if focusOnPress is set to false + edit->setFocusOnPress(false); + edit->setFocus(false); + edit->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open when openSoftwareInputPanel is called + edit->openSoftwareInputPanel(); + QCOMPARE(qApp->inputPanel()->visible(), true); + + // input panel should close when closeSoftwareInputPanel is called + edit->closeSoftwareInputPanel(); + QCOMPARE(qApp->inputPanel()->visible(), false); + + inputPanelPrivate->testContext = 0; +} + +void tst_qquicktextedit::geometrySignals() +{ + QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml")); + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("bindingWidth").toInt(), 400); + QCOMPARE(o->property("bindingHeight").toInt(), 500); + delete o; +} + +void tst_qquicktextedit::pastingRichText_QTBUG_14003() +{ +#ifndef QT_NO_CLIPBOARD + QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.PlainText }"; + QDeclarativeComponent component(&engine); + component.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickTextEdit *obj = qobject_cast(component.create()); + + QTRY_VERIFY(obj != 0); + QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); + + QMimeData *mData = new QMimeData; + mData->setHtml("Hello"); + QGuiApplication::clipboard()->setMimeData(mData); + + obj->paste(); + QTRY_VERIFY(obj->text() == ""); + QTRY_VERIFY(obj->textFormat() == QQuickTextEdit::PlainText); +#endif +} + +void tst_qquicktextedit::implicitSize_data() +{ + QTest::addColumn("text"); + QTest::addColumn("wrap"); + QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; + QTest::newRow("richtext") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap"; + QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; + QTest::newRow("richtext_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap"; +} + +void tst_qquicktextedit::implicitSize() +{ + QFETCH(QString, text); + QFETCH(QString, wrap); + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickTextEdit *textObject = qobject_cast(textComponent.create()); + + QVERIFY(textObject->width() < textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); + + textObject->resetWidth(); + QVERIFY(textObject->width() == textObject->implicitWidth()); + QVERIFY(textObject->height() == textObject->implicitHeight()); +} + +void tst_qquicktextedit::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 2.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; TextEdit { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qquicktextedit::testQtQuick11Attributes_data() +{ + QTest::addColumn("code"); + QTest::addColumn("warning"); + QTest::addColumn("error"); + + QTest::newRow("canPaste") << "property bool foo: canPaste" + << ":1: ReferenceError: Can't find variable: canPaste" + << ""; + + QTest::newRow("lineCount") << "property int foo: lineCount" + << ":1: ReferenceError: Can't find variable: lineCount" + << ""; + + QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" + << ":1: ReferenceError: Can't find variable: moveCursorSelection" + << ""; + + QTest::newRow("deselect") << "Component.onCompleted: deselect()" + << ":1: ReferenceError: Can't find variable: deselect" + << ""; + + QTest::newRow("onLinkActivated") << "onLinkActivated: {}" + << "QDeclarativeComponent: Component is not ready" + << ":1 \"TextEdit.onLinkActivated\" is not available in QtQuick 1.0.\n"; +} + +void tst_qquicktextedit::preeditCursorRectangle() +{ + QString preeditText = "super"; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextEdit *edit = qobject_cast(view.rootObject()); + QVERIFY(edit); + + QSignalSpy editSpy(edit, SIGNAL(cursorRectangleChanged())); + QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged())); + + QRect currentRect; + + QInputMethodQueryEvent query(Qt::ImCursorRectangle); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + QRect previousRect = query.value(Qt::ImCursorRectangle).toRect(); + + // Verify that the micro focus rect is positioned the same for position 0 as + // it would be if there was no preedit text. + QInputMethodEvent imEvent(preeditText, QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, preeditText.length(), QVariant())); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QCOMPARE(currentRect, previousRect); + QCOMPARE(editSpy.count(), 0); + QCOMPARE(panelSpy.count(), 0); + + // Verify that the micro focus rect moves to the left as the cursor position + // is incremented. + for (int i = 1; i <= 5; ++i) { + QInputMethodEvent imEvent(preeditText, QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, preeditText.length(), QVariant())); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QVERIFY(previousRect.left() < currentRect.left()); + QVERIFY(editSpy.count() > 0); editSpy.clear(); + QVERIFY(panelSpy.count() > 0); panelSpy.clear(); + previousRect = currentRect; + } + + // Verify that if there is no preedit cursor then the micro focus rect is the + // same as it would be if it were positioned at the end of the preedit text. + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + editSpy.clear(); + panelSpy.clear(); + { QInputMethodEvent imEvent(preeditText, QList()); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); } + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QCOMPARE(currentRect, previousRect); + QVERIFY(editSpy.count() > 0); + QVERIFY(panelSpy.count() > 0); +} + +void tst_qquicktextedit::inputMethodComposing() +{ + QString text = "supercalifragisiticexpialidocious!"; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextEdit *edit = qobject_cast(view.rootObject()); + QVERIFY(edit); + QSignalSpy spy(edit, SIGNAL(inputMethodComposingChanged())); + edit->setCursorPosition(12); + + QCOMPARE(edit->isInputMethodComposing(), false); + + { + QInputMethodEvent event(text.mid(3), QList()); + QGuiApplication::sendEvent(edit, &event); + } + + QCOMPARE(edit->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 1); + + { + QInputMethodEvent event(text.mid(12), QList()); + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(spy.count(), 1); + + { + QInputMethodEvent event; + QGuiApplication::sendEvent(edit, &event); + } + QCOMPARE(edit->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 2); +} + +void tst_qquicktextedit::cursorRectangleSize() +{ + QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); + QVERIFY(canvas->rootObject() != 0); + QQuickTextEdit *textEdit = qobject_cast(canvas->rootObject()); + + // make sure cursor rectangle is not at (0,0) + textEdit->setX(10); + textEdit->setY(10); + textEdit->setCursorPosition(3); + QVERIFY(textEdit != 0); + textEdit->setFocus(true); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + + QInputMethodQueryEvent event(Qt::ImCursorRectangle); + qApp->sendEvent(qApp->inputPanel()->inputItem(), &event); + QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); + + QRect cursorRectFromItem = textEdit->cursorRectangle(); + QRectF cursorRectFromPositionToRectangle = textEdit->positionToRectangle(textEdit->cursorPosition()); + + // item and input query cursor rectangles match + QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + + // item cursor rectangle and positionToRectangle calculations match + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + + // item-canvas transform and input item transform match + QCOMPARE(QQuickItemPrivate::get(textEdit)->itemToCanvasTransform(), qApp->inputPanel()->inputItemTransform()); + + // input panel cursorRectangle property and tranformed item cursor rectangle match + QRectF sceneCursorRect = QQuickItemPrivate::get(textEdit)->itemToCanvasTransform().mapRect(cursorRectFromItem); + QCOMPARE(sceneCursorRect, qApp->inputPanel()->cursorRectangle()); + + delete canvas; +} + +void tst_qquicktextedit::getText_data() +{ + QTest::addColumn("text"); + QTest::addColumn("start"); + QTest::addColumn("end"); + QTest::addColumn("expectedText"); + + const QString richBoldText = QStringLiteral("This is some bold text"); + const QString plainBoldText = QStringLiteral("This is some bold text"); + + QTest::newRow("all plain text") + << standard.at(0) + << 0 << standard.at(0).length() + << standard.at(0); + + QTest::newRow("plain text sub string") + << standard.at(0) + << 0 << 12 + << standard.at(0).mid(0, 12); + + QTest::newRow("plain text sub string reversed") + << standard.at(0) + << 12 << 0 + << standard.at(0).mid(0, 12); + + QTest::newRow("plain text cropped beginning") + << standard.at(0) + << -3 << 4 + << standard.at(0).mid(0, 4); + + QTest::newRow("plain text cropped end") + << standard.at(0) + << 23 << standard.at(0).length() + 8 + << standard.at(0).mid(23); + + QTest::newRow("plain text cropped beginning and end") + << standard.at(0) + << -9 << standard.at(0).length() + 4 + << standard.at(0); + + QTest::newRow("all rich text") + << richBoldText + << 0 << plainBoldText.length() + << plainBoldText; + + QTest::newRow("rich text sub string") + << richBoldText + << 14 << 21 + << plainBoldText.mid(14, 7); +} + +void tst_qquicktextedit::getText() +{ + QFETCH(QString, text); + QFETCH(int, start); + QFETCH(int, end); + QFETCH(QString, expectedText); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QCOMPARE(textEdit->getText(start, end), expectedText); +} + +void tst_qquicktextedit::getFormattedText_data() +{ + QTest::addColumn("text"); + QTest::addColumn("textFormat"); + QTest::addColumn("start"); + QTest::addColumn("end"); + QTest::addColumn("expectedText"); + + const QString richBoldText = QStringLiteral("This is some bold text"); + const QString plainBoldText = QStringLiteral("This is some bold text"); + + QTest::newRow("all plain text") + << standard.at(0) + << QQuickTextEdit::PlainText + << 0 << standard.at(0).length() + << standard.at(0); + + QTest::newRow("plain text sub string") + << standard.at(0) + << QQuickTextEdit::PlainText + << 0 << 12 + << standard.at(0).mid(0, 12); + + QTest::newRow("plain text sub string reversed") + << standard.at(0) + << QQuickTextEdit::PlainText + << 12 << 0 + << standard.at(0).mid(0, 12); + + QTest::newRow("plain text cropped beginning") + << standard.at(0) + << QQuickTextEdit::PlainText + << -3 << 4 + << standard.at(0).mid(0, 4); + + QTest::newRow("plain text cropped end") + << standard.at(0) + << QQuickTextEdit::PlainText + << 23 << standard.at(0).length() + 8 + << standard.at(0).mid(23); + + QTest::newRow("plain text cropped beginning and end") + << standard.at(0) + << QQuickTextEdit::PlainText + << -9 << standard.at(0).length() + 4 + << standard.at(0); + + QTest::newRow("all rich (Auto) text") + << richBoldText + << QQuickTextEdit::AutoText + << 0 << plainBoldText.length() + << QString("This is some \\<.*\\>bold\\ text"); + + QTest::newRow("all rich (Rich) text") + << richBoldText + << QQuickTextEdit::RichText + << 0 << plainBoldText.length() + << QString("This is some \\<.*\\>bold\\ text"); + + QTest::newRow("all rich (Plain) text") + << richBoldText + << QQuickTextEdit::PlainText + << 0 << richBoldText.length() + << richBoldText; + + QTest::newRow("rich (Auto) text sub string") + << richBoldText + << QQuickTextEdit::AutoText + << 14 << 21 + << QString("\\<.*\\>old\\ tex"); + + QTest::newRow("rich (Rich) text sub string") + << richBoldText + << QQuickTextEdit::RichText + << 14 << 21 + << QString("\\<.*\\>old\\ tex"); + + QTest::newRow("rich (Plain) text sub string") + << richBoldText + << QQuickTextEdit::PlainText + << 17 << 27 + << richBoldText.mid(17, 10); +} + +void tst_qquicktextedit::getFormattedText() +{ + QFETCH(QString, text); + QFETCH(QQuickTextEdit::TextFormat, textFormat); + QFETCH(int, start); + QFETCH(int, end); + QFETCH(QString, expectedText); + + QString componentStr = "import QtQuick 2.0\nTextEdit {}"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + textEdit->setTextFormat(textFormat); + textEdit->setText(text); + + if (textFormat == QQuickTextEdit::RichText + || (textFormat == QQuickTextEdit::AutoText && Qt::mightBeRichText(text))) { + QVERIFY(textEdit->getFormattedText(start, end).contains(QRegExp(expectedText))); + } else { + QCOMPARE(textEdit->getFormattedText(start, end), expectedText); + } +} + +void tst_qquicktextedit::insert_data() +{ + QTest::addColumn("text"); + QTest::addColumn("textFormat"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("insertPosition"); + QTest::addColumn("insertText"); + QTest::addColumn("expectedText"); + QTest::addColumn("expectedSelectionStart"); + QTest::addColumn("expectedSelectionEnd"); + QTest::addColumn("expectedCursorPosition"); + QTest::addColumn("selectionChanged"); + QTest::addColumn("cursorPositionChanged"); + + QTest::newRow("at cursor position (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 5 << 5 << 5 + << false << true; + + QTest::newRow("at cursor position (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("Hello") + << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5 + << false << true; + + QTest::newRow("at cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 << 18 + << QString("Hello") + << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) + << 23 << 23 << 23 + << false << true; + + QTest::newRow("after cursor position (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 << 18 + << QString("Hello") + << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("before cursor position (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() << 18 + << QString("Hello") + << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) + << standard.at(0).length() + 5 << standard.at(0).length() + 5 << standard.at(0).length() + 5 + << false << true; + + QTest::newRow("before cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 23 << 23 << 23 + << false << true; + + QTest::newRow("after cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("Hello") + << 18 << 18 << 18 + << false << false; + + QTest::newRow("before selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 19 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 19 << 24 << 24 + << false << true; + + QTest::newRow("before reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 19 << 14 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 19 << 24 << 19 + << false << true; + + QTest::newRow("after selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 19 << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("Hello") + << 14 << 19 << 19 + << false << false; + + QTest::newRow("after reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 19 << 14 << standard.at(0).length() + << QString("Hello") + << standard.at(0) + QString("Hello") + << 14 << 19 << 14 + << false << false; + + QTest::newRow("into selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 19 << 18 + << QString("Hello") + << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) + << 14 << 24 << 24 + << true << true; + + QTest::newRow("into reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 19 << 14 << 18 + << QString("Hello") + << standard.at(0).mid(0, 18) + QString("Hello") + standard.at(0).mid(18) + << 14 << 24 << 14 + << true << false; + + QTest::newRow("rich text into plain text") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 12 << 12 << 12 + << false << true; + + QTest::newRow("rich text into rich text") + << standard.at(0) << QQuickTextEdit::RichText + << 0 << 0 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 5 << 5 << 5 + << false << true; + + QTest::newRow("rich text into auto text") + << standard.at(0) << QQuickTextEdit::AutoText + << 0 << 0 << 0 + << QString("Hello") + << QString("Hello") + standard.at(0) + << 5 << 5 << 5 + << false << true; + + QTest::newRow("before start") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 << -3 + << QString("Hello") + << standard.at(0) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("past end") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 << standard.at(0).length() + 3 + << QString("Hello") + << standard.at(0) + << 0 << 0 << 0 + << false << false; +} + +void tst_qquicktextedit::insert() +{ + QFETCH(QString, text); + QFETCH(QQuickTextEdit::TextFormat, textFormat); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(int, insertPosition); + QFETCH(QString, insertText); + QFETCH(QString, expectedText); + QFETCH(int, expectedSelectionStart); + QFETCH(int, expectedSelectionEnd); + QFETCH(int, expectedCursorPosition); + QFETCH(bool, selectionChanged); + QFETCH(bool, cursorPositionChanged); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + textEdit->setTextFormat(textFormat); + textEdit->select(selectionStart, selectionEnd); + + QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged())); + QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged())); + QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged())); + QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString))); + QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged())); + + textEdit->insert(insertPosition, insertText); + + if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && ( + Qt::mightBeRichText(text) || Qt::mightBeRichText(insertText)))) { + QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText); + } else { + QCOMPARE(textEdit->text(), expectedText); + + } + QCOMPARE(textEdit->length(), expectedText.length()); + + QCOMPARE(textEdit->selectionStart(), expectedSelectionStart); + QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); + QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); + + if (selectionStart > selectionEnd) + qSwap(selectionStart, selectionEnd); + + QEXPECT_FAIL("into selection", "selectionChanged signal isn't emitted on edits within selection", Continue); + QEXPECT_FAIL("into reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue); + QCOMPARE(selectionSpy.count() > 0, selectionChanged); + QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); + QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue); + QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); + QCOMPARE(textSpy.count() > 0, text != expectedText); + QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged); +} + +void tst_qquicktextedit::remove_data() +{ + QTest::addColumn("text"); + QTest::addColumn("textFormat"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("removeStart"); + QTest::addColumn("removeEnd"); + QTest::addColumn("expectedText"); + QTest::addColumn("expectedSelectionStart"); + QTest::addColumn("expectedSelectionEnd"); + QTest::addColumn("expectedCursorPosition"); + QTest::addColumn("selectionChanged"); + QTest::addColumn("cursorPositionChanged"); + + const QString richBoldText = QStringLiteral("This is some bold text"); + const QString plainBoldText = QStringLiteral("This is some bold text"); + + QTest::newRow("from cursor position (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << 0 << 5 + << standard.at(0).mid(5) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("to cursor position (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << 5 << 0 + << standard.at(0).mid(5) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("to cursor position (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() + << standard.at(0).length() << standard.at(0).length() - 5 + << standard.at(0).mid(0, standard.at(0).length() - 5) + << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 + << false << true; + + QTest::newRow("to cursor position (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() + << standard.at(0).length() - 5 << standard.at(0).length() + << standard.at(0).mid(0, standard.at(0).length() - 5) + << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 + << false << true; + + QTest::newRow("from cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 18 << 18 << 18 + << false << false; + + QTest::newRow("to cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 23 << 23 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 18 << 18 << 18 + << false << true; + + QTest::newRow("after cursor position (beginning)") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("before cursor position (end)") + << standard.at(0) << QQuickTextEdit::PlainText + << standard.at(0).length() << standard.at(0).length() + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << standard.at(0).length() - 5 << standard.at(0).length() - 5 << standard.at(0).length() - 5 + << false << true; + + QTest::newRow("before cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 23 << 23 + << 0 << 5 + << standard.at(0).mid(5) + << 18 << 18 << 18 + << false << true; + + QTest::newRow("after cursor position (middle)") + << standard.at(0) << QQuickTextEdit::PlainText + << 18 << 18 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 18 << 18 << 18 + << false << false; + + QTest::newRow("before selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 19 + << 0 << 5 + << standard.at(0).mid(5) + << 9 << 14 << 14 + << false << true; + + QTest::newRow("before reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 19 << 14 + << 0 << 5 + << standard.at(0).mid(5) + << 9 << 14 << 9 + << false << true; + + QTest::newRow("after selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 19 + << standard.at(0).length() - 5 << standard.at(0).length() + << standard.at(0).mid(0, standard.at(0).length() - 5) + << 14 << 19 << 19 + << false << false; + + QTest::newRow("after reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 19 << 14 + << standard.at(0).length() - 5 << standard.at(0).length() + << standard.at(0).mid(0, standard.at(0).length() - 5) + << 14 << 19 << 14 + << false << false; + + QTest::newRow("from selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 14 << 24 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 14 << 19 << 19 + << true << true; + + QTest::newRow("from reversed selection") + << standard.at(0) << QQuickTextEdit::PlainText + << 24 << 14 + << 18 << 23 + << standard.at(0).mid(0, 18) + standard.at(0).mid(23) + << 14 << 19 << 14 + << true << false; + + QTest::newRow("plain text cropped beginning") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << -3 << 4 + << standard.at(0).mid(4) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("plain text cropped end") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << 23 << standard.at(0).length() + 8 + << standard.at(0).mid(0, 23) + << 0 << 0 << 0 + << false << false; + + QTest::newRow("plain text cropped beginning and end") + << standard.at(0) << QQuickTextEdit::PlainText + << 0 << 0 + << -9 << standard.at(0).length() + 4 + << QString() + << 0 << 0 << 0 + << false << false; + + QTest::newRow("all rich text") + << richBoldText << QQuickTextEdit::RichText + << 0 << 0 + << 0 << plainBoldText.length() + << QString() + << 0 << 0 << 0 + << false << false; + + QTest::newRow("rick text sub string") + << richBoldText << QQuickTextEdit::RichText + << 0 << 0 + << 14 << 21 + << plainBoldText.mid(0, 14) + plainBoldText.mid(21) + << 0 << 0 << 0 + << false << false; +} + +void tst_qquicktextedit::remove() +{ + QFETCH(QString, text); + QFETCH(QQuickTextEdit::TextFormat, textFormat); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(int, removeStart); + QFETCH(int, removeEnd); + QFETCH(QString, expectedText); + QFETCH(int, expectedSelectionStart); + QFETCH(int, expectedSelectionEnd); + QFETCH(int, expectedCursorPosition); + QFETCH(bool, selectionChanged); + QFETCH(bool, cursorPositionChanged); + + QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + textEdit->setTextFormat(textFormat); + textEdit->select(selectionStart, selectionEnd); + + QSignalSpy selectionSpy(textEdit, SIGNAL(selectionChanged())); + QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged())); + QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged())); + QSignalSpy textSpy(textEdit, SIGNAL(textChanged(QString))); + QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged())); + + textEdit->remove(removeStart, removeEnd); + + if (textFormat == QQuickTextEdit::RichText + || (textFormat == QQuickTextEdit::AutoText && Qt::mightBeRichText(text))) { + QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText); + } else { + QCOMPARE(textEdit->text(), expectedText); + } + QCOMPARE(textEdit->length(), expectedText.length()); + + if (selectionStart > selectionEnd) // + qSwap(selectionStart, selectionEnd); + + QCOMPARE(textEdit->selectionStart(), expectedSelectionStart); + QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd); + QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition); + + QEXPECT_FAIL("from selection", "selectionChanged signal isn't emitted on edits within selection", Continue); + QEXPECT_FAIL("from reversed selection", "selectionChanged signal isn't emitted on edits within selection", Continue); + QCOMPARE(selectionSpy.count() > 0, selectionChanged); + QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart); + QEXPECT_FAIL("from reversed selection", "selectionEndChanged signal not emitted", Continue); + QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd); + QCOMPARE(textSpy.count() > 0, text != expectedText); + + + if (cursorPositionChanged) // + QVERIFY(cursorPositionSpy.count() > 0); +} + + +void tst_qquicktextedit::keySequence_data() +{ + QTest::addColumn("text"); + QTest::addColumn("sequence"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("expectedText"); + QTest::addColumn("selectedText"); + + // standard[0] == "the [4]quick [10]brown [16]fox [20]jumped [27]over [32]the [36]lazy [41]dog" + + QTest::newRow("select all") + << standard.at(0) << QKeySequence(QKeySequence::SelectAll) << 0 << 0 + << 44 << standard.at(0) << standard.at(0); + QTest::newRow("select end of line") + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfLine) << 5 << 5 + << 44 << standard.at(0) << standard.at(0).mid(5); + QTest::newRow("select end of document") + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfDocument) << 3 << 3 + << 44 << standard.at(0) << standard.at(0).mid(3); + QTest::newRow("select end of block") + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfBlock) << 18 << 18 + << 44 << standard.at(0) << standard.at(0).mid(18); + QTest::newRow("delete end of line") + << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfLine) << 24 << 24 + << 24 << standard.at(0).mid(0, 24) << QString(); + QTest::newRow("move to start of line") + << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfLine) << 31 << 31 + << 0 << standard.at(0) << QString(); + QTest::newRow("move to start of block") + << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfBlock) << 25 << 25 + << 0 << standard.at(0) << QString(); + QTest::newRow("move to next char") + << standard.at(0) << QKeySequence(QKeySequence::MoveToNextChar) << 12 << 12 + << 13 << standard.at(0) << QString(); + QTest::newRow("move to previous char") + << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousChar) << 3 << 3 + << 2 << standard.at(0) << QString(); + QTest::newRow("select next char") + << standard.at(0) << QKeySequence(QKeySequence::SelectNextChar) << 23 << 23 + << 24 << standard.at(0) << standard.at(0).mid(23, 1); + QTest::newRow("select previous char") + << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousChar) << 19 << 19 + << 18 << standard.at(0) << standard.at(0).mid(18, 1); + QTest::newRow("move to next word") + << standard.at(0) << QKeySequence(QKeySequence::MoveToNextWord) << 7 << 7 + << 10 << standard.at(0) << QString(); + QTest::newRow("move to previous word") + << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousWord) << 7 << 7 + << 4 << standard.at(0) << QString(); + QTest::newRow("select previous word") + << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousWord) << 11 << 11 + << 10 << standard.at(0) << standard.at(0).mid(10, 1); + QTest::newRow("delete (selection)") + << standard.at(0) << QKeySequence(QKeySequence::Delete) << 12 << 15 + << 12 << (standard.at(0).mid(0, 12) + standard.at(0).mid(15)) << QString(); + QTest::newRow("delete (no selection)") + << standard.at(0) << QKeySequence(QKeySequence::Delete) << 15 << 15 + << 15 << (standard.at(0).mid(0, 15) + standard.at(0).mid(16)) << QString(); + QTest::newRow("delete end of word") + << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfWord) << 24 << 24 + << 24 << (standard.at(0).mid(0, 24) + standard.at(0).mid(27)) << QString(); + QTest::newRow("delete start of word") + << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 + << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString(); +} + +void tst_qquicktextedit::keySequence() +{ + QFETCH(QString, text); + QFETCH(QKeySequence, sequence); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(int, cursorPosition); + QFETCH(QString, expectedText); + QFETCH(QString, selectedText); + + if (sequence.isEmpty()) { + QSKIP("Key sequence is undefined"); + } + + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true; text: \"" + text + "\" }"; + QDeclarativeComponent textEditComponent(&engine); + textEditComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textEdit = qobject_cast(textEditComponent.create()); + QVERIFY(textEdit != 0); + + QQuickCanvas canvas; + textEdit->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + textEdit->select(selectionStart, selectionEnd); + + simulateKeys(&canvas, sequence); + + QCOMPARE(textEdit->cursorPosition(), cursorPosition); + QCOMPARE(textEdit->text(), expectedText); + QCOMPARE(textEdit->selectedText(), selectedText); +} + +#define NORMAL 0 +#define REPLACE_UNTIL_END 1 + +void tst_qquicktextedit::undo_data() +{ + QTest::addColumn("insertString"); + QTest::addColumn("insertIndex"); + QTest::addColumn("insertMode"); + QTest::addColumn("expectedString"); + QTest::addColumn("use_keys"); + + for (int i=0; i<2; i++) { + QString keys_str = "keyboard"; + bool use_keys = true; + if (i==0) { + keys_str = "insert"; + use_keys = false; + } + + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "1"; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "5"; + + insertIndex << 1; + insertMode << NORMAL; + insertString << "3"; + + insertIndex << 1; + insertMode << NORMAL; + insertString << "2"; + + insertIndex << 3; + insertMode << NORMAL; + insertString << "4"; + + expectedString << "12345"; + expectedString << "1235"; + expectedString << "135"; + expectedString << "15"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_numbers").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "World"; // World + + insertIndex << 0; + insertMode << NORMAL; + insertString << "Hello"; // HelloWorld + + insertIndex << 0; + insertMode << NORMAL; + insertString << "Well"; // WellHelloWorld + + insertIndex << 9; + insertMode << NORMAL; + insertString << "There"; // WellHelloThereWorld; + + expectedString << "WellHelloThereWorld"; + expectedString << "WellHelloWorld"; + expectedString << "HelloWorld"; + expectedString << "World"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "Ensuring"; + + insertIndex << -1; + insertMode << NORMAL; + insertString << " instan"; + + insertIndex << 9; + insertMode << NORMAL; + insertString << "an "; + + insertIndex << 10; + insertMode << REPLACE_UNTIL_END; + insertString << " unique instance."; + + expectedString << "Ensuring a unique instance."; + expectedString << "Ensuring a "; // ### Not present in TextInput. + expectedString << "Ensuring an instan"; + expectedString << "Ensuring instan"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_patterns").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + } +} + +void tst_qquicktextedit::undo() +{ + QFETCH(QStringList, insertString); + QFETCH(IntList, insertIndex); + QFETCH(IntList, insertMode); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + int i; + +// STEP 1: First build up an undo history by inserting or typing some strings... + for (i = 0; i < insertString.size(); ++i) { + if (insertIndex[i] > -1) + textInput->setCursorPosition(insertIndex[i]); + + // experimental stuff + if (insertMode[i] == REPLACE_UNTIL_END) { + textInput->select(insertIndex[i], insertIndex[i] + 8); + + // This is what I actually want... + // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier); + } + + for (int j = 0; j < insertString.at(i).length(); j++) + QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); + } + +// STEP 2: Next call undo several times and see if we can restore to the previous state + for (i = 0; i < expectedString.size() - 1; ++i) { + QCOMPARE(textInput->text(), expectedString[i]); + simulateKeys(&canvas, QKeySequence::Undo); + } + +// STEP 3: Verify that we have undone everything + QVERIFY(textInput->text().isEmpty()); +} + +void tst_qquicktextedit::redo_data() +{ + QTest::addColumn("insertString"); + QTest::addColumn("insertIndex"); + QTest::addColumn("expectedString"); + + { + IntList insertIndex; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertString << "World"; // World + insertIndex << 0; + insertString << "Hello"; // HelloWorld + insertIndex << 0; + insertString << "Well"; // WellHelloWorld + insertIndex << 9; + insertString << "There"; // WellHelloThereWorld; + + expectedString << "World"; + expectedString << "HelloWorld"; + expectedString << "WellHelloWorld"; + expectedString << "WellHelloThereWorld"; + + QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString; + } +} + +void tst_qquicktextedit::redo() +{ + QFETCH(QStringList, insertString); + QFETCH(IntList, insertIndex); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + int i; + // inserts the diff strings at diff positions + for (i = 0; i < insertString.size(); ++i) { + if (insertIndex[i] > -1) + textInput->setCursorPosition(insertIndex[i]); + for (int j = 0; j < insertString.at(i).length(); j++) + QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); + } + + // undo everything + while (!textInput->text().isEmpty()) + simulateKeys(&canvas, QKeySequence::Undo); + + for (i = 0; i < expectedString.size(); ++i) { + simulateKeys(&canvas, QKeySequence::Redo); + QCOMPARE(textInput->text() , expectedString[i]); + } +} + +void tst_qquicktextedit::undo_keypressevents_data() +{ + QTest::addColumn("keys"); + QTest::addColumn("expectedString"); + + { + KeyList keys; + QStringList expectedString; + + keys << "AFRAID" + << Qt::Key_Home + << "VERY" + << Qt::Key_Left + << Qt::Key_Left + << Qt::Key_Left + << Qt::Key_Left + << "BE" + << Qt::Key_End + << "!"; + + expectedString << "BEVERYAFRAID!"; + expectedString << "BEVERYAFRAID"; + expectedString << "VERYAFRAID"; + expectedString << "AFRAID"; + + QTest::newRow("Inserts and moving cursor") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting '1234' + keys << "1234" << Qt::Key_Home + // skipping '12' + << Qt::Key_Right << Qt::Key_Right + // selecting '34' + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + // deleting '34' + << Qt::Key_Delete; + + expectedString << "12"; + expectedString << "1234"; + + QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'AB12' + keys << "AB12" + << Qt::Key_Home + // selecting 'AB' + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + << Qt::Key_Delete + << QKeySequence::Undo + // ### Text is selected in text input +// << Qt::Key_Right + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + << Qt::Key_Delete; + + expectedString << "AB"; + expectedString << "AB12"; + + QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'ABCD' + keys << "abcd" + //move left two + << Qt::Key_Left << Qt::Key_Left + // inserting '1234' + << "1234" + // selecting '1234' + << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) + // overwriting '1234' with '5' + << "5" + // undoing deletion of 'AB' + << QKeySequence::Undo + // ### Text is selected in text input + << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) + // overwriting '1234' with '6' + << "6"; + + expectedString << "ab6cd"; + // for versions previous to 3.2 we overwrite needed two undo operations + expectedString << "ab1234cd"; + expectedString << "abcd"; + + QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'ABC' + keys << "ABC" + // removes 'C' + << Qt::Key_Backspace; + + expectedString << "AB"; + expectedString << "ABC"; + + QTest::newRow("Inserts,backspace") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + keys << "ABC" + // removes 'C' + << Qt::Key_Backspace + // inserting 'Z' + << "Z"; + + expectedString << "ABZ"; + expectedString << "AB"; + expectedString << "ABC"; + + QTest::newRow("Inserts,backspace,inserts") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting '123' + keys << "123" << Qt::Key_Home + // selecting '123' + << (Qt::Key_End | Qt::ShiftModifier) + // overwriting '123' with 'ABC' + << "ABC"; + + expectedString << "ABC"; + // ### One operation in TextInput. + expectedString << "A"; + expectedString << "123"; + + QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString; + } +} + +void tst_qquicktextedit::undo_keypressevents() +{ + QFETCH(KeyList, keys); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextEdit *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + simulateKeys(&canvas, keys); + + for (int i = 0; i < expectedString.size(); ++i) { + QCOMPARE(textInput->text() , expectedString[i]); + simulateKeys(&canvas, QKeySequence::Undo); + } + QVERIFY(textInput->text().isEmpty()); +} + +void tst_qquicktextedit::emptytags_QTBUG_22058() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("qtbug-22058.qml"))); + QVERIFY(canvas.rootObject() != 0); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QQuickTextEdit *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("inputField"))); + QVERIFY(input->hasActiveFocus()); + + QInputMethodEvent event("", QList()); + event.setCommitString("Bold<"); + QGuiApplication::sendEvent(input, &event); + QCOMPARE(input->text(), QString("Bold<")); + event.setCommitString(">"); + QEXPECT_FAIL("", "Entering empty tags into a TextEdit asserts - QTBUG-22058", Abort); + QVERIFY(false); + QGuiApplication::sendEvent(input, &event); + QCOMPARE(input->text(), QString("Bold<>")); +} + +QTEST_MAIN(tst_qquicktextedit) + +#include "tst_qquicktextedit.moc" diff --git a/tests/auto/qtquick2/qquicktextinput/data/cursorTest.qml b/tests/auto/qtquick2/qquicktextinput/data/cursorTest.qml new file mode 100644 index 0000000000..71a420ee7c --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/cursorTest.qml @@ -0,0 +1,9 @@ +import QtQuick 2.0 + +Rectangle { id:rect; width: 300; height: 300; color: "white" + property string contextualProperty: "Hello" + TextInput { text: "Hello world!"; id: textInputObject; objectName: "textInputObject" + resources: [ Component { id:cursor; Item { id:cursorInstance; objectName: "cursorInstance"; property string localProperty: contextualProperty } } ] + cursorDelegate: cursor + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/cursorVisible.qml b/tests/auto/qtquick2/qquicktextinput/data/cursorVisible.qml new file mode 100644 index 0000000000..49e9386947 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/cursorVisible.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +Item { + width: 100 + height: 20 +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/echoMode.qml b/tests/auto/qtquick2/qquicktextinput/data/echoMode.qml new file mode 100644 index 0000000000..f8a6cf1c89 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/echoMode.qml @@ -0,0 +1,11 @@ +import QtQuick 2.0 + +Rectangle { + property QtObject myInput: input + + width: 400; height: 200; color: "green" + + TextInput { id: input; focus: true + text: "ABCDefgh" + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/geometrySignals.qml b/tests/auto/qtquick2/qquicktextinput/data/geometrySignals.qml new file mode 100644 index 0000000000..90855a61cf --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/geometrySignals.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Item { + width: 400; height: 500; + property int bindingWidth: text.width + property int bindingHeight: text.height + + TextEdit { + id: text + anchors.fill: parent + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/halign_center.png b/tests/auto/qtquick2/qquicktextinput/data/halign_center.png new file mode 100644 index 0000000000..53e09a8e5b Binary files /dev/null and b/tests/auto/qtquick2/qquicktextinput/data/halign_center.png differ diff --git a/tests/auto/qtquick2/qquicktextinput/data/halign_left.png b/tests/auto/qtquick2/qquicktextinput/data/halign_left.png new file mode 100644 index 0000000000..247acbc9df Binary files /dev/null and b/tests/auto/qtquick2/qquicktextinput/data/halign_left.png differ diff --git a/tests/auto/qtquick2/qquicktextinput/data/halign_right.png b/tests/auto/qtquick2/qquicktextinput/data/halign_right.png new file mode 100644 index 0000000000..691bc75c89 Binary files /dev/null and b/tests/auto/qtquick2/qquicktextinput/data/halign_right.png differ diff --git a/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment.qml b/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment.qml new file mode 100644 index 0000000000..e0fef4c11e --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 70; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "Test" + + Rectangle { + anchors.centerIn: parent + width: 60 + height: 20 + color: "green" + + TextInput { + id: text + anchors.fill: parent + text: top.text + } + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment_RightToLeft.qml b/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment_RightToLeft.qml new file mode 100644 index 0000000000..5f88025536 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/horizontalAlignment_RightToLeft.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + id: top + width: 200; height: 70; + + property alias horizontalAlignment: text.horizontalAlignment + property string text: "اختبا" + + Rectangle { + anchors.centerIn: parent + width: 180 + height: 20 + color: "green" + + TextInput { + id: text + objectName: "text" + anchors.fill: parent + text: top.text + focus: true + } + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/inputContext.qml b/tests/auto/qtquick2/qquicktextinput/data/inputContext.qml new file mode 100644 index 0000000000..dfc80990c6 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/inputContext.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextInput { + width: 200 + text: "supercalifra" + focus: true + cursorPosition: 12 +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/inputMethodEvent.qml b/tests/auto/qtquick2/qquicktextinput/data/inputMethodEvent.qml new file mode 100644 index 0000000000..7aefdf28f4 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/inputMethodEvent.qml @@ -0,0 +1,6 @@ +import QtQuick 2.0 + +TextInput { + focus: true + autoScroll: false +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/inputmethods.qml b/tests/auto/qtquick2/qquicktextinput/data/inputmethods.qml new file mode 100644 index 0000000000..711e89144c --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/inputmethods.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput { + text: "Hello world!" + inputMethodHints: Qt.ImhNoPredictiveText + Keys.onLeftPressed: {} +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/masks.qml b/tests/auto/qtquick2/qquicktextinput/data/masks.qml new file mode 100644 index 0000000000..589b6a3c15 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/masks.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput{ + focus: true + objectName: "myInput" + inputMask: "HHHHhhhh; " +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/maxLength.qml b/tests/auto/qtquick2/qquicktextinput/data/maxLength.qml new file mode 100644 index 0000000000..cca537ed6b --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/maxLength.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput{ + focus: true + objectName: "myInput" + maximumLength: 10 +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/mouseselection_true.qml b/tests/auto/qtquick2/qquicktextinput/data/mouseselection_true.qml new file mode 100644 index 0000000000..974041b04a --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/mouseselection_true.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_characters.qml b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_characters.qml new file mode 100644 index 0000000000..f7c658b618 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_characters.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectCharacters +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_default.qml b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_default.qml new file mode 100644 index 0000000000..974041b04a --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_default.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_words.qml b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_words.qml new file mode 100644 index 0000000000..20e777e470 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/mouseselectionmode_words.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectWords +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/navigation.qml b/tests/auto/qtquick2/qquicktextinput/data/navigation.qml new file mode 100644 index 0000000000..3a7d07b3c7 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/navigation.qml @@ -0,0 +1,24 @@ +import QtQuick 2.0 + +Rectangle { + property variant myInput: input + + width: 800; height: 600; color: "blue" + + Item { + id: firstItem; + KeyNavigation.right: input + } + + TextInput { id: input; focus: true + text: "Needs some text" + KeyNavigation.left: firstItem + KeyNavigation.right: lastItem + KeyNavigation.up: firstItem + KeyNavigation.down: lastItem + } + Item { + id: lastItem + KeyNavigation.left: input + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/openInputPanel.qml b/tests/auto/qtquick2/qquicktextinput/data/openInputPanel.qml new file mode 100644 index 0000000000..ca5cb263aa --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/openInputPanel.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput { + width: 100; height: 100 + text: "Hello world" + focus: false +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/positionAt.qml b/tests/auto/qtquick2/qquicktextinput/data/positionAt.qml new file mode 100644 index 0000000000..1840462c87 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/positionAt.qml @@ -0,0 +1,8 @@ +import QtQuick 2.0 + +TextInput{ + focus: true + objectName: "myInput" + width: 50 + text: "AAAAAAAAAAAAAAAAAAAAAAAAAAAA" +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/preeditAutoScroll.qml b/tests/auto/qtquick2/qquicktextinput/data/preeditAutoScroll.qml new file mode 100644 index 0000000000..9d98a2e220 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/preeditAutoScroll.qml @@ -0,0 +1,7 @@ +import QtQuick 2.0 + +TextInput { + focus: true + text: "super" + autoScroll: true +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956double.qml b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956double.qml new file mode 100644 index 0000000000..e9b80fceb2 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956double.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +TextInput { + id: textinput + property real topvalue: 30 + property real bottomvalue: 10 + height: 50 + width: 200 + text: "20" + validator: DoubleValidator { + id: doublevalidator + bottom: bottomvalue + top: topvalue + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956int.qml b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956int.qml new file mode 100644 index 0000000000..0d70eedb80 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956int.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +TextInput { + id: textinput + property real topvalue: 30 + property real bottomvalue: 10 + height: 50 + width: 200 + text: "20" + validator: IntValidator { + id: intvalidator + bottom: bottomvalue + top: topvalue + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956regexp.qml b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956regexp.qml new file mode 100644 index 0000000000..b5af13cc4c --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/qtbug-19956regexp.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +TextInput { + id: textinput + property variant regexvalue + height: 50 + width: 200 + text: "abc" + validator: RegExpValidator { + id: regexpvalidator + regExp: regexvalue + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/readOnly.qml b/tests/auto/qtquick2/qquicktextinput/data/readOnly.qml new file mode 100644 index 0000000000..9cda7fbd1d --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/readOnly.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +Rectangle { + property variant myInput: input + + width: 800; height: 600; color: "blue" + + TextInput { id: input; focus: true + readOnly: true + text: "I am the very model of a modern major general.\n" + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/data/validators.qml b/tests/auto/qtquick2/qquicktextinput/data/validators.qml new file mode 100644 index 0000000000..0a074ce7dc --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/validators.qml @@ -0,0 +1,22 @@ +import QtQuick 2.0 + +Item { + property variant intInput: intInput + property variant dblInput: dblInput + property variant strInput: strInput + + width: 800; height: 600; + + Column{ + TextInput { id: intInput; + validator: IntValidator{top: 11; bottom: 2} + } + TextInput { id: dblInput; + validator: DoubleValidator{top: 12.12; bottom: 2.93; decimals: 2; notation: DoubleValidator.StandardNotation} + } + TextInput { id: strInput; + validator: RegExpValidator { regExp: /[a-zA-z]{2,4}/ } + } + } + +} diff --git a/tests/auto/qtquick2/qquicktextinput/qquicktextinput.pro b/tests/auto/qtquick2/qquicktextinput/qquicktextinput.pro new file mode 100644 index 0000000000..f81da61634 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/qquicktextinput.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TARGET = tst_qquicktextinput +macx:CONFIG -= app_bundle + +SOURCES += tst_qquicktextinput.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp new file mode 100644 index 0000000000..57b2df11c9 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -0,0 +1,3310 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include "../../shared/util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_MAC +#include +#endif + +#include "qplatformdefs.h" + +Q_DECLARE_METATYPE(QQuickTextInput::SelectionMode) +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + +QString createExpectedFileIfNotFound(const QString& filebasename, const QImage& actual) +{ + // XXX This will be replaced by some clever persistent platform image store. + QString persistent_dir = TESTDATA(""); + QString arch = "unknown-architecture"; // QTest needs to help with this. + + QString expectfile = persistent_dir + QDir::separator() + filebasename + "-" + arch + ".png"; + + if (!QFile::exists(expectfile)) { + actual.save(expectfile); + qWarning() << "created" << expectfile; + } + + return expectfile; +} + +typedef QPair Key; + +class tst_qquicktextinput : public QObject + +{ + Q_OBJECT +public: + tst_qquicktextinput(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void cleanup(); + void text(); + void width(); + void font(); + void color(); + void selection(); + void isRightToLeft_data(); + void isRightToLeft(); + void moveCursorSelection_data(); + void moveCursorSelection(); + void moveCursorSelectionSequence_data(); + void moveCursorSelectionSequence(); + void dragMouseSelection(); + void mouseSelectionMode_data(); + void mouseSelectionMode(); + void tripleClickSelectsAll(); + + void horizontalAlignment_data(); + void horizontalAlignment(); + void horizontalAlignment_RightToLeft(); + + void positionAt(); + + void maxLength(); + void masks(); + void validators(); + void inputMethods(); + + void passwordCharacter(); + void cursorDelegate(); + void cursorVisible(); + void cursorRectangle(); + void navigation(); + void navigation_RTL(); + void copyAndPaste(); + void copyAndPasteKeySequence(); + void canPasteEmpty(); + void canPaste(); + void readOnly(); + + void openInputPanel(); + void setHAlignClearCache(); + void focusOutClearSelection(); + + void echoMode(); +#ifdef QT_GUI_PASSWORD_ECHO_DELAY + void passwordEchoDelay(); +#endif + void geometrySignals(); + void testQtQuick11Attributes(); + void testQtQuick11Attributes_data(); + + void preeditAutoScroll(); + void preeditCursorRectangle(); + void inputContextMouseHandler(); + void inputMethodComposing(); + void cursorRectangleSize(); + + void keySequence_data(); + void keySequence(); + + void undo_data(); + void undo(); + void redo_data(); + void redo(); + void undo_keypressevents_data(); + void undo_keypressevents(); + + void QTBUG_19956(); + void QTBUG_19956_data(); + void QTBUG_19956_regexp(); + +private: + void simulateKey(QQuickView *, int key); + + void simulateKeys(QWindow *window, const QList &keys); + void simulateKeys(QWindow *window, const QKeySequence &sequence); + + QDeclarativeEngine engine; + QStringList standard; + QStringList colorStrings; +}; + +typedef QList IntList; +Q_DECLARE_METATYPE(IntList) + +typedef QList KeyList; +Q_DECLARE_METATYPE(KeyList) + +void tst_qquicktextinput::simulateKeys(QWindow *window, const QList &keys) +{ + for (int i = 0; i < keys.count(); ++i) { + const int key = keys.at(i).first; + const int modifiers = key & Qt::KeyboardModifierMask; + const QString text = !keys.at(i).second.isNull() ? QString(keys.at(i).second) : QString(); + + QKeyEvent press(QEvent::KeyPress, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); + QKeyEvent release(QEvent::KeyRelease, Qt::Key(key), Qt::KeyboardModifiers(modifiers), text); + + QGuiApplication::sendEvent(window, &press); + QGuiApplication::sendEvent(window, &release); + } +} + +void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequence) +{ + for (uint i = 0; i < sequence.count(); ++i) { + const int key = sequence[i]; + const int modifiers = key & Qt::KeyboardModifierMask; + + QTest::keyClick(window, Qt::Key(key & ~modifiers), Qt::KeyboardModifiers(modifiers)); + } +} + +QList &operator <<(QList &keys, const QKeySequence &sequence) +{ + for (uint i = 0; i < sequence.count(); ++i) + keys << Key(sequence[i], QChar()); + return keys; +} + +template QList &operator <<(QList &keys, const char (&characters)[N]) +{ + for (int i = 0; i < N - 1; ++i) { + int key = QTest::asciiToKey(characters[i]); + QChar character = QLatin1Char(characters[i]); + keys << Key(key, character); + } + return keys; +} + +QList &operator <<(QList &keys, Qt::Key key) +{ + keys << Key(key, QChar()); + return keys; +} + +void tst_qquicktextinput::initTestCase() +{ +} + +void tst_qquicktextinput::cleanupTestCase() +{ +} + +void tst_qquicktextinput::cleanup() +{ + // ensure not even skipped tests with custom input context leave it dangling + QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); + inputPanelPrivate->testContext = 0; +} + +tst_qquicktextinput::tst_qquicktextinput() +{ + standard << "the quick brown fox jumped over the lazy dog" + << "It's supercalifragisiticexpialidocious!" + << "Hello, world!" + << "!dlrow ,olleH" + << " spacey text "; + + colorStrings << "aliceblue" + << "antiquewhite" + << "aqua" + << "darkkhaki" + << "darkolivegreen" + << "dimgray" + << "palevioletred" + << "lightsteelblue" + << "#000000" + << "#AAAAAA" + << "#FFFFFF" + << "#2AC05F"; +} + +void tst_qquicktextinput::text() +{ + { + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData("import QtQuick 2.0\nTextInput { text: \"\" }", QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->text(), QString("")); + + delete textinputObject; + } + + for (int i = 0; i < standard.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->text(), standard.at(i)); + + delete textinputObject; + } + +} + +void tst_qquicktextinput::width() +{ + // uses Font metrics to find the width for standard + { + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData("import QtQuick 2.0\nTextInput { text: \"\" }", QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->width(), 0.0); + + delete textinputObject; + } + + bool requiresUnhintedMetrics = !qmlDisableDistanceField(); + + for (int i = 0; i < standard.size(); i++) + { + QFont f; + qreal metricWidth = 0.0; + if (requiresUnhintedMetrics) { + QString s = standard.at(i); + s.replace(QLatin1Char('\n'), QChar::LineSeparator); + + QTextLayout layout(s); + layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic); + { + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + } + + layout.beginLayout(); + forever { + QTextLine line = layout.createLine(); + if (!line.isValid()) + break; + } + + layout.endLayout(); + + metricWidth = ceil(layout.boundingRect().width()); + } else { + QFontMetricsF fm(f); + metricWidth = fm.width(standard.at(i)); + } + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + standard.at(i) + "\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + int delta = abs(int(int(textinputObject->width()) - metricWidth)); + QVERIFY(delta <= 3.0); // As best as we can hope for cross-platform. + + delete textinputObject; + } +} + +void tst_qquicktextinput::font() +{ + //test size, then bold, then italic, then family + { + QString componentStr = "import QtQuick 2.0\nTextInput { font.pointSize: 40; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->font().pointSize(), 40); + QCOMPARE(textinputObject->font().bold(), false); + QCOMPARE(textinputObject->font().italic(), false); + + delete textinputObject; + } + + { + QString componentStr = "import QtQuick 2.0\nTextInput { font.bold: true; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->font().bold(), true); + QCOMPARE(textinputObject->font().italic(), false); + + delete textinputObject; + } + + { + QString componentStr = "import QtQuick 2.0\nTextInput { font.italic: true; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->font().italic(), true); + QCOMPARE(textinputObject->font().bold(), false); + + delete textinputObject; + } + + { + QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"Helvetica\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->font().family(), QString("Helvetica")); + QCOMPARE(textinputObject->font().bold(), false); + QCOMPARE(textinputObject->font().italic(), false); + + delete textinputObject; + } + + { + QString componentStr = "import QtQuick 2.0\nTextInput { font.family: \"\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->font().family(), QString("")); + + delete textinputObject; + } +} + +void tst_qquicktextinput::color() +{ + //test color + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextInput { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->color(), QColor(colorStrings.at(i))); + + delete textinputObject; + } + + //test selection color + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextInput { selectionColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->selectionColor(), QColor(colorStrings.at(i))); + + delete textinputObject; + } + + //test selected text color + for (int i = 0; i < colorStrings.size(); i++) + { + QString componentStr = "import QtQuick 2.0\nTextInput { selectedTextColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->selectedTextColor(), QColor(colorStrings.at(i))); + + delete textinputObject; + } + + { + QString colorStr = "#AA001234"; + QColor testColor("#001234"); + testColor.setAlpha(170); + + QString componentStr = "import QtQuick 2.0\nTextInput { color: \"" + colorStr + "\"; text: \"Hello World\" }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + + QVERIFY(textinputObject != 0); + QCOMPARE(textinputObject->color(), testColor); + + delete textinputObject; + } +} + +void tst_qquicktextinput::selection() +{ + QString testStr = standard[0]; + QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + + //Test selection follows cursor + for (int i=0; i<= testStr.size(); i++) { + textinputObject->setCursorPosition(i); + QCOMPARE(textinputObject->cursorPosition(), i); + QCOMPARE(textinputObject->selectionStart(), i); + QCOMPARE(textinputObject->selectionEnd(), i); + QVERIFY(textinputObject->selectedText().isNull()); + } + + textinputObject->setCursorPosition(0); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + + // Verify invalid positions are ignored. + textinputObject->setCursorPosition(-1); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + + textinputObject->setCursorPosition(textinputObject->text().count()+1); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + + //Test selection + for (int i=0; i<= testStr.size(); i++) { + textinputObject->select(0,i); + QCOMPARE(testStr.mid(0,i), textinputObject->selectedText()); + } + for (int i=0; i<= testStr.size(); i++) { + textinputObject->select(i,testStr.size()); + QCOMPARE(testStr.mid(i,testStr.size()-i), textinputObject->selectedText()); + } + + textinputObject->setCursorPosition(0); + QVERIFY(textinputObject->cursorPosition() == 0); + QVERIFY(textinputObject->selectionStart() == 0); + QVERIFY(textinputObject->selectionEnd() == 0); + QVERIFY(textinputObject->selectedText().isNull()); + + //Test Error Ignoring behaviour + textinputObject->setCursorPosition(0); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(-10,0); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(100,110); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(0,-10); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(0,100); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(0,10); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->select(-10,10); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->select(100,101); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->select(0,-10); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->select(0,100); + QVERIFY(textinputObject->selectedText().size() == 10); + + textinputObject->deselect(); + QVERIFY(textinputObject->selectedText().isNull()); + textinputObject->select(0,10); + QVERIFY(textinputObject->selectedText().size() == 10); + textinputObject->deselect(); + QVERIFY(textinputObject->selectedText().isNull()); + + // test input method selection + QSignalSpy selectionSpy(textinputObject, SIGNAL(selectedTextChanged())); + textinputObject->setFocus(true); + { + QList attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 12, 5, QVariant()); + QInputMethodEvent event("", attributes); + QApplication::sendEvent(textinputObject, &event); + } + QCOMPARE(selectionSpy.count(), 1); + QCOMPARE(textinputObject->selectionStart(), 12); + QCOMPARE(textinputObject->selectionEnd(), 17); + + delete textinputObject; +} + +void tst_qquicktextinput::isRightToLeft_data() +{ + QTest::addColumn("text"); + QTest::addColumn("emptyString"); + QTest::addColumn("firstCharacter"); + QTest::addColumn("lastCharacter"); + QTest::addColumn("middleCharacter"); + QTest::addColumn("startString"); + QTest::addColumn("midString"); + QTest::addColumn("endString"); + + const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; + QTest::newRow("Empty") << "" << false << false << false << false << false << false << false; + QTest::newRow("Neutral") << "23244242" << false << false << false << false << false << false << false; + QTest::newRow("LTR") << "Hello world" << false << false << false << false << false << false << false; + QTest::newRow("RTL") << QString::fromUtf16(arabic_str, 11) << false << true << true << true << true << true << true; + QTest::newRow("Bidi RTL + LTR + RTL") << QString::fromUtf16(arabic_str, 11) + QString("Hello world") + QString::fromUtf16(arabic_str, 11) << false << true << true << false << true << true << true; + QTest::newRow("Bidi LTR + RTL + LTR") << QString("Hello world") + QString::fromUtf16(arabic_str, 11) + QString("Hello world") << false << false << false << true << false << false << false; +} + +void tst_qquicktextinput::isRightToLeft() +{ + QFETCH(QString, text); + QFETCH(bool, emptyString); + QFETCH(bool, firstCharacter); + QFETCH(bool, lastCharacter); + QFETCH(bool, middleCharacter); + QFETCH(bool, startString); + QFETCH(bool, midString); + QFETCH(bool, endString); + + QQuickTextInput textInput; + textInput.setText(text); + + // first test that the right string is delivered to the QString::isRightToLeft() + QCOMPARE(textInput.isRightToLeft(0,0), text.mid(0,0).isRightToLeft()); + QCOMPARE(textInput.isRightToLeft(0,1), text.mid(0,1).isRightToLeft()); + QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), text.mid(text.count()-2, text.count()-1).isRightToLeft()); + QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), text.mid(text.count()/2, text.count()/2 + 1).isRightToLeft()); + QCOMPARE(textInput.isRightToLeft(0,text.count()/4), text.mid(0,text.count()/4).isRightToLeft()); + QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), text.mid(text.count()/4,3*text.count()/4).isRightToLeft()); + if (text.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ": QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start."); + QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), text.mid(3*text.count()/4,text.count()-1).isRightToLeft()); + + // then test that the feature actually works + QCOMPARE(textInput.isRightToLeft(0,0), emptyString); + QCOMPARE(textInput.isRightToLeft(0,1), firstCharacter); + QCOMPARE(textInput.isRightToLeft(text.count()-2, text.count()-1), lastCharacter); + QCOMPARE(textInput.isRightToLeft(text.count()/2, text.count()/2 + 1), middleCharacter); + QCOMPARE(textInput.isRightToLeft(0,text.count()/4), startString); + QCOMPARE(textInput.isRightToLeft(text.count()/4,3*text.count()/4), midString); + if (text.isEmpty()) + QTest::ignoreMessage(QtWarningMsg, ": QML TextInput: isRightToLeft(start, end) called with the end property being smaller than the start."); + QCOMPARE(textInput.isRightToLeft(3*text.count()/4,text.count()-1), endString); +} + +void tst_qquicktextinput::moveCursorSelection_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition"); + QTest::addColumn("mode"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("reversible"); + + // () contains the text selected by the cursor. + // <> contains the actual selection. + + QTest::newRow("(t)he|characters") + << standard[0] << 0 << 1 << QQuickTextInput::SelectCharacters << 0 << 1 << true; + QTest::newRow("do(g)|characters") + << standard[0] << 43 << 44 << QQuickTextInput::SelectCharacters << 43 << 44 << true; + QTest::newRow("jum(p)ed|characters") + << standard[0] << 23 << 24 << QQuickTextInput::SelectCharacters << 23 << 24 << true; + QTest::newRow("jumped( )over|characters") + << standard[0] << 26 << 27 << QQuickTextInput::SelectCharacters << 26 << 27 << true; + QTest::newRow("(the )|characters") + << standard[0] << 0 << 4 << QQuickTextInput::SelectCharacters << 0 << 4 << true; + QTest::newRow("( dog)|characters") + << standard[0] << 40 << 44 << QQuickTextInput::SelectCharacters << 40 << 44 << true; + QTest::newRow("( jumped )|characters") + << standard[0] << 19 << 27 << QQuickTextInput::SelectCharacters << 19 << 27 << true; + QTest::newRow("th(e qu)ick|characters") + << standard[0] << 2 << 6 << QQuickTextInput::SelectCharacters << 2 << 6 << true; + QTest::newRow("la(zy d)og|characters") + << standard[0] << 38 << 42 << QQuickTextInput::SelectCharacters << 38 << 42 << true; + QTest::newRow("jum(ped ov)er|characters") + << standard[0] << 23 << 29 << QQuickTextInput::SelectCharacters << 23 << 29 << true; + QTest::newRow("()the|characters") + << standard[0] << 0 << 0 << QQuickTextInput::SelectCharacters << 0 << 0 << true; + QTest::newRow("dog()|characters") + << standard[0] << 44 << 44 << QQuickTextInput::SelectCharacters << 44 << 44 << true; + QTest::newRow("jum()ped|characters") + << standard[0] << 23 << 23 << QQuickTextInput::SelectCharacters << 23 << 23 << true; + + QTest::newRow("<(t)he>|words") + << standard[0] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 3 << true; + QTest::newRow("|words") + << standard[0] << 43 << 44 << QQuickTextInput::SelectWords << 41 << 44 << true; + QTest::newRow("|words") + << standard[0] << 23 << 24 << QQuickTextInput::SelectWords << 20 << 26 << true; + QTest::newRow("over|words,ltr") + << standard[0] << 26 << 27 << QQuickTextInput::SelectWords << 20 << 27 << false; + QTest::newRow("jumped<( )over>|words,rtl") + << standard[0] << 27 << 26 << QQuickTextInput::SelectWords << 26 << 31 << false; + QTest::newRow("<(the )>quick|words,ltr") + << standard[0] << 0 << 4 << QQuickTextInput::SelectWords << 0 << 4 << false; + QTest::newRow("<(the )quick>|words,rtl") + << standard[0] << 4 << 0 << QQuickTextInput::SelectWords << 0 << 9 << false; + QTest::newRow("|words,ltr") + << standard[0] << 40 << 44 << QQuickTextInput::SelectWords << 36 << 44 << false; + QTest::newRow("lazy<( dog)>|words,rtl") + << standard[0] << 44 << 40 << QQuickTextInput::SelectWords << 40 << 44 << false; + QTest::newRow("over|words,ltr") + << standard[0] << 19 << 27 << QQuickTextInput::SelectWords << 16 << 27 << false; + QTest::newRow("fox<( jumped )over>|words,rtl") + << standard[0] << 27 << 19 << QQuickTextInput::SelectWords << 19 << 31 << false; + QTest::newRow("|words") + << standard[0] << 2 << 6 << QQuickTextInput::SelectWords << 0 << 9 << true; + QTest::newRow("") + << standard[0] << 38 << 42 << QQuickTextInput::SelectWords << 36 << 44 << true; + QTest::newRow("|words") + << standard[0] << 23 << 29 << QQuickTextInput::SelectWords << 20 << 31 << true; + QTest::newRow("<()>the|words") + << standard[0] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true; + QTest::newRow("dog<()>|words") + << standard[0] << 44 << 44 << QQuickTextInput::SelectWords << 44 << 44 << true; + QTest::newRow("jum<()>ped|words") + << standard[0] << 23 << 23 << QQuickTextInput::SelectWords << 23 << 23 << true; + + QTest::newRow("Hello<(,)> |words") + << standard[2] << 5 << 6 << QQuickTextInput::SelectWords << 5 << 6 << true; + QTest::newRow("Hello<(, )>world|words,ltr") + << standard[2] << 5 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello<(, )world>|words,rtl") + << standard[2] << 7 << 5 << QQuickTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("world|words,ltr") + << standard[2] << 3 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("|words,rtl") + << standard[2] << 7 << 3 << QQuickTextInput::SelectWords << 0 << 12 << false; + QTest::newRow(",|words") + << standard[2] << 3 << 5 << QQuickTextInput::SelectWords << 0 << 5 << true; + QTest::newRow("Hello<()>,|words") + << standard[2] << 5 << 5 << QQuickTextInput::SelectWords << 5 << 5 << true; + QTest::newRow("Hello,<()>|words") + << standard[2] << 6 << 6 << QQuickTextInput::SelectWords << 6 << 6 << true; + QTest::newRow("Hello<,( )>world|words,ltr") + << standard[2] << 6 << 7 << QQuickTextInput::SelectWords << 5 << 7 << false; + QTest::newRow("Hello,<( )world>|words,rtl") + << standard[2] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world)>|words,ltr") + << standard[2] << 6 << 12 << QQuickTextInput::SelectWords << 5 << 12 << false; + QTest::newRow("Hello,<( world)>|words,rtl") + << standard[2] << 12 << 6 << QQuickTextInput::SelectWords << 6 << 12 << false; + QTest::newRow("Hello<,( world!)>|words,ltr") + << standard[2] << 6 << 13 << QQuickTextInput::SelectWords << 5 << 13 << false; + QTest::newRow("Hello,<( world!)>|words,rtl") + << standard[2] << 13 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false; + QTest::newRow("Hello<(, world!)>|words") + << standard[2] << 5 << 13 << QQuickTextInput::SelectWords << 5 << 13 << true; + // Fails due to an issue with QTextBoundaryFinder and punctuation at the end of strings. + // QTBUG-11365 + // QTest::newRow("world<(!)>|words") + // << standard[2] << 12 << 13 << QQuickTextInput::SelectWords << 12 << 13 << true; + QTest::newRow("world!<()>)|words") + << standard[2] << 13 << 13 << QQuickTextInput::SelectWords << 13 << 13 << true; + QTest::newRow("world<()>!)|words") + << standard[2] << 12 << 12 << QQuickTextInput::SelectWords << 12 << 12 << true; + + QTest::newRow("<(,)>olleH |words") + << standard[3] << 7 << 8 << QQuickTextInput::SelectWords << 7 << 8 << true; + QTest::newRow("olleH|words,ltr") + << standard[3] << 6 << 8 << QQuickTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("dlrow<( ,)>olleH|words,rtl") + << standard[3] << 8 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("|words,ltr") + << standard[3] << 6 << 10 << QQuickTextInput::SelectWords << 1 << 13 << false; + QTest::newRow("dlrow<( ,ol)leH>|words,rtl") + << standard[3] << 10 << 6 << QQuickTextInput::SelectWords << 6 << 13 << false; + QTest::newRow(",<(ol)leH>,|words") + << standard[3] << 8 << 10 << QQuickTextInput::SelectWords << 8 << 13 << true; + QTest::newRow(",<()>olleH|words") + << standard[3] << 8 << 8 << QQuickTextInput::SelectWords << 8 << 8 << true; + QTest::newRow("<()>,olleH|words") + << standard[3] << 7 << 7 << QQuickTextInput::SelectWords << 7 << 7 << true; + QTest::newRow(",olleH|words,ltr") + << standard[3] << 6 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("dlrow<( ),>olleH|words,rtl") + << standard[3] << 7 << 6 << QQuickTextInput::SelectWords << 6 << 8 << false; + QTest::newRow("<(dlrow )>,olleH|words,ltr") + << standard[3] << 1 << 7 << QQuickTextInput::SelectWords << 1 << 7 << false; + QTest::newRow("<(dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 1 << QQuickTextInput::SelectWords << 1 << 8 << false; + QTest::newRow("<(!dlrow )>,olleH|words,ltr") + << standard[3] << 0 << 7 << QQuickTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("<(!dlrow ),>olleH|words,rtl") + << standard[3] << 7 << 0 << QQuickTextInput::SelectWords << 0 << 8 << false; + QTest::newRow("(!dlrow ,)olleH|words") + << standard[3] << 0 << 8 << QQuickTextInput::SelectWords << 0 << 8 << true; + QTest::newRow("<(!)>dlrow|words") + << standard[3] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << true; + QTest::newRow("<()>!dlrow|words") + << standard[3] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << true; + QTest::newRow("!<()>dlrow|words") + << standard[3] << 1 << 1 << QQuickTextInput::SelectWords << 1 << 1 << true; + + QTest::newRow(" text |words") + << standard[4] << 1 << 4 << QQuickTextInput::SelectWords << 1 << 7 << true; + QTest::newRow(" spacey |words") + << standard[4] << 11 << 13 << QQuickTextInput::SelectWords << 10 << 14 << false; // Should be reversible. QTBUG-11365 + QTest::newRow("<( )>spacey text |words|ltr") + << standard[4] << 0 << 1 << QQuickTextInput::SelectWords << 0 << 1 << false; + QTest::newRow("<( )spacey> text |words|rtl") + << standard[4] << 1 << 0 << QQuickTextInput::SelectWords << 0 << 7 << false; + QTest::newRow("spacey |words|ltr") + << standard[4] << 14 << 15 << QQuickTextInput::SelectWords << 10 << 15 << false; +// QTBUG-11365 +// QTest::newRow("spacey text<( )>|words|rtl") +// << standard[4] << 15 << 14 << QQuickTextInput::SelectWords << 14 << 15 << false; + QTest::newRow("<()> spacey text |words") + << standard[4] << 0 << 0 << QQuickTextInput::SelectWords << 0 << 0 << false; + QTest::newRow(" spacey text <()>|words") + << standard[4] << 15 << 15 << QQuickTextInput::SelectWords << 15 << 15 << false; +} + +void tst_qquicktextinput::moveCursorSelection() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition); + QFETCH(QQuickTextInput::SelectionMode, mode); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(bool, reversible); + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + textinputObject->setCursorPosition(cursorPosition); + textinputObject->moveCursorSelection(movePosition, mode); + + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(textinputObject->selectionStart(), selectionStart); + QCOMPARE(textinputObject->selectionEnd(), selectionEnd); + + if (reversible) { + textinputObject->setCursorPosition(movePosition); + textinputObject->moveCursorSelection(cursorPosition, mode); + + QCOMPARE(textinputObject->selectedText(), testStr.mid(selectionStart, selectionEnd - selectionStart)); + QCOMPARE(textinputObject->selectionStart(), selectionStart); + QCOMPARE(textinputObject->selectionEnd(), selectionEnd); + } + + delete textinputObject; +} + +void tst_qquicktextinput::moveCursorSelectionSequence_data() +{ + QTest::addColumn("testStr"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("movePosition1"); + QTest::addColumn("movePosition2"); + QTest::addColumn("selection1Start"); + QTest::addColumn("selection1End"); + QTest::addColumn("selection2Start"); + QTest::addColumn("selection2End"); + + // () contains the text selected by the cursor. + // <> contains the actual selection. + // ^ is the revised cursor position. + // {} contains the revised selection. + + QTest::newRow("the { f^ox} jumped|ltr") + << standard[0] + << 9 << 13 << 17 + << 4 << 15 + << 4 << 19; + QTest::newRow("the quick<( {bro)wn> f^ox} jumped|rtl") + << standard[0] + << 13 << 9 << 17 + << 9 << 15 + << 10 << 19; + QTest::newRow("the { ^}fox jumped|ltr") + << standard[0] + << 9 << 13 << 16 + << 4 << 15 + << 4 << 16; + QTest::newRow("the quick<( {bro)wn> ^}fox jumped|rtl") + << standard[0] + << 13 << 9 << 16 + << 9 << 15 + << 10 << 16; + QTest::newRow("the {} fox jumped|ltr") + << standard[0] + << 9 << 13 << 15 + << 4 << 15 + << 4 << 15; + QTest::newRow("the quick<( {bro)wn^>} f^ox jumped|rtl") + << standard[0] + << 13 << 9 << 15 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 10 + << 4 << 15 + << 4 << 10; + QTest::newRow("the quick<( {^bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 10 + << 9 << 15 + << 10 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 9 + << 4 << 15 + << 4 << 9; + QTest::newRow("the quick{<(^ bro)wn>} fox|rtl") + << standard[0] + << 13 << 9 << 9 + << 9 << 15 + << 9 << 15; + QTest::newRow("the { fox|ltr") + << standard[0] + << 9 << 13 << 7 + << 4 << 15 + << 4 << 9; + QTest::newRow("the { fox|rtl") + << standard[0] + << 13 << 9 << 7 + << 9 << 15 + << 4 << 15; + QTest::newRow("the {<^quick}( bro)wn> fox|ltr") + << standard[0] + << 9 << 13 << 4 + << 4 << 15 + << 4 << 9; + QTest::newRow("the {<^quick}( bro)wn> fox|rtl") + << standard[0] + << 13 << 9 << 4 + << 9 << 15 + << 4 << 15; + QTest::newRow("the{^ fox|ltr") + << standard[0] + << 9 << 13 << 3 + << 4 << 15 + << 3 << 9; + QTest::newRow("the{^ fox|rtl") + << standard[0] + << 13 << 9 << 3 + << 9 << 15 + << 3 << 15; + QTest::newRow("{t^he fox|ltr") + << standard[0] + << 9 << 13 << 1 + << 4 << 15 + << 0 << 9; + QTest::newRow("{t^he fox|rtl") + << standard[0] + << 13 << 9 << 1 + << 9 << 15 + << 0 << 15; + + QTest::newRow("{, w^orld}!|ltr") + << standard[2] + << 2 << 4 << 8 + << 0 << 5 + << 0 << 12; + QTest::newRow("{, w^orld}!|rtl") + << standard[2] + << 4 << 2 << 8 + << 0 << 5 + << 0 << 12; + + QTest::newRow("!{dlro^w ,}|ltr") + << standard[3] + << 9 << 11 << 5 + << 8 << 13 + << 1 << 13; + QTest::newRow("!{dlro^w ,}|rtl") + << standard[3] + << 11 << 9 << 5 + << 8 << 13 + << 1 << 13; + + QTest::newRow("{<(^} sp)acey> text |ltr") + << standard[4] + << 0 << 3 << 0 + << 0 << 7 + << 0 << 0; + QTest::newRow("{<( ^}sp)acey> text |ltr") + << standard[4] + << 0 << 3 << 1 + << 0 << 7 + << 0 << 1; + QTest::newRow("<( {s^p)acey>} text |rtl") + << standard[4] + << 3 << 0 << 2 + << 0 << 7 + << 1 << 7; + QTest::newRow("<( {^sp)acey>} text |rtl") + << standard[4] + << 3 << 0 << 1 + << 0 << 7 + << 1 << 7; + + QTest::newRow(" spacey }|rtl") + << standard[4] + << 15 << 12 << 15 + << 10 << 15 + << 15 << 15; +// QTBUG-11365 +// QTest::newRow(" spacey }|rtl") +// << standard[4] +// << 15 << 12 << 14 +// << 10 << 15 +// << 14 << 15; + QTest::newRow(" spacey {|ltr") + << standard[4] + << 12 << 15 << 13 + << 10 << 15 + << 10 << 14; +// QTBUG-11365 +// QTest::newRow(" spacey {|ltr") +// << standard[4] +// << 12 << 15 << 14 +// << 10 << 15 +// << 10 << 14; +} + +void tst_qquicktextinput::moveCursorSelectionSequence() +{ + QFETCH(QString, testStr); + QFETCH(int, cursorPosition); + QFETCH(int, movePosition1); + QFETCH(int, movePosition2); + QFETCH(int, selection1Start); + QFETCH(int, selection1End); + QFETCH(int, selection2Start); + QFETCH(int, selection2End); + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \""+ testStr +"\"; }"; + QDeclarativeComponent textinputComponent(&engine); + textinputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textinputObject = qobject_cast(textinputComponent.create()); + QVERIFY(textinputObject != 0); + + textinputObject->setCursorPosition(cursorPosition); + + textinputObject->moveCursorSelection(movePosition1, QQuickTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection1Start, selection1End - selection1Start)); + QCOMPARE(textinputObject->selectionStart(), selection1Start); + QCOMPARE(textinputObject->selectionEnd(), selection1End); + + textinputObject->moveCursorSelection(movePosition2, QQuickTextInput::SelectWords); + QCOMPARE(textinputObject->selectedText(), testStr.mid(selection2Start, selection2End - selection2Start)); + QCOMPARE(textinputObject->selectionStart(), selection2Start); + QCOMPARE(textinputObject->selectionEnd(), selection2End); + + delete textinputObject; +} + +void tst_qquicktextinput::dragMouseSelection() +{ + QString qmlfile = TESTDATA("mouseselection_true.qml"); + + QQuickView canvas(QUrl::fromLocalFile(qmlfile)); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *textInputObject = qobject_cast(canvas.rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2, y)); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QTest::qWait(100); + QString str1; + QVERIFY((str1 = textInputObject->selectedText()).length() > 3); + QVERIFY(str1.length() > 3); + + // press and drag the current selection. + x1 = 40; + x2 = 100; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2, y)); + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QTest::qWait(300); + QString str2 = textInputObject->selectedText(); + QVERIFY(str2.length() > 3); + + QVERIFY(str1 != str2); +} + +void tst_qquicktextinput::mouseSelectionMode_data() +{ + QTest::addColumn("qmlfile"); + QTest::addColumn("selectWords"); + + // import installed + QTest::newRow("SelectWords") << TESTDATA("mouseselectionmode_words.qml") << true; + QTest::newRow("SelectCharacters") << TESTDATA("mouseselectionmode_characters.qml") << false; + QTest::newRow("default") << TESTDATA("mouseselectionmode_default.qml") << false; +} + +void tst_qquicktextinput::mouseSelectionMode() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, selectWords); + + QString text = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + QQuickView canvas(QUrl::fromLocalFile(qmlfile)); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *textInputObject = qobject_cast(canvas.rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(&canvas, Qt::LeftButton, 0, QPoint(x1,y)); + QTest::mouseMove(&canvas, QPoint(x2,y)); // doesn't work + QTest::mouseRelease(&canvas, Qt::LeftButton, 0, QPoint(x2,y)); + QTest::qWait(300); + if (selectWords) { + QTRY_COMPARE(textInputObject->selectedText(), text); + } else { + QTRY_VERIFY(textInputObject->selectedText().length() > 3); + QVERIFY(textInputObject->selectedText() != text); + } +} + +void tst_qquicktextinput::horizontalAlignment_data() +{ + QTest::addColumn("hAlign"); + QTest::addColumn("expectfile"); + + QTest::newRow("L") << int(Qt::AlignLeft) << "halign_left"; + QTest::newRow("R") << int(Qt::AlignRight) << "halign_right"; + QTest::newRow("C") << int(Qt::AlignHCenter) << "halign_center"; +} + +void tst_qquicktextinput::horizontalAlignment() +{ + QSKIP("Image comparison of text is almost guaranteed to fail during development"); + + QFETCH(int, hAlign); + QFETCH(QString, expectfile); + + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment.qml"))); + + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + QObject *ob = canvas.rootObject(); + QVERIFY(ob != 0); + ob->setProperty("horizontalAlignment",hAlign); + QImage actual = canvas.grabFrameBuffer(); + + expectfile = createExpectedFileIfNotFound(expectfile, actual); + + QImage expect(expectfile); + + QCOMPARE(actual,expect); +} + +void tst_qquicktextinput::horizontalAlignment_RightToLeft() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("horizontalAlignment_RightToLeft.qml"))); + QQuickTextInput *textInput = canvas.rootObject()->findChild("text"); + QVERIFY(textInput != 0); + canvas.show(); + + const QString rtlText = textInput->text(); + + QQuickTextInputPrivate *textInputPrivate = QQuickTextInputPrivate::get(textInput); + QVERIFY(textInputPrivate != 0); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // implicit alignment should follow the reading direction of RTL text + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // explicitly left aligned + textInput->setHAlign(QQuickTextInput::AlignLeft); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); + + // explicitly right aligned + textInput->setHAlign(QQuickTextInput::AlignRight); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // explicitly center aligned + textInput->setHAlign(QQuickTextInput::AlignHCenter); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignHCenter); + QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); + QVERIFY(-textInputPrivate->hscroll + textInputPrivate->width > canvas.width()/2); + + // reseted alignment should go back to following the text reading direction + textInput->resetHAlign(); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // mirror the text item + QQuickItemPrivate::get(textInput)->setLayoutMirror(true); + + // mirrored implicit alignment should continue to follow the reading direction of the text + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // explicitly right aligned behaves as left aligned + textInput->setHAlign(QQuickTextInput::AlignRight); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignLeft); + QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); + + // mirrored explicitly left aligned behaves as right aligned + textInput->setHAlign(QQuickTextInput::AlignLeft); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); + QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignRight); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + // disable mirroring + QQuickItemPrivate::get(textInput)->setLayoutMirror(false); + QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign()); + textInput->resetHAlign(); + + // English text should be implicitly left aligned + textInput->setText("Hello world!"); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); + QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); + + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + // If there is no commited text, the preedit text should determine the alignment. + textInput->setText(QString()); + { QInputMethodEvent ev(rtlText, QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + { QInputMethodEvent ev("Hello world!", QList()); QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft); + + // Clear pre-edit text. TextInput should maybe do this itself on setText, but that may be + // redundant as an actual input method may take care of it. + { QInputMethodEvent ev; QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &ev); } + +#ifdef Q_OS_MAC + // empty text with implicit alignment follows the system locale-based + // keyboard input direction from QGuiApplication::keyboardInputDirection + QEXPECT_FAIL("", "QTBUG-18040", Abort); +#endif + textInput->setText(""); + QCOMPARE(textInput->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight); + if (QGuiApplication::keyboardInputDirection() == Qt::LeftToRight) + QVERIFY(-textInputPrivate->hscroll < canvas.width()/2); + else + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + textInput->setHAlign(QQuickTextInput::AlignRight); + QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight); + QVERIFY(-textInputPrivate->hscroll > canvas.width()/2); + + +#ifdef Q_OS_MAC + QEXPECT_FAIL("", "QTBUG-18040", Abort); // alignment of TextInput with no text set to it +#endif + QString componentStr = "import QtQuick 2.0\nTextInput {}"; + QDeclarativeComponent textComponent(&engine); + textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile("")); + QQuickTextInput *textObject = qobject_cast(textComponent.create()); + QCOMPARE(textObject->hAlign(), QGuiApplication::keyboardInputDirection() == Qt::LeftToRight ? + QQuickTextInput::AlignLeft : QQuickTextInput::AlignRight); + delete textObject; +} + +void tst_qquicktextinput::positionAt() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); + QVERIFY(canvas.rootObject() != 0); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); + QVERIFY(textinputObject != 0); + + // Check autoscrolled... + QFontMetrics fm(textinputObject->font()); + + int pos = textinputObject->positionAt(textinputObject->width()/2); + int textWidth = 0; + int textLeftWidthBegin = 0; + int textLeftWidthEnd = 0; + if (!qmlDisableDistanceField()) { + QTextLayout layout(textinputObject->text()); + + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + textLeftWidthBegin = floor(line.cursorToX(pos - 1)); + textLeftWidthEnd = ceil(line.cursorToX(pos + 1)); + textWidth = floor(line.horizontalAdvance()); + } else { + textWidth = fm.width(textinputObject->text()); + textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1)); + textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1)); + } + + QVERIFY(textLeftWidthBegin <= textWidth - textinputObject->width() / 2); + QVERIFY(textLeftWidthEnd >= textWidth - textinputObject->width() / 2); + + int x = textinputObject->positionToRectangle(pos + 1).x() - 1; + QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1); + QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos); + + // Check without autoscroll... + textinputObject->setAutoScroll(false); + pos = textinputObject->positionAt(textinputObject->width()/2); + + if (!qmlDisableDistanceField()) { + QTextLayout layout(textinputObject->text()); + + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + textLeftWidthBegin = floor(line.cursorToX(pos - 1)); + textLeftWidthEnd = ceil(line.cursorToX(pos + 1)); + } else { + textLeftWidthBegin = fm.width(textinputObject->text().left(pos - 1)); + textLeftWidthEnd = fm.width(textinputObject->text().left(pos + 1)); + } + + QVERIFY(textLeftWidthBegin <= textinputObject->width() / 2); + QVERIFY(textLeftWidthEnd >= textinputObject->width() / 2); + + x = textinputObject->positionToRectangle(pos + 1).x() - 1; + QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorBetweenCharacters), pos + 1); + QCOMPARE(textinputObject->positionAt(x, QQuickTextInput::CursorOnCharacter), pos); + + const qreal x0 = textinputObject->positionToRectangle(pos).x(); + const qreal x1 = textinputObject->positionToRectangle(pos + 1).x(); + + QString preeditText = textinputObject->text().mid(0, pos); + textinputObject->setText(textinputObject->text().mid(pos)); + textinputObject->setCursorPosition(0); + + QInputMethodEvent inputEvent(preeditText, QList()); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &inputEvent); + + // Check all points within the preedit text return the same position. + QCOMPARE(textinputObject->positionAt(0), 0); + QCOMPARE(textinputObject->positionAt(x0 / 2), 0); + QCOMPARE(textinputObject->positionAt(x0), 0); + + // Verify positioning returns to normal after the preedit text. + QCOMPARE(textinputObject->positionAt(x1), 1); + QCOMPARE(textinputObject->positionToRectangle(1).x(), x1); +} + +void tst_qquicktextinput::maxLength() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("maxLength.qml"))); + QVERIFY(canvas.rootObject() != 0); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); + QVERIFY(textinputObject != 0); + QVERIFY(textinputObject->text().isEmpty()); + QVERIFY(textinputObject->maxLength() == 10); + foreach (const QString &str, standard) { + QVERIFY(textinputObject->text().length() <= 10); + textinputObject->setText(str); + QVERIFY(textinputObject->text().length() <= 10); + } + + textinputObject->setText(""); + QTRY_VERIFY(textinputObject->hasActiveFocus() == true); + for (int i=0; i<20; i++) { + QTRY_COMPARE(textinputObject->text().length(), qMin(i,10)); + //simulateKey(&canvas, Qt::Key_A); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + } +} + +void tst_qquicktextinput::masks() +{ + //Not a comprehensive test of the possible masks, that's done elsewhere (QLineEdit) + //QString componentStr = "import QtQuick 2.0\nTextInput { inputMask: 'HHHHhhhh'; }"; + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("masks.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *textinputObject = qobject_cast(canvas.rootObject()); + QVERIFY(textinputObject != 0); + QTRY_VERIFY(textinputObject->hasActiveFocus() == true); + QVERIFY(textinputObject->text().length() == 0); + QCOMPARE(textinputObject->inputMask(), QString("HHHHhhhh; ")); + for (int i=0; i<10; i++) { + QTRY_COMPARE(qMin(i,8), textinputObject->text().length()); + QCOMPARE(i>=4, textinputObject->hasAcceptableInput()); + //simulateKey(&canvas, Qt::Key_A); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + } +} + +void tst_qquicktextinput::validators() +{ + // Note that this test assumes that the validators are working properly + // so you may need to run their tests first. All validators are checked + // here to ensure that their exposure to QML is working. + + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("validators.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *intInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("intInput"))); + QVERIFY(intInput); + intInput->setFocus(true); + QTRY_VERIFY(intInput->hasActiveFocus()); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(intInput->text(), QLatin1String("1")); + QCOMPARE(intInput->hasAcceptableInput(), false); + QTest::keyPress(&canvas, Qt::Key_2); + QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(intInput->text(), QLatin1String("1")); + QCOMPARE(intInput->hasAcceptableInput(), false); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QCOMPARE(intInput->text(), QLatin1String("11")); + QCOMPARE(intInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_0); + QTest::keyRelease(&canvas, Qt::Key_0, Qt::NoModifier ,10); + QTest::qWait(50); + QCOMPARE(intInput->text(), QLatin1String("11")); + QCOMPARE(intInput->hasAcceptableInput(), true); + + QQuickTextInput *dblInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("dblInput"))); + QTRY_VERIFY(dblInput); + dblInput->setFocus(true); + QVERIFY(dblInput->hasActiveFocus() == true); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("1")); + QCOMPARE(dblInput->hasAcceptableInput(), false); + QTest::keyPress(&canvas, Qt::Key_2); + QTest::keyRelease(&canvas, Qt::Key_2, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("12")); + QCOMPARE(dblInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_Period); + QTest::keyRelease(&canvas, Qt::Key_Period, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("12.")); + QCOMPARE(dblInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("12.1")); + QCOMPARE(dblInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("12.11")); + QCOMPARE(dblInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(dblInput->text(), QLatin1String("12.11")); + QCOMPARE(dblInput->hasAcceptableInput(), true); + + QQuickTextInput *strInput = qobject_cast(qvariant_cast(canvas.rootObject()->property("strInput"))); + QTRY_VERIFY(strInput); + strInput->setFocus(true); + QVERIFY(strInput->hasActiveFocus() == true); + QTest::keyPress(&canvas, Qt::Key_1); + QTest::keyRelease(&canvas, Qt::Key_1, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("")); + QCOMPARE(strInput->hasAcceptableInput(), false); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("a")); + QCOMPARE(strInput->hasAcceptableInput(), false); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("aa")); + QCOMPARE(strInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("aaa")); + QCOMPARE(strInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("aaaa")); + QCOMPARE(strInput->hasAcceptableInput(), true); + QTest::keyPress(&canvas, Qt::Key_A); + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QTest::qWait(50); + QTRY_COMPARE(strInput->text(), QLatin1String("aaaa")); + QCOMPARE(strInput->hasAcceptableInput(), true); +} + +void tst_qquicktextinput::inputMethods() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("inputmethods.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + + // test input method hints + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *input = qobject_cast(canvas.rootObject()); + QVERIFY(input != 0); + QVERIFY(input->inputMethodHints() & Qt::ImhNoPredictiveText); + input->setInputMethodHints(Qt::ImhUppercaseOnly); + QVERIFY(input->inputMethodHints() & Qt::ImhUppercaseOnly); + + input->setFocus(true); + QVERIFY(input->hasActiveFocus() == true); + // test that input method event is committed + QInputMethodEvent event; + event.setCommitString( "My ", -12, 0); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); + QCOMPARE(input->text(), QString("My Hello world!")); + + input->setCursorPosition(2); + event.setCommitString("Your", -2, 2); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); + QCOMPARE(input->text(), QString("Your Hello world!")); + QCOMPARE(input->cursorPosition(), 4); + + input->setCursorPosition(7); + event.setCommitString("Goodbye", -2, 5); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); + QCOMPARE(input->text(), QString("Your Goodbye world!")); + QCOMPARE(input->cursorPosition(), 12); + + input->setCursorPosition(8); + event.setCommitString("Our", -8, 4); + QGuiApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); + QCOMPARE(input->text(), QString("Our Goodbye world!")); + QCOMPARE(input->cursorPosition(), 7); + + // test that basic tentative commit gets to text property on preedit state + input->setText(""); + QList attributes; + QInputMethodEvent preeditEvent("test", attributes); + preeditEvent.setTentativeCommitString("test"); + QApplication::sendEvent(input, &preeditEvent); + QCOMPARE(input->text(), QString("test")); + + // tentative commit not allowed present in surrounding text + QInputMethodQueryEvent queryEvent(Qt::ImSurroundingText); + QApplication::sendEvent(input, &queryEvent); + QCOMPARE(queryEvent.value(Qt::ImSurroundingText).toString(), QString("")); + + // if text with tentative commit does not validate, not allowed to be part of text property + input->setText(""); // ensure input state is reset + QValidator *validator = new QIntValidator(0, 100); + input->setValidator(validator); + QApplication::sendEvent(input, &preeditEvent); + QCOMPARE(input->text(), QString("")); + input->setValidator(0); + delete validator; +} + +/* +TextInput element should only handle left/right keys until the cursor reaches +the extent of the text, then they should ignore the keys. + +*/ +void tst_qquicktextinput::navigation() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + input->setCursorPosition(0); + QTRY_VERIFY(input->hasActiveFocus() == true); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == false); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == true); + //QT-2944: If text is selected, ensure we deselect upon cursor motion + input->setCursorPosition(input->text().length()); + input->select(0,input->text().length()); + QVERIFY(input->selectionStart() != input->selectionEnd()); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->selectionStart() == input->selectionEnd()); + QVERIFY(input->selectionStart() == input->text().length()); + QVERIFY(input->hasActiveFocus() == true); + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == false); + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == true); + + // Up and Down should NOT do Home/End, even on Mac OS X (QTBUG-10438). + input->setCursorPosition(2); + QCOMPARE(input->cursorPosition(),2); + simulateKey(&canvas, Qt::Key_Up); + QCOMPARE(input->cursorPosition(),2); + simulateKey(&canvas, Qt::Key_Down); + QCOMPARE(input->cursorPosition(),2); +} + +void tst_qquicktextinput::navigation_RTL() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("navigation.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + const quint16 arabic_str[] = { 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0638, 0x0643, 0x00646, 0x0647, 0x0633, 0x0647}; + input->setText(QString::fromUtf16(arabic_str, 11)); + + input->setCursorPosition(0); + QTRY_VERIFY(input->hasActiveFocus() == true); + + // move off + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == false); + + // move back + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == true); + + input->setCursorPosition(input->text().length()); + QVERIFY(input->hasActiveFocus() == true); + + // move off + simulateKey(&canvas, Qt::Key_Left); + QVERIFY(input->hasActiveFocus() == false); + + // move back + simulateKey(&canvas, Qt::Key_Right); + QVERIFY(input->hasActiveFocus() == true); +} + +void tst_qquicktextinput::copyAndPaste() { +#ifndef QT_NO_CLIPBOARD + +#ifdef Q_OS_MAC + { + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate(0, &pasteboard); + if (status == noErr) + CFRelease(pasteboard); + else + QSKIP("This machine doesn't support the clipboard"); + } +#endif + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + // copy and paste + QCOMPARE(textInput->text().length(), 12); + textInput->select(0, textInput->text().length());; + textInput->copy(); + QCOMPARE(textInput->selectedText(), QString("Hello world!")); + QCOMPARE(textInput->selectedText().length(), 12); + textInput->setCursorPosition(0); + QVERIFY(textInput->canPaste()); + textInput->paste(); + QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); + QCOMPARE(textInput->text().length(), 24); + + // can paste + QVERIFY(textInput->canPaste()); + textInput->setReadOnly(true); + QVERIFY(!textInput->canPaste()); + textInput->setReadOnly(false); + QVERIFY(textInput->canPaste()); + + // select word + textInput->setCursorPosition(0); + textInput->selectWord(); + QCOMPARE(textInput->selectedText(), QString("Hello")); + + // select all and cut + textInput->selectAll(); + textInput->cut(); + QCOMPARE(textInput->text().length(), 0); + textInput->paste(); + QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); + QCOMPARE(textInput->text().length(), 24); + + // clear copy buffer + QClipboard *clipboard = QGuiApplication::clipboard(); + QVERIFY(clipboard); + clipboard->clear(); + QVERIFY(!textInput->canPaste()); + + // test that copy functionality is disabled + // when echo mode is set to hide text/password mode + int index = 0; + while (index < 4) { + QQuickTextInput::EchoMode echoMode = QQuickTextInput::EchoMode(index); + textInput->setEchoMode(echoMode); + textInput->setText("My password"); + textInput->select(0, textInput->text().length());; + textInput->copy(); + if (echoMode == QQuickTextInput::Normal) { + QVERIFY(!clipboard->text().isEmpty()); + QCOMPARE(clipboard->text(), QString("My password")); + clipboard->clear(); + } else { + QVERIFY(clipboard->text().isEmpty()); + } + index++; + } + + delete textInput; +#endif +} + +void tst_qquicktextinput::copyAndPasteKeySequence() { +#ifndef QT_NO_CLIPBOARD + +#ifdef Q_OS_MAC + { + PasteboardRef pasteboard; + OSStatus status = PasteboardCreate(0, &pasteboard); + if (status == noErr) + CFRelease(pasteboard); + else + QSKIP("This machine doesn't support the clipboard"); + } +#endif + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + // copy and paste + QVERIFY(textInput->hasActiveFocus()); + QCOMPARE(textInput->text().length(), 12); + textInput->select(0, textInput->text().length()); + simulateKeys(&canvas, QKeySequence::Copy); + QCOMPARE(textInput->selectedText(), QString("Hello world!")); + QCOMPARE(textInput->selectedText().length(), 12); + textInput->setCursorPosition(0); + QVERIFY(textInput->canPaste()); + simulateKeys(&canvas, QKeySequence::Paste); + QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); + QCOMPARE(textInput->text().length(), 24); + + // select all and cut + simulateKeys(&canvas, QKeySequence::SelectAll); + simulateKeys(&canvas, QKeySequence::Cut); + QCOMPARE(textInput->text().length(), 0); + simulateKeys(&canvas, QKeySequence::Paste); + QCOMPARE(textInput->text(), QString("Hello world!Hello world!")); + QCOMPARE(textInput->text().length(), 24); + + // clear copy buffer + QClipboard *clipboard = QGuiApplication::clipboard(); + QVERIFY(clipboard); + clipboard->clear(); + QVERIFY(!textInput->canPaste()); + + // test that copy functionality is disabled + // when echo mode is set to hide text/password mode + int index = 0; + while (index < 4) { + QQuickTextInput::EchoMode echoMode = QQuickTextInput::EchoMode(index); + textInput->setEchoMode(echoMode); + textInput->setText("My password"); + textInput->select(0, textInput->text().length());; + simulateKeys(&canvas, QKeySequence::Copy); + if (echoMode == QQuickTextInput::Normal) { + QVERIFY(!clipboard->text().isEmpty()); + QCOMPARE(clipboard->text(), QString("My password")); + clipboard->clear(); + } else { + QVERIFY(clipboard->text().isEmpty()); + } + index++; + } + + delete textInput; +#endif +} + +void tst_qquicktextinput::canPasteEmpty() { +#ifndef QT_NO_CLIPBOARD + + QGuiApplication::clipboard()->clear(); + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QLineControl lc; + bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0; + QCOMPARE(textInput->canPaste(), cp); + +#endif +} + +void tst_qquicktextinput::canPaste() { +#ifndef QT_NO_CLIPBOARD + + QGuiApplication::clipboard()->setText("Some text"); + + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\" }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QLineControl lc; + bool cp = !lc.isReadOnly() && QGuiApplication::clipboard()->text().length() != 0; + QCOMPARE(textInput->canPaste(), cp); + +#endif +} + +void tst_qquicktextinput::passwordCharacter() +{ + QString componentStr = "import QtQuick 2.0\nTextInput { text: \"Hello world!\"; font.family: \"Helvetica\"; echoMode: TextInput.Password }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + textInput->setPasswordCharacter("X"); + qreal implicitWidth = textInput->implicitWidth(); + textInput->setPasswordCharacter("."); + + // QTBUG-12383 content is updated and redrawn + QVERIFY(textInput->implicitWidth() < implicitWidth); + + delete textInput; +} + +void tst_qquicktextinput::cursorDelegate() +{ + QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorTest.qml"))); + view.show(); + view.requestActivateWindow(); + QQuickTextInput *textInputObject = view.rootObject()->findChild("textInputObject"); + QVERIFY(textInputObject != 0); + QVERIFY(textInputObject->findChild("cursorInstance")); + //Test Delegate gets created + textInputObject->setFocus(true); + QQuickItem* delegateObject = textInputObject->findChild("cursorInstance"); + QVERIFY(delegateObject); + QCOMPARE(delegateObject->property("localProperty").toString(), QString("Hello")); + //Test Delegate gets moved + for (int i=0; i<= textInputObject->text().length(); i++) { + textInputObject->setCursorPosition(i); + QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + } + textInputObject->setCursorPosition(0); + QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + //Test Delegate gets deleted + textInputObject->setCursorDelegate(0); + QVERIFY(!textInputObject->findChild("cursorInstance")); +} + +void tst_qquicktextinput::cursorVisible() +{ + QQuickView view(QUrl::fromLocalFile(TESTDATA("cursorVisible.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QQuickTextInput input; + QSignalSpy spy(&input, SIGNAL(cursorVisibleChanged(bool))); + + QCOMPARE(input.isCursorVisible(), false); + + input.setCursorVisible(true); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 1); + + input.setCursorVisible(false); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + input.setFocus(true); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 2); + + input.setParentItem(view.rootObject()); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 3); + + input.setFocus(false); + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 4); + + input.setFocus(true); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 5); + + QQuickView alternateView; + alternateView.show(); + alternateView.requestActivateWindow(); + QTest::qWaitForWindowShown(&alternateView); + + QCOMPARE(input.isCursorVisible(), false); + QCOMPARE(spy.count(), 6); + + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QCOMPARE(input.isCursorVisible(), true); + QCOMPARE(spy.count(), 7); +} + +void tst_qquicktextinput::cursorRectangle() +{ + QSKIP("QTBUG-21689"); + + QString text = "Hello World!"; + + QQuickTextInput input; + input.setText(text); + QFontMetricsF fm(input.font()); + input.setWidth(fm.width(text.mid(0, 5))); + + QRect r; + + // some tolerance for different fonts. +#ifdef Q_OS_LINUX + const int error = 2; +#else + const int error = 5; +#endif + + + for (int i = 0; i <= 5; ++i) { + input.setCursorPosition(i); + r = input.cursorRectangle(); + int textWidth = fm.width(text.mid(0, i)); + + QVERIFY(r.left() < textWidth + error); + QVERIFY(r.right() > textWidth - error); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + } + + // Check the cursor rectangle remains within the input bounding rect when auto scrolling. + QVERIFY(r.left() < input.boundingRect().width()); + QVERIFY(r.right() >= input.width() - error); + + for (int i = 6; i < text.length(); ++i) { + input.setCursorPosition(i); + QCOMPARE(r, input.cursorRectangle()); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + } + + for (int i = text.length() - 2; i >= 0; --i) { + input.setCursorPosition(i); + r = input.cursorRectangle(); + QVERIFY(r.right() >= 0); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); + } + + input.setText("Hi!"); + input.setHAlign(QQuickTextInput::AlignRight); + r = input.cursorRectangle(); + QVERIFY(r.left() < input.boundingRect().width()); + QVERIFY(r.right() >= input.width() - error); +} + +void tst_qquicktextinput::readOnly() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("readOnly.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + QTRY_VERIFY(input->hasActiveFocus() == true); + QVERIFY(input->isReadOnly() == true); + QString initial = input->text(); + for (int k=Qt::Key_0; k<=Qt::Key_Z; k++) + simulateKey(&canvas, k); + simulateKey(&canvas, Qt::Key_Return); + simulateKey(&canvas, Qt::Key_Space); + simulateKey(&canvas, Qt::Key_Escape); + QCOMPARE(input->text(), initial); + + input->setCursorPosition(3); + input->setReadOnly(false); + QCOMPARE(input->isReadOnly(), false); + QCOMPARE(input->cursorPosition(), input->text().length()); +} + +void tst_qquicktextinput::echoMode() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml"))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QVERIFY(input != 0); + QTRY_VERIFY(input->hasActiveFocus() == true); + QString initial = input->text(); + Qt::InputMethodHints ref; + QCOMPARE(initial, QLatin1String("ABCDefgh")); + QCOMPARE(input->echoMode(), QQuickTextInput::Normal); + QCOMPARE(input->displayText(), input->text()); + //Normal + ref &= ~Qt::ImhHiddenText; + ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + QCOMPARE(input->inputMethodHints(), ref); + input->setEchoMode(QQuickTextInput::NoEcho); + QCOMPARE(input->text(), initial); + QCOMPARE(input->displayText(), QLatin1String("")); + QCOMPARE(input->passwordCharacter(), QLatin1String("*")); + //NoEcho + ref |= Qt::ImhHiddenText; + ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + QCOMPARE(input->inputMethodHints(), ref); + input->setEchoMode(QQuickTextInput::Password); + //Password + ref |= Qt::ImhHiddenText; + ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + QCOMPARE(input->text(), initial); + QCOMPARE(input->displayText(), QLatin1String("********")); + QCOMPARE(input->inputMethodHints(), ref); + input->setPasswordCharacter(QChar('Q')); + QCOMPARE(input->passwordCharacter(), QLatin1String("Q")); + QCOMPARE(input->text(), initial); + QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); + input->setEchoMode(QQuickTextInput::PasswordEchoOnEdit); + //PasswordEchoOnEdit + ref &= ~Qt::ImhHiddenText; + ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText); + QCOMPARE(input->inputMethodHints(), ref); + QCOMPARE(input->text(), initial); + QCOMPARE(input->displayText(), QLatin1String("QQQQQQQQ")); + QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("QQQQQQQQ")); + QTest::keyPress(&canvas, Qt::Key_A);//Clearing previous entry is part of PasswordEchoOnEdit + QTest::keyRelease(&canvas, Qt::Key_A, Qt::NoModifier ,10); + QCOMPARE(input->text(), QLatin1String("a")); + QCOMPARE(input->displayText(), QLatin1String("a")); + QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("a")); + input->setFocus(false); + QVERIFY(input->hasActiveFocus() == false); + QCOMPARE(input->displayText(), QLatin1String("Q")); + QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QLatin1String("Q")); + input->setFocus(true); + QVERIFY(input->hasActiveFocus()); + QInputMethodEvent inputEvent; + inputEvent.setCommitString(initial); + QGuiApplication::sendEvent(input, &inputEvent); + QCOMPARE(input->text(), initial); + QCOMPARE(input->displayText(), initial); + QCOMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), initial); +} + +#ifdef QT_GUI_PASSWORD_ECHO_DELAY +void tst_qdeclarativetextinput::passwordEchoDelay() +{ + QQuickView canvas(QUrl::fromLocalFile(TESTDATA("echoMode.qml"))); + canvas.show(); + canvas.setFocus(); + QGuiApplication::setActiveWindow(&canvas); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(&canvas, qGuiApp->focusWindow()); + + QVERIFY(canvas.rootObject() != 0); + + QQuickTextInput *input = qobject_cast(qvariant_cast(canvas.rootObject()->property("myInput"))); + + QChar fillChar = QLatin1Char('*'); + + input->setEchoMode(QDeclarativeTextInput::Password); + QCOMPARE(input->displayText(), QString(8, fillChar)); + input->setText(QString()); + QCOMPARE(input->displayText(), QString()); + + QTest::keyPress(&canvas, '0'); + QTest::keyPress(&canvas, '1'); + QTest::keyPress(&canvas, '2'); + QCOMPARE(input->displayText(), QString(2, fillChar) + QLatin1Char('2')); + QTest::keyPress(&canvas, '3'); + QTest::keyPress(&canvas, '4'); + QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4')); + QTest::keyPress(&canvas, Qt::Key_Backspace); + QCOMPARE(input->displayText(), QString(4, fillChar)); + QTest::keyPress(&canvas, '4'); + QCOMPARE(input->displayText(), QString(4, fillChar) + QLatin1Char('4')); + QTest::qWait(QT_GUI_PASSWORD_ECHO_DELAY); + QTRY_COMPARE(input->displayText(), QString(5, fillChar)); + QTest::keyPress(&canvas, '5'); + QCOMPARE(input->displayText(), QString(5, fillChar) + QLatin1Char('5')); + input->setFocus(false); + QVERIFY(!input->hasFocus()); + QCOMPARE(input->displayText(), QString(6, fillChar)); + input->setFocus(true); + QTRY_VERIFY(input->hasFocus()); + QCOMPARE(input->displayText(), QString(6, fillChar)); + QTest::keyPress(&canvas, '6'); + QCOMPARE(input->displayText(), QString(6, fillChar) + QLatin1Char('6')); + + QInputMethodEvent ev; + ev.setCommitString(QLatin1String("7")); + QGuiApplication::sendEvent(&canvas, &ev); + QCOMPARE(input->displayText(), QString(7, fillChar) + QLatin1Char('7')); +} +#endif + + +void tst_qquicktextinput::simulateKey(QQuickView *view, int key) +{ + QKeyEvent press(QKeyEvent::KeyPress, key, 0); + QKeyEvent release(QKeyEvent::KeyRelease, key, 0); + + QGuiApplication::sendEvent(view, &press); + QGuiApplication::sendEvent(view, &release); +} + +class PlatformInputContext : public QPlatformInputContext +{ +public: + PlatformInputContext() + : m_visible(false), m_action(QInputPanel::Click), m_cursorPosition(0), + m_invokeActionCallCount(0) + { + } + + virtual void showInputPanel() + { + m_visible = true; + } + virtual void hideInputPanel() + { + m_visible = false; + } + virtual bool isInputPanelVisible() const + { + return m_visible; + } + virtual void invokeAction(QInputPanel::Action action, int cursorPosition) + { + m_invokeActionCallCount++; + m_action = action; + m_cursorPosition = cursorPosition; + } + + bool m_visible; + QInputPanel::Action m_action; + int m_cursorPosition; + int m_invokeActionCallCount; +}; + +void tst_qquicktextinput::openInputPanel() +{ + PlatformInputContext platformInputContext; + QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); + inputPanelPrivate->testContext = &platformInputContext; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("openInputPanel.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QQuickTextInput *input = qobject_cast(view.rootObject()); + QVERIFY(input); + + // check default values + QVERIFY(input->focusOnPress()); + QVERIFY(!input->hasActiveFocus()); + qDebug() << &input << qApp->inputPanel()->inputItem(); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open on focus + QPoint centerPoint(view.width()/2, view.height()/2); + Qt::KeyboardModifiers noModifiers = 0; + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QVERIFY(input->hasActiveFocus()); + QCOMPARE(qApp->inputPanel()->inputItem(), input); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + + // input panel should be re-opened when pressing already focused TextInput + qApp->inputPanel()->hide(); + QCOMPARE(qApp->inputPanel()->visible(), false); + QVERIFY(input->hasActiveFocus()); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QCOMPARE(qApp->inputPanel()->visible(), true); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + + // input panel should stay visible if focus is lost to another text inputor + QSignalSpy inputPanelVisibilitySpy(qApp->inputPanel(), SIGNAL(visibleChanged())); + QQuickTextInput anotherInput; + anotherInput.setParentItem(view.rootObject()); + anotherInput.setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), true); + QCOMPARE(qApp->inputPanel()->inputItem(), qobject_cast(&anotherInput)); + QCOMPARE(inputPanelVisibilitySpy.count(), 0); + + anotherInput.setFocus(false); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), view.rootItem()); + anotherInput.setFocus(true); + + // input item should be null if focus is lost to an item that doesn't accept inputs + QQuickItem item; + item.setParentItem(view.rootObject()); + item.setFocus(true); + QCOMPARE(qApp->inputPanel()->inputItem(), static_cast(0)); + QCOMPARE(view.activeFocusItem(), &item); + + qApp->inputPanel()->hide(); + + // input panel should not be opened if TextInput is read only + input->setReadOnly(true); + input->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QGuiApplication::processEvents(); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should not be opened if focusOnPress is set to false + input->setFocusOnPress(false); + input->setFocus(false); + input->setFocus(true); + QCOMPARE(qApp->inputPanel()->visible(), false); + QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QCOMPARE(qApp->inputPanel()->visible(), false); + + // input panel should open when openSoftwareInputPanel is called + input->openSoftwareInputPanel(); + QCOMPARE(qApp->inputPanel()->visible(), true); + + // input panel should close when closeSoftwareInputPanel is called + input->closeSoftwareInputPanel(); + QCOMPARE(qApp->inputPanel()->visible(), false); +} + +class MyTextInput : public QQuickTextInput +{ +public: + MyTextInput(QQuickItem *parent = 0) : QQuickTextInput(parent) + { + nbPaint = 0; + } + virtual QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) + { + nbPaint++; + return QQuickTextInput::updatePaintNode(node, data); + } + int nbPaint; +}; + +void tst_qquicktextinput::setHAlignClearCache() +{ + QQuickView view; + MyTextInput input; + input.setText("Hello world"); + input.setParentItem(view.rootItem()); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(input.nbPaint, 1); + input.setHAlign(QQuickTextInput::AlignRight); + //Changing the alignment should trigger a repaint + QTRY_COMPARE(input.nbPaint, 2); +} + +void tst_qquicktextinput::focusOutClearSelection() +{ + QQuickView view; + QQuickTextInput input; + QQuickTextInput input2; + input.setText(QLatin1String("Hello world")); + input.setFocus(true); + input2.setParentItem(view.rootItem()); + input.setParentItem(view.rootItem()); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + input.select(2,5); + //The selection should work + QTRY_COMPARE(input.selectedText(), QLatin1String("llo")); + input2.setFocus(true); + QGuiApplication::processEvents(); + //The input lost the focus selection should be cleared + QTRY_COMPARE(input.selectedText(), QLatin1String("")); +} + +void tst_qquicktextinput::geometrySignals() +{ + QDeclarativeComponent component(&engine, TESTDATA("geometrySignals.qml")); + QObject *o = component.create(); + QVERIFY(o); + QCOMPARE(o->property("bindingWidth").toInt(), 400); + QCOMPARE(o->property("bindingHeight").toInt(), 500); + delete o; +} + +void tst_qquicktextinput::testQtQuick11Attributes() +{ + QFETCH(QString, code); + QFETCH(QString, warning); + QFETCH(QString, error); + + QDeclarativeEngine engine; + QObject *obj; + + QDeclarativeComponent valid(&engine); + valid.setData("import QtQuick 2.0; TextInput { " + code.toUtf8() + " }", QUrl("")); + obj = valid.create(); + QVERIFY(obj); + QVERIFY(valid.errorString().isEmpty()); + delete obj; + + QDeclarativeComponent invalid(&engine); + invalid.setData("import QtQuick 1.0; TextInput { " + code.toUtf8() + " }", QUrl("")); + QTest::ignoreMessage(QtWarningMsg, warning.toUtf8()); + obj = invalid.create(); + QCOMPARE(invalid.errorString(), error); + delete obj; +} + +void tst_qquicktextinput::testQtQuick11Attributes_data() +{ + QTest::addColumn("code"); + QTest::addColumn("warning"); + QTest::addColumn("error"); + + QTest::newRow("canPaste") << "property bool foo: canPaste" + << ":1: ReferenceError: Can't find variable: canPaste" + << ""; + + QTest::newRow("moveCursorSelection") << "Component.onCompleted: moveCursorSelection(0, TextEdit.SelectCharacters)" + << ":1: ReferenceError: Can't find variable: moveCursorSelection" + << ""; + + QTest::newRow("deselect") << "Component.onCompleted: deselect()" + << ":1: ReferenceError: Can't find variable: deselect" + << ""; +} + +static void sendPreeditText(const QString &text, int cursor) +{ + QInputMethodEvent event(text, QList() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, cursor, text.length(), QVariant())); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &event); +} + +void tst_qquicktextinput::preeditAutoScroll() +{ + QString preeditText = "califragisiticexpialidocious!"; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("preeditAutoScroll.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextInput *input = qobject_cast(view.rootObject()); + QVERIFY(input); + QVERIFY(input->hasActiveFocus()); + + input->setWidth(input->implicitWidth()); + + QSignalSpy cursorRectangleSpy(input, SIGNAL(cursorRectangleChanged())); + int cursorRectangleChanges = 0; + + // test the text is scrolled so the preedit is visible. + sendPreeditText(preeditText.mid(0, 3), 1); + QVERIFY(input->positionAt(0) != 0); + QVERIFY(input->cursorRectangle().left() < input->boundingRect().width()); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + + // test the text is scrolled back when the preedit is removed. + QInputMethodEvent imEvent; + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + QCOMPARE(input->positionAt(0), 0); + QCOMPARE(input->positionAt(input->width()), 5); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + + QTextLayout layout(preeditText); + if (!qmlDisableDistanceField()) { + QTextOption option; + option.setUseDesignMetrics(true); + layout.setTextOption(option); + } + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + // test if the preedit is larger than the text input that the + // character preceding the cursor is still visible. + qreal x = input->positionToRectangle(0).x(); + for (int i = 0; i < 3; ++i) { + sendPreeditText(preeditText, i + 1); + int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i)); + QVERIFY(input->cursorRectangle().right() >= width - 3); + QVERIFY(input->positionToRectangle(0).x() < x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + x = input->positionToRectangle(0).x(); + } + for (int i = 1; i >= 0; --i) { + sendPreeditText(preeditText, i + 1); + int width = ceil(line.cursorToX(i, QTextLine::Trailing)) - floor(line.cursorToX(i)); + QVERIFY(input->cursorRectangle().right() >= width - 3); + QVERIFY(input->positionToRectangle(0).x() > x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + x = input->positionToRectangle(0).x(); + } + + // Test incrementing the preedit cursor doesn't cause further + // scrolling when right most text is visible. + sendPreeditText(preeditText, preeditText.length() - 3); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + x = input->positionToRectangle(0).x(); + for (int i = 2; i >= 0; --i) { + sendPreeditText(preeditText, preeditText.length() - i); + QCOMPARE(input->positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + } + for (int i = 1; i < 3; ++i) { + sendPreeditText(preeditText, preeditText.length() - i); + QCOMPARE(input->positionToRectangle(0).x(), x); + QCOMPARE(cursorRectangleSpy.count(), ++cursorRectangleChanges); + } + + // Test disabling auto scroll. + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + + input->setAutoScroll(false); + sendPreeditText(preeditText.mid(0, 3), 1); + QCOMPARE(input->positionAt(0), 0); + QCOMPARE(input->positionAt(input->width()), 5); +} + +void tst_qquicktextinput::preeditCursorRectangle() +{ + QString preeditText = "super"; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputMethodEvent.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextInput *input = qobject_cast(view.rootObject()); + QVERIFY(input); + + QRect currentRect; + + QInputMethodQueryEvent query(Qt::ImCursorRectangle); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + QRect previousRect = query.value(Qt::ImCursorRectangle).toRect(); + + // Verify that the micro focus rect is positioned the same for position 0 as + // it would be if there was no preedit text. + sendPreeditText(preeditText, 0); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QCOMPARE(currentRect, previousRect); + + QSignalSpy inputSpy(input, SIGNAL(cursorRectangleChanged())); + QSignalSpy panelSpy(qGuiApp->inputPanel(), SIGNAL(cursorRectangleChanged())); + + // Verify that the micro focus rect moves to the left as the cursor position + // is incremented. + for (int i = 1; i <= 5; ++i) { + sendPreeditText(preeditText, i); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QVERIFY(previousRect.left() < currentRect.left()); + QVERIFY(inputSpy.count() > 0); inputSpy.clear(); + QVERIFY(panelSpy.count() > 0); panelSpy.clear(); + previousRect = currentRect; + } + + // Verify that if there is no preedit cursor then the micro focus rect is the + // same as it would be if it were positioned at the end of the preedit text. + sendPreeditText(preeditText, 0); + QInputMethodEvent imEvent(preeditText, QList()); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &imEvent); + QCoreApplication::sendEvent(qGuiApp->inputPanel()->inputItem(), &query); + currentRect = query.value(Qt::ImCursorRectangle).toRect(); + QCOMPARE(currentRect, previousRect); + QVERIFY(inputSpy.count() > 0); + QVERIFY(panelSpy.count() > 0); +} + +void tst_qquicktextinput::inputContextMouseHandler() +{ + PlatformInputContext platformInputContext; + QInputPanelPrivate *inputPanelPrivate = QInputPanelPrivate::get(qApp->inputPanel()); + inputPanelPrivate->testContext = &platformInputContext; + + QString text = "supercalifragisiticexpialidocious!"; + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); + QQuickTextInput *input = qobject_cast(view.rootObject()); + QVERIFY(input); + + input->setFocus(true); + input->setText(""); + + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QFontMetricsF fm(input->font()); + const qreal y = fm.height() / 2; + QPoint position = QPointF(fm.width(text.mid(0, 2)), y).toPoint(); + + QInputMethodEvent inputEvent(text.mid(0, 5), QList()); + QApplication::sendEvent(input, &inputEvent); + + QTest::mousePress(&view, Qt::LeftButton, Qt::NoModifier, position); + QTest::mouseRelease(&view, Qt::LeftButton, Qt::NoModifier, position); + QGuiApplication::processEvents(); + + QCOMPARE(platformInputContext.m_action, QInputPanel::Click); + QCOMPARE(platformInputContext.m_invokeActionCallCount, 1); + QCOMPARE(platformInputContext.m_cursorPosition, 2); +} + +void tst_qquicktextinput::inputMethodComposing() +{ + QString text = "supercalifragisiticexpialidocious!"; + + QQuickView view(QUrl::fromLocalFile(TESTDATA("inputContext.qml"))); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + QQuickTextInput *input = qobject_cast(view.rootObject()); + QVERIFY(input); + QSignalSpy spy(input, SIGNAL(inputMethodComposingChanged())); + + QCOMPARE(input->isInputMethodComposing(), false); + { + QInputMethodEvent event(text.mid(3), QList()); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), true); + QCOMPARE(spy.count(), 1); + + { + QInputMethodEvent event(text.mid(12), QList()); + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(spy.count(), 1); + + { + QInputMethodEvent event; + QGuiApplication::sendEvent(input, &event); + } + QCOMPARE(input->isInputMethodComposing(), false); + QCOMPARE(spy.count(), 2); +} + +void tst_qquicktextinput::cursorRectangleSize() +{ + QQuickView *canvas = new QQuickView(QUrl::fromLocalFile(TESTDATA("positionAt.qml"))); + QVERIFY(canvas->rootObject() != 0); + QQuickTextInput *textInput = qobject_cast(canvas->rootObject()); + + // make sure cursor rectangle is not at (0,0) + textInput->setX(10); + textInput->setY(10); + textInput->setCursorPosition(3); + QVERIFY(textInput != 0); + textInput->setFocus(true); + canvas->show(); + canvas->requestActivateWindow(); + QTest::qWaitForWindowShown(canvas); + + QInputMethodQueryEvent event(Qt::ImCursorRectangle); + qApp->sendEvent(qApp->inputPanel()->inputItem(), &event); + QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); + + QRect cursorRectFromItem = textInput->cursorRectangle(); + QRectF cursorRectFromPositionToRectangle = textInput->positionToRectangle(textInput->cursorPosition()); + + // item and input query cursor rectangles match + QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + + // item cursor rectangle and positionToRectangle calculations match + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + + // item-canvas transform and input item transform match + QCOMPARE(QQuickItemPrivate::get(textInput)->itemToCanvasTransform(), qApp->inputPanel()->inputItemTransform()); + + // input panel cursorRectangle property and tranformed item cursor rectangle match + QRectF sceneCursorRect = QQuickItemPrivate::get(textInput)->itemToCanvasTransform().mapRect(cursorRectFromItem); + QCOMPARE(sceneCursorRect, qApp->inputPanel()->cursorRectangle()); + + delete canvas; +} + +void tst_qquicktextinput::tripleClickSelectsAll() +{ + QString qmlfile = TESTDATA("positionAt.qml"); + QQuickView view(QUrl::fromLocalFile(qmlfile)); + view.show(); + view.requestActivateWindow(); + QTest::qWaitForWindowShown(&view); + + QTRY_COMPARE(&view, qGuiApp->focusWindow()); + + QQuickTextInput* input = qobject_cast(view.rootObject()); + QVERIFY(input); + + QLatin1String hello("Hello world!"); + input->setSelectByMouse(true); + input->setText(hello); + + // Clicking on the same point inside TextInput three times in a row + // should trigger a triple click, thus selecting all the text. + QPoint pointInside = input->pos().toPoint() + QPoint(2,2); + QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); + QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside); + QGuiApplication::processEvents(); + QCOMPARE(input->selectedText(), hello); + + // Now it simulates user moving the mouse between the second and the third click. + // In this situation, we don't expect a triple click. + QPoint pointInsideButFar = QPoint(input->width(),input->height()) - QPoint(2,2); + QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); + QTest::mouseClick(&view, Qt::LeftButton, 0, pointInsideButFar); + QGuiApplication::processEvents(); + QVERIFY(input->selectedText().isEmpty()); + + // And now we press the third click too late, so no triple click event is triggered. + QTest::mouseDClick(&view, Qt::LeftButton, 0, pointInside); + QGuiApplication::processEvents(); + QTest::qWait(qApp->styleHints()->mouseDoubleClickInterval() + 1); + QTest::mouseClick(&view, Qt::LeftButton, 0, pointInside); + QGuiApplication::processEvents(); + QVERIFY(input->selectedText().isEmpty()); +} + +void tst_qquicktextinput::QTBUG_19956_data() +{ + QTest::addColumn("url"); + QTest::newRow("intvalidator") << "qtbug-19956int.qml"; + QTest::newRow("doublevalidator") << "qtbug-19956double.qml"; +} + +void tst_qquicktextinput::keySequence_data() +{ + QTest::addColumn("text"); + QTest::addColumn("sequence"); + QTest::addColumn("selectionStart"); + QTest::addColumn("selectionEnd"); + QTest::addColumn("cursorPosition"); + QTest::addColumn("expectedText"); + QTest::addColumn("selectedText"); + + // standard[0] == "the [4]quick [10]brown [16]fox [20]jumped [27]over [32]the [36]lazy [41]dog" + + QTest::newRow("select all") + << standard.at(0) << QKeySequence(QKeySequence::SelectAll) << 0 << 0 + << 44 << standard.at(0) << standard.at(0); + QTest::newRow("select end of line") + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfLine) << 5 << 5 + << 44 << standard.at(0) << standard.at(0).mid(5); + QTest::newRow("select end of document") // ### Not handled. + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfDocument) << 3 << 3 + << 3 << standard.at(0) << QString(); + QTest::newRow("select end of block") + << standard.at(0) << QKeySequence(QKeySequence::SelectEndOfBlock) << 18 << 18 + << 44 << standard.at(0) << standard.at(0).mid(18); + QTest::newRow("delete end of line") + << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfLine) << 24 << 24 + << 24 << standard.at(0).mid(0, 24) << QString(); + QTest::newRow("move to start of line") + << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfLine) << 31 << 31 + << 0 << standard.at(0) << QString(); + QTest::newRow("move to start of block") + << standard.at(0) << QKeySequence(QKeySequence::MoveToStartOfBlock) << 25 << 25 + << 0 << standard.at(0) << QString(); + QTest::newRow("move to next char") + << standard.at(0) << QKeySequence(QKeySequence::MoveToNextChar) << 12 << 12 + << 13 << standard.at(0) << QString(); + QTest::newRow("move to previous char") + << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousChar) << 3 << 3 + << 2 << standard.at(0) << QString(); + QTest::newRow("select next char") + << standard.at(0) << QKeySequence(QKeySequence::SelectNextChar) << 23 << 23 + << 24 << standard.at(0) << standard.at(0).mid(23, 1); + QTest::newRow("select previous char") + << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousChar) << 19 << 19 + << 18 << standard.at(0) << standard.at(0).mid(18, 1); + QTest::newRow("move to next word") + << standard.at(0) << QKeySequence(QKeySequence::MoveToNextWord) << 7 << 7 + << 10 << standard.at(0) << QString(); + QTest::newRow("move to previous word") + << standard.at(0) << QKeySequence(QKeySequence::MoveToPreviousWord) << 7 << 7 + << 4 << standard.at(0) << QString(); + QTest::newRow("select previous word") + << standard.at(0) << QKeySequence(QKeySequence::SelectPreviousWord) << 11 << 11 + << 10 << standard.at(0) << standard.at(0).mid(10, 1); + QTest::newRow("delete (selection)") + << standard.at(0) << QKeySequence(QKeySequence::Delete) << 12 << 15 + << 12 << (standard.at(0).mid(0, 12) + standard.at(0).mid(15)) << QString(); + QTest::newRow("delete (no selection)") + << standard.at(0) << QKeySequence(QKeySequence::Delete) << 15 << 15 + << 15 << (standard.at(0).mid(0, 15) + standard.at(0).mid(16)) << QString(); + QTest::newRow("delete end of word") + << standard.at(0) << QKeySequence(QKeySequence::DeleteEndOfWord) << 24 << 24 + << 24 << (standard.at(0).mid(0, 24) + standard.at(0).mid(27)) << QString(); + QTest::newRow("delete start of word") + << standard.at(0) << QKeySequence(QKeySequence::DeleteStartOfWord) << 7 << 7 + << 4 << (standard.at(0).mid(0, 4) + standard.at(0).mid(7)) << QString(); +} + +void tst_qquicktextinput::keySequence() +{ + QFETCH(QString, text); + QFETCH(QKeySequence, sequence); + QFETCH(int, selectionStart); + QFETCH(int, selectionEnd); + QFETCH(int, cursorPosition); + QFETCH(QString, expectedText); + QFETCH(QString, selectedText); + + if (sequence.isEmpty()) { + QSKIP("Key sequence is undefined"); + } + + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true; text: \"" + text + "\" }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + textInput->select(selectionStart, selectionEnd); + + simulateKeys(&canvas, sequence); + + QCOMPARE(textInput->cursorPosition(), cursorPosition); + QCOMPARE(textInput->text(), expectedText); + QCOMPARE(textInput->selectedText(), selectedText); +} + +#define NORMAL 0 +#define REPLACE_UNTIL_END 1 + +void tst_qquicktextinput::undo_data() +{ + QTest::addColumn("insertString"); + QTest::addColumn("insertIndex"); + QTest::addColumn("insertMode"); + QTest::addColumn("expectedString"); + QTest::addColumn("use_keys"); + + for (int i=0; i<2; i++) { + QString keys_str = "keyboard"; + bool use_keys = true; + if (i==0) { + keys_str = "insert"; + use_keys = false; + } + + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "1"; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "5"; + + insertIndex << 1; + insertMode << NORMAL; + insertString << "3"; + + insertIndex << 1; + insertMode << NORMAL; + insertString << "2"; + + insertIndex << 3; + insertMode << NORMAL; + insertString << "4"; + + expectedString << "12345"; + expectedString << "1235"; + expectedString << "135"; + expectedString << "15"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_numbers").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "World"; // World + + insertIndex << 0; + insertMode << NORMAL; + insertString << "Hello"; // HelloWorld + + insertIndex << 0; + insertMode << NORMAL; + insertString << "Well"; // WellHelloWorld + + insertIndex << 9; + insertMode << NORMAL; + insertString << "There"; // WellHelloThereWorld; + + expectedString << "WellHelloThereWorld"; + expectedString << "WellHelloWorld"; + expectedString << "HelloWorld"; + expectedString << "World"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_helloworld").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + { + IntList insertIndex; + IntList insertMode; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertMode << NORMAL; + insertString << "Ensuring"; + + insertIndex << -1; + insertMode << NORMAL; + insertString << " instan"; + + insertIndex << 9; + insertMode << NORMAL; + insertString << "an "; + + insertIndex << 10; + insertMode << REPLACE_UNTIL_END; + insertString << " unique instance."; + + expectedString << "Ensuring a unique instance."; + expectedString << "Ensuring an instan"; + expectedString << "Ensuring instan"; + expectedString << ""; + + QTest::newRow(QString(keys_str + "_patterns").toLatin1()) << + insertString << + insertIndex << + insertMode << + expectedString << + bool(use_keys); + } + } +} + +void tst_qquicktextinput::undo() +{ + QFETCH(QStringList, insertString); + QFETCH(IntList, insertIndex); + QFETCH(IntList, insertMode); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + int i; + +// STEP 1: First build up an undo history by inserting or typing some strings... + for (i = 0; i < insertString.size(); ++i) { + if (insertIndex[i] > -1) + textInput->setCursorPosition(insertIndex[i]); + + // experimental stuff + if (insertMode[i] == REPLACE_UNTIL_END) { + textInput->select(insertIndex[i], insertIndex[i] + 8); + + // This is what I actually want... + // QTest::keyClick(testWidget, Qt::Key_End, Qt::ShiftModifier); + } + + for (int j = 0; j < insertString.at(i).length(); j++) + QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); + } + +// STEP 2: Next call undo several times and see if we can restore to the previous state + for (i = 0; i < expectedString.size() - 1; ++i) { + QCOMPARE(textInput->text(), expectedString[i]); + simulateKeys(&canvas, QKeySequence::Undo); + } + +// STEP 3: Verify that we have undone everything + QVERIFY(textInput->text().isEmpty()); +} + +void tst_qquicktextinput::redo_data() +{ + QTest::addColumn("insertString"); + QTest::addColumn("insertIndex"); + QTest::addColumn("expectedString"); + + { + IntList insertIndex; + QStringList insertString; + QStringList expectedString; + + insertIndex << -1; + insertString << "World"; // World + insertIndex << 0; + insertString << "Hello"; // HelloWorld + insertIndex << 0; + insertString << "Well"; // WellHelloWorld + insertIndex << 9; + insertString << "There"; // WellHelloThereWorld; + + expectedString << "World"; + expectedString << "HelloWorld"; + expectedString << "WellHelloWorld"; + expectedString << "WellHelloThereWorld"; + + QTest::newRow("Inserts and setting cursor") << insertString << insertIndex << expectedString; + } +} + +void tst_qquicktextinput::redo() +{ + QFETCH(QStringList, insertString); + QFETCH(IntList, insertIndex); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + int i; + // inserts the diff strings at diff positions + for (i = 0; i < insertString.size(); ++i) { + if (insertIndex[i] > -1) + textInput->setCursorPosition(insertIndex[i]); + for (int j = 0; j < insertString.at(i).length(); j++) + QTest::keyClick(&canvas, insertString.at(i).at(j).toLatin1()); + } + + // undo everything + while (!textInput->text().isEmpty()) + simulateKeys(&canvas, QKeySequence::Undo); + + for (i = 0; i < expectedString.size(); ++i) { + simulateKeys(&canvas, QKeySequence::Redo); + QCOMPARE(textInput->text() , expectedString[i]); + } +} + +void tst_qquicktextinput::undo_keypressevents_data() +{ + QTest::addColumn("keys"); + QTest::addColumn("expectedString"); + + { + KeyList keys; + QStringList expectedString; + + keys << "AFRAID" + << Qt::Key_Home + << "VERY" + << Qt::Key_Left + << Qt::Key_Left + << Qt::Key_Left + << Qt::Key_Left + << "BE" + << Qt::Key_End + << "!"; + + expectedString << "BEVERYAFRAID!"; + expectedString << "BEVERYAFRAID"; + expectedString << "VERYAFRAID"; + expectedString << "AFRAID"; + + QTest::newRow("Inserts and moving cursor") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting '1234' + keys << "1234" << Qt::Key_Home + // skipping '12' + << Qt::Key_Right << Qt::Key_Right + // selecting '34' + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + // deleting '34' + << Qt::Key_Delete; + + expectedString << "12"; + expectedString << "1234"; + + QTest::newRow("Inserts,moving,selection and delete") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'AB12' + keys << "AB12" + << Qt::Key_Home + // selecting 'AB' + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + << Qt::Key_Delete + << QKeySequence::Undo + << Qt::Key_Right +#ifdef Q_OS_WIN //Mac(?) has a specialcase to handle jumping to the end of a selection + << Qt::Key_Left +#endif + << (Qt::Key_Right | Qt::ShiftModifier) << (Qt::Key_Right | Qt::ShiftModifier) + << Qt::Key_Delete; + + expectedString << "AB"; + expectedString << "AB12"; + + QTest::newRow("Inserts,moving,selection, delete and undo") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'ABCD' + keys << "abcd" + //move left two + << Qt::Key_Left << Qt::Key_Left + // inserting '1234' + << "1234" + // selecting '1234' + << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) << (Qt::Key_Left | Qt::ShiftModifier) + // overwriting '1234' with '5' + << "5" + // undoing deletion of 'AB' + << QKeySequence::Undo + // overwriting '1234' with '6' + << "6"; + + expectedString << "ab6cd"; + // for versions previous to 3.2 we overwrite needed two undo operations + expectedString << "ab1234cd"; + expectedString << "abcd"; + + QTest::newRow("Inserts,moving,selection and undo, removing selection") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting 'ABC' + keys << "ABC" + // removes 'C' + << Qt::Key_Backspace; + + expectedString << "AB"; + expectedString << "ABC"; + + QTest::newRow("Inserts,backspace") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + keys << "ABC" + // removes 'C' + << Qt::Key_Backspace + // inserting 'Z' + << "Z"; + + expectedString << "ABZ"; + expectedString << "AB"; + expectedString << "ABC"; + + QTest::newRow("Inserts,backspace,inserts") << keys << expectedString; + } { + KeyList keys; + QStringList expectedString; + + // inserting '123' + keys << "123" << Qt::Key_Home + // selecting '123' + << (Qt::Key_End | Qt::ShiftModifier) + // overwriting '123' with 'ABC' + << "ABC"; + + expectedString << "ABC"; + // for versions previous to 3.2 we overwrite needed two undo operations + expectedString << "123"; + + QTest::newRow("Inserts,moving,selection and overwriting") << keys << expectedString; + } +} + +void tst_qquicktextinput::undo_keypressevents() +{ + QFETCH(KeyList, keys); + QFETCH(QStringList, expectedString); + + QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }"; + QDeclarativeComponent textInputComponent(&engine); + textInputComponent.setData(componentStr.toLatin1(), QUrl()); + QQuickTextInput *textInput = qobject_cast(textInputComponent.create()); + QVERIFY(textInput != 0); + + QQuickCanvas canvas; + textInput->setParentItem(canvas.rootItem()); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QTRY_COMPARE(QGuiApplication::activeWindow(), &canvas); + + simulateKeys(&canvas, keys); + + for (int i = 0; i < expectedString.size(); ++i) { + QCOMPARE(textInput->text() , expectedString[i]); + simulateKeys(&canvas, QKeySequence::Undo); + } + QVERIFY(textInput->text().isEmpty()); +} + +void tst_qquicktextinput::QTBUG_19956() +{ + QFETCH(QString, url); + + QQuickView canvas(QUrl::fromLocalFile(TESTDATA(url))); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *input = qobject_cast(canvas.rootObject()); + QVERIFY(input); + input->setFocus(true); + QVERIFY(input->hasActiveFocus()); + + QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 30); + QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10); + QCOMPARE(canvas.rootObject()->property("text").toString(), QString("20")); + QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("topvalue", 15); + QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 15); + QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("topvalue", 25); + QCOMPARE(canvas.rootObject()->property("topvalue").toInt(), 25); + QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("bottomvalue", 21); + QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 21); + QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("bottomvalue", 10); + QCOMPARE(canvas.rootObject()->property("bottomvalue").toInt(), 10); + QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); +} + +void tst_qquicktextinput::QTBUG_19956_regexp() +{ + QUrl url = QUrl::fromLocalFile(TESTDATA("qtbug-19956regexp.qml")); + + QString warning = url.toString() + ":11: Unable to assign [undefined] to QRegExp"; + QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); + + QQuickView canvas(url); + canvas.show(); + canvas.requestActivateWindow(); + QTest::qWaitForWindowShown(&canvas); + QVERIFY(canvas.rootObject() != 0); + QQuickTextInput *input = qobject_cast(canvas.rootObject()); + QVERIFY(input); + input->setFocus(true); + QVERIFY(input->hasActiveFocus()); + + canvas.rootObject()->setProperty("regexvalue", QRegExp("abc")); + QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc")); + QCOMPARE(canvas.rootObject()->property("text").toString(), QString("abc")); + QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("regexvalue", QRegExp("abcd")); + QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abcd")); + QVERIFY(!canvas.rootObject()->property("acceptableInput").toBool()); + + canvas.rootObject()->setProperty("regexvalue", QRegExp("abc")); + QCOMPARE(canvas.rootObject()->property("regexvalue").toRegExp(), QRegExp("abc")); + QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); +} + +QTEST_MAIN(tst_qquicktextinput) + +#include "tst_qquicktextinput.moc" diff --git a/tests/auto/qtquick2/qquickview/data/error1.qml b/tests/auto/qtquick2/qquickview/data/error1.qml new file mode 100644 index 0000000000..09df679555 --- /dev/null +++ b/tests/auto/qtquick2/qquickview/data/error1.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 + +Rectangle { + nonExistentProperty: 5 +} diff --git a/tests/auto/qtquick2/qquickview/data/resizemodeitem.qml b/tests/auto/qtquick2/qquickview/data/resizemodeitem.qml new file mode 100644 index 0000000000..ed73009b26 --- /dev/null +++ b/tests/auto/qtquick2/qquickview/data/resizemodeitem.qml @@ -0,0 +1,5 @@ +import QtQuick 2.0 +Item { + width: 200 + height: 200 +} diff --git a/tests/auto/qtquick2/qquickview/qquickview.pro b/tests/auto/qtquick2/qquickview/qquickview.pro new file mode 100644 index 0000000000..d4e7c064fa --- /dev/null +++ b/tests/auto/qtquick2/qquickview/qquickview.pro @@ -0,0 +1,11 @@ +CONFIG += testcase +TARGET = tst_qquickview +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickview.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +QT += core-private gui-private declarative-private quick-private testlib diff --git a/tests/auto/qtquick2/qquickview/tst_qquickview.cpp b/tests/auto/qtquick2/qquickview/tst_qquickview.cpp new file mode 100644 index 0000000000..953374dcab --- /dev/null +++ b/tests/auto/qtquick2/qquickview/tst_qquickview.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "../../shared/util.h" +#include +#include + +class tst_QQuickView : public QObject +{ + Q_OBJECT +public: + tst_QQuickView(); + +private slots: + void resizemodeitem(); + void errors(); +}; + + +tst_QQuickView::tst_QQuickView() +{ +} + +void tst_QQuickView::resizemodeitem() +{ + QWindow window; + window.setGeometry(0, 0, 400, 400); + + QQuickView *canvas = new QQuickView(&window); + QVERIFY(canvas); + canvas->setResizeMode(QQuickView::SizeRootObjectToView); + QCOMPARE(QSize(0,0), canvas->initialSize()); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); + QQuickItem* item = qobject_cast(canvas->rootObject()); + QVERIFY(item); + window.show(); + + canvas->show(); + + // initial size from root object + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 200.0); + QCOMPARE(canvas->size(), QSize(200, 200)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + QCOMPARE(canvas->size(), canvas->initialSize()); + + // size update from view + canvas->resize(QSize(80,100)); + + QTRY_COMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QCOMPARE(canvas->size(), QSize(80, 100)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + + canvas->setResizeMode(QQuickView::SizeViewToRootObject); + + // size update from view disabled + canvas->resize(QSize(60,80)); + QCOMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QTest::qWait(50); + QCOMPARE(canvas->size(), QSize(60, 80)); + + // size update from root object + item->setWidth(250); + item->setHeight(350); + QCOMPARE(item->width(), 250.0); + QCOMPARE(item->height(), 350.0); + QTRY_COMPARE(canvas->size(), QSize(250, 350)); + QCOMPARE(canvas->size(), QSize(250, 350)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + + // reset canvas + window.hide(); + delete canvas; + canvas = new QQuickView(&window); + QVERIFY(canvas); + canvas->setResizeMode(QQuickView::SizeViewToRootObject); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); + item = qobject_cast(canvas->rootObject()); + QVERIFY(item); + window.show(); + + canvas->show(); + + // initial size for root object + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 200.0); + QCOMPARE(canvas->size(), canvas->sizeHint()); + QCOMPARE(canvas->size(), canvas->initialSize()); + + // size update from root object + item->setWidth(80); + item->setHeight(100); + QCOMPARE(item->width(), 80.0); + QCOMPARE(item->height(), 100.0); + QTRY_COMPARE(canvas->size(), QSize(80, 100)); + QCOMPARE(canvas->size(), QSize(80, 100)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + + // size update from root object disabled + canvas->setResizeMode(QQuickView::SizeRootObjectToView); + item->setWidth(60); + item->setHeight(80); + QCOMPARE(canvas->width(), 80); + QCOMPARE(canvas->height(), 100); + QCOMPARE(QSize(item->width(), item->height()), canvas->sizeHint()); + + // size update from view + canvas->resize(QSize(200,300)); + QTest::qWait(50); + QCOMPARE(item->width(), 200.0); + QCOMPARE(item->height(), 300.0); + QCOMPARE(canvas->size(), QSize(200, 300)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + + window.hide(); + delete canvas; + + // if we set a specific size for the view then it should keep that size + // for SizeRootObjectToView mode. + canvas = new QQuickView(&window); + canvas->resize(300, 300); + canvas->setResizeMode(QQuickView::SizeRootObjectToView); + QCOMPARE(QSize(0,0), canvas->initialSize()); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("resizemodeitem.qml"))); + canvas->resize(300, 300); + item = qobject_cast(canvas->rootObject()); + QVERIFY(item); + window.show(); + + canvas->show(); + QTest::qWait(50); + + // initial size from root object + QCOMPARE(item->width(), 300.0); + QCOMPARE(item->height(), 300.0); + QCOMPARE(canvas->size(), QSize(300, 300)); + QCOMPARE(canvas->size(), canvas->sizeHint()); + QCOMPARE(canvas->initialSize(), QSize(200, 200)); // initial object size + + delete canvas; +} + +static void silentErrorsMsgHandler(QtMsgType, const char *) +{ +} + +void tst_QQuickView::errors() +{ + QQuickView *canvas = new QQuickView; + QVERIFY(canvas); + QtMsgHandler old = qInstallMsgHandler(silentErrorsMsgHandler); + canvas->setSource(QUrl::fromLocalFile(TESTDATA("error1.qml"))); + qInstallMsgHandler(old); + QVERIFY(canvas->status() == QQuickView::Error); + QVERIFY(canvas->errors().count() == 1); + delete canvas; +} + + +QTEST_MAIN(tst_QQuickView) + +#include "tst_qquickview.moc" diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/create.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/create.qml new file mode 100644 index 0000000000..3475a0dace --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/create.qml @@ -0,0 +1,25 @@ +import QtQuick 2.0 + +ListView { + width: 200 + height: 200 + + model: VisualDataModel { + id: visualModel + + persistedItems.includeByDefault: true + + model: myModel + delegate: Item { + id: delegate + objectName: "delegate" + width: 200 + height: 20 + + property bool destroyed: false + + + Component.onDestruction: destroyed = true + } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist-package.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist-package.qml new file mode 100644 index 0000000000..ae3bd81d91 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist-package.qml @@ -0,0 +1,20 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: visualModel.parts.package + VisualDataModel { + id: visualModel + objectName: "visualModel" + model: myModel + delegate: Package { + Rectangle { + height: 25 + width: 100 + Package.name: "package" + Text { objectName: "display"; text: display } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist.qml new file mode 100644 index 0000000000..8ce59caddc --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/datalist.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: VisualDataModel { + id: visualModel + objectName: "visualModel" + model: myModel + delegate: Component { + Rectangle { + height: 25 + width: 100 + Text { objectName: "display"; text: display } + } + } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-invalid.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-invalid.qml new file mode 100644 index 0000000000..70c6f9f995 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-invalid.qml @@ -0,0 +1,14 @@ +import QtQuick 2.0 + +VisualDataModel { + id: visualModel + + objectName: "visualModel" + + groups: [ + VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, + VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" }, + VisualDataGroup { id: unnamed; objectName: "unnamed" }, + VisualDataGroup { id: capitalised; objectName: "capitalised"; name: "Capitalised" } + ] +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-package.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-package.qml new file mode 100644 index 0000000000..ea5ad5d3bd --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups-package.qml @@ -0,0 +1,52 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + + function contains(array, value) { + for (var i = 0; i < array.length; ++i) + if (array[i] == value) + return true + return false + } + model: visualModel.parts.package + + VisualDataModel { + id: visualModel + + objectName: "visualModel" + + groups: [ + VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, + VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" } + ] + + model: myModel + delegate: Package { + id: delegate + + property variant test1: name + property variant test2: index + property variant test3: VisualDataModel.itemsIndex + property variant test4: VisualDataModel.inItems + property variant test5: VisualDataModel.visibleIndex + property variant test6: VisualDataModel.inVisible + property variant test7: VisualDataModel.selectedIndex + property variant test8: VisualDataModel.inSelected + property variant test9: VisualDataModel.groups + + function hide() { VisualDataModel.inVisible = false } + function select() { VisualDataModel.inSelected = true } + + Item { + Package.name: "package" + + objectName: "delegate" + width: 100 + height: 2 + } + } + } + +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/groups.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups.qml new file mode 100644 index 0000000000..7502dd2502 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/groups.qml @@ -0,0 +1,46 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + + function contains(array, value) { + for (var i = 0; i < array.length; ++i) + if (array[i] == value) + return true + return false + } + + model: visualModel + VisualDataModel { + id: visualModel + + objectName: "visualModel" + + groups: [ + VisualDataGroup { id: visibleItems; objectName: "visibleItems"; name: "visible"; includeByDefault: true }, + VisualDataGroup { id: selectedItems; objectName: "selectedItems"; name: "selected" } + ] + + model: myModel + delegate: Item { + id: delegate + + objectName: "delegate" + width: 100 + height: 2 + property variant test1: name + property variant test2: index + property variant test3: VisualDataModel.itemsIndex + property variant test4: VisualDataModel.inItems + property variant test5: VisualDataModel.visibleIndex + property variant test6: VisualDataModel.inVisible + property variant test7: VisualDataModel.selectedIndex + property variant test8: VisualDataModel.inSelected + property variant test9: VisualDataModel.groups + + function hide() { VisualDataModel.inVisible = false } + function select() { VisualDataModel.inSelected = true } + } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_listView.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_listView.qml new file mode 100644 index 0000000000..103c4d2eb6 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_listView.qml @@ -0,0 +1,13 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 100 + height: 20 + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_package.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_package.qml new file mode 100644 index 0000000000..b47f22dc34 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_package.qml @@ -0,0 +1,42 @@ +import QtQuick 2.0 + +Item { + width: 100 + height: 100 + + ListView { + anchors.fill: parent + + model: visualModel.parts.list + } + VisualDataModel { + id: visualModel + + model: myModel + delegate: Package { + Item { + Package.name: "list" + width: 100 + height: 20 + } + + Item { + id: gridItem + Package.name: "grid" + width: 50 + height: 50 + } + Rectangle { + objectName: "delegate" + parent: gridItem + width: 20 + height: 20 + } + } + } + GridView { + anchors.fill: parent + + model: visualModel.parts.grid + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml new file mode 100644 index 0000000000..bc619124fd --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_pathView.qml @@ -0,0 +1,18 @@ +import QtQuick 2.0 + +PathView { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 100 + height: 20 + } + + path: Path { + startX: 50; startY: 0 + PathLine { x: 50; y: 100 } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml new file mode 100644 index 0000000000..e97e0dad2e --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/itemsDestroyed_repeater.qml @@ -0,0 +1,15 @@ +import QtQuick 2.0 + +Grid { + Repeater { + width: 100 + height: 100 + + model: myModel + delegate: Item { + objectName: "delegate" + width: 50 + height: 50 + } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties.qml new file mode 100644 index 0000000000..73b766f1af --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: myModel + delegate: Item { + objectName: "delegate" + width: 100 + height: 2 + property variant test1: name + property variant test2: model.name + property variant test3: modelData + property variant test4: model.modelData + property variant test5: modelData.name + property variant test6: model + property variant test7: index + property variant test8: model.index + property variant test9: model.modelData.name + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties2.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties2.qml new file mode 100644 index 0000000000..ea5c240b29 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/modelproperties2.qml @@ -0,0 +1,21 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: myModel + delegate: Item { + objectName: "delegate" + property variant test1: display + property variant test2: model.display + property variant test3: modelData + property variant test4: model.modelData + property variant test5: modelData.display + property variant test6: model + property variant test7: index + property variant test8: model.index + property variant test9: model.modelData.display + width: 100 + height: 2 + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/objectlist.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/objectlist.qml new file mode 100644 index 0000000000..b3952a8a4d --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/objectlist.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: myModel + delegate: Component { + Rectangle { + height: 25 + width: 100 + color: model.modelData.color + Text { objectName: "name"; text: name; function getText() { return name } } + Text { objectName: "section"; text: parent.ListView.section } + } + } + section.property: "name" + section.criteria: ViewSection.FullString +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/onChanged.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/onChanged.qml new file mode 100644 index 0000000000..71dc7d72d7 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/onChanged.qml @@ -0,0 +1,87 @@ +import QtQuick 2.0 + +VisualDataModel { + id: vm + + property var inserted + property var removed + + Component.onCompleted: { + vm.inserted = [] + vm.removed = [] + vi.inserted = [] + vi.removed = [] + si.inserted = [] + si.removed = [] + } + + function verify(changes, indexes, counts, moveIds) { + if (changes.length != indexes.length + || changes.length != counts.length + || changes.length != moveIds.length) { + console.log("invalid length", changes.length, indexes.length, counts.length, moveIds.length) + return false + } + + var valid = true; + for (var i = 0; i < changes.length; ++i) { + if (changes[i].index != indexes[i]) { + console.log(i, "incorrect index. actual:", changes[i].index, "expected:", indexes[i]) + valid = false; + } + if (changes[i].count != counts[i]) { + console.log(i, "incorrect count. actual:", changes[i].count, "expected:", counts[i]) + valid = false; + } + if (changes[i].moveId != moveIds[i]) { + console.log(i, "incorrect moveId. actual:", changes[i].moveId, "expected:", moveIds[i]) + valid = false; + } + } + return valid + } + + groups: [ + VisualDataGroup { + id: vi; + + property var inserted + property var removed + + name: "visible" + includeByDefault: true + + onChanged: { + vi.inserted = inserted + vi.removed = removed + } + }, + VisualDataGroup { + id: si; + + property var inserted + property var removed + + name: "selected" + onChanged: { + si.inserted = inserted + si.removed = removed + } + } + ] + + model: ListModel { + id: listModel + ListElement { number: "one" } + ListElement { number: "two" } + ListElement { number: "three" } + ListElement { number: "four" } + } + + delegate: Item {} + + items.onChanged: { + vm.inserted = inserted + vm.removed = removed + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole1.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole1.qml new file mode 100644 index 0000000000..c471893e1d --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole1.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: myModel + delegate: Component { + Text { objectName: "name"; text: name; function getText() { return name; } } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole2.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole2.qml new file mode 100644 index 0000000000..ab1798999d --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/singlerole2.qml @@ -0,0 +1,10 @@ +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + model: myModel + delegate: Component { + Text { objectName: "name"; text: modelData; function getText() { return modelData } } + } +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/data/visualdatamodel.qml b/tests/auto/qtquick2/qquickvisualdatamodel/data/visualdatamodel.qml new file mode 100644 index 0000000000..0d4d9e2e46 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/data/visualdatamodel.qml @@ -0,0 +1,12 @@ +import QtQuick 2.0 + +VisualDataModel { + function setRoot() { + rootIndex = modelIndex(0); + } + function setRootToParent() { + rootIndex = parentModelIndex(); + } + model: myModel + delegate: Item {} +} diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/qquickvisualdatamodel.pro b/tests/auto/qtquick2/qquickvisualdatamodel/qquickvisualdatamodel.pro new file mode 100644 index 0000000000..8e87e10a97 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/qquickvisualdatamodel.pro @@ -0,0 +1,13 @@ +CONFIG += testcase +TARGET = tst_qquickvisualdatamodel +macx:CONFIG -= app_bundle + +SOURCES += tst_qquickvisualdatamodel.cpp + +testDataFiles.files = data +testDataFiles.path = . +DEPLOYMENT += testDataFiles + +CONFIG += parallel_test + +QT += core-private gui-private v8-private declarative-private quick-private widgets testlib diff --git a/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp new file mode 100644 index 0000000000..f0e6228d29 --- /dev/null +++ b/tests/auto/qtquick2/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp @@ -0,0 +1,1865 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "../../shared/util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template int lengthOf(const T (&)[N]) { return N; } + +static void initStandardTreeModel(QStandardItemModel *model) +{ + QStandardItem *item; + item = new QStandardItem(QLatin1String("Row 1 Item")); + model->insertRow(0, item); + + item = new QStandardItem(QLatin1String("Row 2 Item")); + item->setCheckable(true); + model->insertRow(1, item); + + QStandardItem *childItem = new QStandardItem(QLatin1String("Row 2 Child Item")); + item->setChild(0, childItem); + + item = new QStandardItem(QLatin1String("Row 3 Item")); + item->setIcon(QIcon()); + model->insertRow(2, item); +} + +class SingleRoleModel : public QAbstractListModel +{ + Q_OBJECT + +public: + SingleRoleModel(const QByteArray &role = "name", QObject * /* parent */ = 0) { + QHash roles; + roles.insert(Qt::DisplayRole , role); + setRoleNames(roles); + list << "one" << "two" << "three" << "four"; + } + + void emitMove(int sourceFirst, int sourceLast, int destinationChild) { + emit beginMoveRows(QModelIndex(), sourceFirst, sourceLast, QModelIndex(), destinationChild); + emit endMoveRows(); + } + + QStringList list; + +public slots: + void set(int idx, QString string) { + list[idx] = string; + emit dataChanged(index(idx,0), index(idx,0)); + } + +protected: + int rowCount(const QModelIndex & /* parent */ = QModelIndex()) const { + return list.count(); + } + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const { + if (role == Qt::DisplayRole) + return list.at(index.row()); + return QVariant(); + } +}; + + +class tst_qquickvisualdatamodel : public QObject +{ + Q_OBJECT +public: + tst_qquickvisualdatamodel(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void rootIndex(); + void updateLayout_data(); + void updateLayout(); + void childChanged_data(); + void childChanged(); + void objectListModel(); + void singleRole(); + void modelProperties(); + void noDelegate_data(); + void noDelegate(); + void itemsDestroyed_data(); + void itemsDestroyed(); + void qaimRowsMoved(); + void qaimRowsMoved_data(); + void remove_data(); + void remove(); + void move_data(); + void move(); + void groups_data(); + void groups(); + void invalidGroups(); + void get(); + void onChanged_data(); + void onChanged(); + void create(); + void incompleteModel(); + +private: + template void groups_verify( + const SingleRoleModel &model, + QQuickItem *contentItem, + const int (&mIndex)[N], + const int (&iIndex)[N], + const int (&vIndex)[N], + const int (&sIndex)[N], + const bool (&vMember)[N], + const bool (&sMember)[N]); + + template void get_verify( + const SingleRoleModel &model, + QQuickVisualDataModel *visualModel, + QQuickVisualDataGroup *visibleItems, + QQuickVisualDataGroup *selectedItems, + const int (&mIndex)[N], + const int (&iIndex)[N], + const int (&vIndex)[N], + const int (&sIndex)[N], + const bool (&vMember)[N], + const bool (&sMember)[N]); + + bool failed; + QDeclarativeEngine engine; + template + T *findItem(QQuickItem *parent, const QString &objectName, int index); +}; + +Q_DECLARE_METATYPE(QDeclarativeChangeSet) + +void tst_qquickvisualdatamodel::initTestCase() +{ + qRegisterMetaType(); +} + +void tst_qquickvisualdatamodel::cleanupTestCase() +{ + +} +class DataObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) + +public: + DataObject(QObject *parent=0) : QObject(parent) {} + DataObject(const QString &name, const QString &color, QObject *parent=0) + : QObject(parent), m_name(name), m_color(color) { } + + + QString name() const { return m_name; } + void setName(const QString &name) { + if (name != m_name) { + m_name = name; + emit nameChanged(); + } + } + + QString color() const { return m_color; } + void setColor(const QString &color) { + if (color != m_color) { + m_color = color; + emit colorChanged(); + } + } + +signals: + void nameChanged(); + void colorChanged(); + +private: + QString m_name; + QString m_color; +}; + +template static T evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + T result = expr.evaluate().value(); + if (expr.hasError()) + qWarning() << expr.error().toString(); + return result; +} + +template <> void evaluate(QObject *scope, const QString &expression) +{ + QDeclarativeExpression expr(qmlContext(scope), scope, expression); + expr.evaluate(); + if (expr.hasError()) + qWarning() << expr.error().toString(); +} + +tst_qquickvisualdatamodel::tst_qquickvisualdatamodel() +{ +} + +void tst_qquickvisualdatamodel::rootIndex() +{ + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml"))); + + QStandardItemModel model; + initStandardTreeModel(&model); + + engine.rootContext()->setContextProperty("myModel", &model); + + QQuickVisualDataModel *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QMetaObject::invokeMethod(obj, "setRoot"); + QVERIFY(qvariant_cast(obj->rootIndex()) == model.index(0,0)); + + QMetaObject::invokeMethod(obj, "setRootToParent"); + QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); + + QMetaObject::invokeMethod(obj, "setRoot"); + QVERIFY(qvariant_cast(obj->rootIndex()) == model.index(0,0)); + model.clear(); // will emit modelReset() + QVERIFY(qvariant_cast(obj->rootIndex()) == QModelIndex()); + + delete obj; +} + +void tst_qquickvisualdatamodel::updateLayout_data() +{ + QTest::addColumn("source"); + + QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); + QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); +} + +void tst_qquickvisualdatamodel::updateLayout() +{ + QFETCH(QUrl, source); + + QQuickView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + view.setSource(source); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); + name = findItem(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); + + model.invisibleRootItem()->sortChildren(0, Qt::DescendingOrder); + + name = findItem(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); + name = findItem(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); +} + +void tst_qquickvisualdatamodel::childChanged_data() +{ + QTest::addColumn("source"); + + QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); + QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); +} + +void tst_qquickvisualdatamodel::childChanged() +{ + QFETCH(QUrl, source); + + QQuickView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + view.setSource(source); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *vdm = listview->findChild("visualModel"); + vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0)))); + QCOMPARE(listview->count(), 1); + + QQuickText *name = findItem(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Child Item")); + + model.item(1,0)->child(0,0)->setText("Row 2 updated child"); + + name = findItem(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 updated child")); + + model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2"))); + QCOMPARE(listview->count(), 2); + + name = findItem(contentItem, "display", 1); + QVERIFY(name != 0); + QCOMPARE(name->text(), QString("Row 2 Child Item 2")); + + model.item(1,0)->takeRow(1); + name = findItem(contentItem, "display", 1); + QVERIFY(name == 0); + + vdm->setRootIndex(QVariant::fromValue(QModelIndex())); + QCOMPARE(listview->count(), 3); + name = findItem(contentItem, "display", 0); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 1 Item")); + name = findItem(contentItem, "display", 1); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 2 Item")); + name = findItem(contentItem, "display", 2); + QVERIFY(name); + QCOMPARE(name->text(), QString("Row 3 Item")); +} + +void tst_qquickvisualdatamodel::objectListModel() +{ + QQuickView view; + + QList dataList; + dataList.append(new DataObject("Item 1", "red")); + dataList.append(new DataObject("Item 2", "green")); + dataList.append(new DataObject("Item 3", "blue")); + dataList.append(new DataObject("Item 4", "yellow")); + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); + + view.setSource(QUrl::fromLocalFile(TESTDATA("objectlist.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "name", 0); + QCOMPARE(name->text(), QString("Item 1")); + + QQuickText *section = findItem(contentItem, "section", 0); + QCOMPARE(section->text(), QString("Item 1")); + + dataList[0]->setProperty("name", QLatin1String("Changed")); + QCOMPARE(name->text(), QString("Changed")); +} + +void tst_qquickvisualdatamodel::singleRole() +{ + { + QQuickView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole1.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "name", 1); + QCOMPARE(name->text(), QString("two")); + + model.set(1, "Changed"); + QCOMPARE(name->text(), QString("Changed")); + } + { + QQuickView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "name", 1); + QCOMPARE(name->text(), QString("two")); + + model.set(1, "Changed"); + QCOMPARE(name->text(), QString("Changed")); + } + { + QQuickView view; + + SingleRoleModel model("modelData"); + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("singlerole2.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickText *name = findItem(contentItem, "name", 1); + QCOMPARE(name->text(), QString("two")); + + model.set(1, "Changed"); + QCOMPARE(name->text(), QString("Changed")); + } +} + +void tst_qquickvisualdatamodel::modelProperties() +{ + { + QQuickView view; + + SingleRoleModel model; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickItem *delegate = findItem(contentItem, "delegate", 1); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(),QString("two")); + QCOMPARE(delegate->property("test2").toString(),QString("two")); + QCOMPARE(delegate->property("test3").toString(),QString("two")); + QCOMPARE(delegate->property("test4").toString(),QString("two")); + QVERIFY(!delegate->property("test9").isValid()); + QCOMPARE(delegate->property("test5").toString(),QString("")); + QVERIFY(delegate->property("test6").value() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + { + QQuickView view; + + QList dataList; + dataList.append(new DataObject("Item 1", "red")); + dataList.append(new DataObject("Item 2", "green")); + dataList.append(new DataObject("Item 3", "blue")); + dataList.append(new DataObject("Item 4", "yellow")); + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", QVariant::fromValue(dataList)); + + view.setSource(QUrl::fromLocalFile(TESTDATA("modelproperties.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickItem *delegate = findItem(contentItem, "delegate", 1); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(),QString("Item 2")); + QCOMPARE(delegate->property("test2").toString(),QString("Item 2")); + QVERIFY(qobject_cast(delegate->property("test3").value()) != 0); + QVERIFY(qobject_cast(delegate->property("test4").value()) != 0); + QCOMPARE(delegate->property("test5").toString(),QString("Item 2")); + QCOMPARE(delegate->property("test9").toString(),QString("Item 2")); + QVERIFY(delegate->property("test6").value() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + { + QQuickView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + QUrl source(QUrl::fromLocalFile(TESTDATA("modelproperties2.qml"))); + + //3 items, 3 i each + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":13: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":11: ReferenceError: Can't find variable: modelData"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); + QTest::ignoreMessage(QtWarningMsg, source.toString().toLatin1() + ":17: TypeError: Cannot read property 'display' of undefined"); + + view.setSource(source); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickItem *delegate = findItem(contentItem, "delegate", 1); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(),QString("Row 2 Item")); + QCOMPARE(delegate->property("test2").toString(),QString("Row 2 Item")); + QVERIFY(!delegate->property("test3").isValid()); + QVERIFY(!delegate->property("test4").isValid()); + QVERIFY(!delegate->property("test5").isValid()); + QVERIFY(!delegate->property("test9").isValid()); + QVERIFY(delegate->property("test6").value() != 0); + QCOMPARE(delegate->property("test7").toInt(),1); + QCOMPARE(delegate->property("test8").toInt(),1); + } + + //### should also test QStringList and QVariantList +} + +void tst_qquickvisualdatamodel::noDelegate_data() +{ + QTest::addColumn("source"); + + QTest::newRow("item delegate") << QUrl::fromLocalFile(TESTDATA("datalist.qml")); + QTest::newRow("package delegate") << QUrl::fromLocalFile(TESTDATA("datalist-package.qml")); +} + +void tst_qquickvisualdatamodel::noDelegate() +{ + QFETCH(QUrl, source); + + QQuickView view; + + QStandardItemModel model; + initStandardTreeModel(&model); + + view.rootContext()->setContextProperty("myModel", &model); + + view.setSource(source); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickVisualDataModel *vdm = listview->findChild("visualModel"); + QVERIFY(vdm != 0); + QCOMPARE(vdm->count(), 3); + + vdm->setDelegate(0); + QCOMPARE(vdm->count(), 0); +} + +void tst_qquickvisualdatamodel::itemsDestroyed_data() +{ + QTest::addColumn("source"); + + QTest::newRow("listView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_listView.qml")); + QTest::newRow("package") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_package.qml")); + QTest::newRow("pathView") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_pathView.qml")); + QTest::newRow("repeater") << QUrl::fromLocalFile(TESTDATA("itemsDestroyed_repeater.qml")); +} + +void tst_qquickvisualdatamodel::itemsDestroyed() +{ + QFETCH(QUrl, source); + + QDeclarativeGuard delegate; + + { + QQuickView view; + QStandardItemModel model; + initStandardTreeModel(&model); + view.rootContext()->setContextProperty("myModel", &model); + view.setSource(source); + + view.show(); + QTest::qWaitForWindowShown(&view); + + QVERIFY(delegate = findItem(view.rootItem(), "delegate", 1)); + } + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QVERIFY(!delegate); +} + +void tst_qquickvisualdatamodel::qaimRowsMoved() +{ + // Test parameters passed in QAIM::rowsMoved() signal are converted correctly + // when translated and emitted as the QListModelInterface::itemsMoved() signal + QFETCH(int, sourceFirst); + QFETCH(int, sourceLast); + QFETCH(int, destinationChild); + QFETCH(int, expectFrom); + QFETCH(int, expectTo); + QFETCH(int, expectCount); + + QDeclarativeEngine engine; + QDeclarativeComponent c(&engine, QUrl::fromLocalFile(TESTDATA("visualdatamodel.qml"))); + + SingleRoleModel model; + model.list.clear(); + for (int i=0; i<30; i++) + model.list << ("item " + i); + engine.rootContext()->setContextProperty("myModel", &model); + + QQuickVisualDataModel *obj = qobject_cast(c.create()); + QVERIFY(obj != 0); + + QSignalSpy spy(obj, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool))); + model.emitMove(sourceFirst, sourceLast, destinationChild); + // QAbstractItemModel also emits the changed signal when items are moved. + QCOMPARE(spy.count(), 2); + + bool move = false; + for (int i = 0; i < 2; ++i) { + QCOMPARE(spy[1].count(), 2); + QDeclarativeChangeSet changeSet = spy[i][0].value(); + if (!changeSet.changes().isEmpty()) + continue; + move = true; + QCOMPARE(changeSet.removes().count(), 1); + QCOMPARE(changeSet.removes().at(0).index, expectFrom); + QCOMPARE(changeSet.removes().at(0).count, expectCount); + QCOMPARE(changeSet.inserts().count(), 1); + QCOMPARE(changeSet.inserts().at(0).index, expectTo); + QCOMPARE(changeSet.inserts().at(0).count, expectCount); + QCOMPARE(changeSet.removes().at(0).moveId, changeSet.inserts().at(0).moveId); + QCOMPARE(spy[i][1].toBool(), false); + } + QVERIFY(move); + + delete obj; +} + +void tst_qquickvisualdatamodel::qaimRowsMoved_data() +{ + QTest::addColumn("sourceFirst"); + QTest::addColumn("sourceLast"); + QTest::addColumn("destinationChild"); + QTest::addColumn("expectFrom"); + QTest::addColumn("expectTo"); + QTest::addColumn("expectCount"); + + QTest::newRow("move 1 forward") + << 1 << 1 << 6 + << 1 << 5 << 1; + + QTest::newRow("move 1 backwards") + << 4 << 4 << 1 + << 4 << 1 << 1; + + QTest::newRow("move multiple forwards") + << 0 << 2 << 13 + << 0 << 10 << 3; + + QTest::newRow("move multiple forwards, with same to") + << 0 << 1 << 3 + << 0 << 1 << 2; + + QTest::newRow("move multiple backwards") + << 10 << 14 << 1 + << 10 << 1 << 5; +} + +void tst_qquickvisualdatamodel::remove_data() +{ + QTest::addColumn("source"); + QTest::addColumn("package delegate"); + + QTest::newRow("item delegate") + << QUrl::fromLocalFile(TESTDATA("groups.qml")) + << QString(); + QTest::newRow("package") + << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) + << QString("package."); +} + +void tst_qquickvisualdatamodel::remove() +{ + QQuickView view; + + SingleRoleModel model; + model.list = QStringList() + << "one" + << "two" + << "three" + << "four" + << "five" + << "six" + << "seven" + << "eight" + << "nine" + << "ten" + << "eleven" + << "twelve"; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); + QVERIFY(visualModel); + + { + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.remove(2)"); + QCOMPARE(listview->count(), 11); + QCOMPARE(visualModel->items()->count(), 11); + static const int mIndex[] = { 0, 1, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.remove(1, 4)"); + QCOMPARE(listview->count(), 7); + QCOMPARE(visualModel->items()->count(), 7); + static const int mIndex[] = { 0, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); + evaluate(visualModel, "items.remove(-8, 4)"); + QCOMPARE(listview->count(), 7); + QCOMPARE(visualModel->items()->count(), 7); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); + evaluate(visualModel, "items.remove(12, 2)"); + QCOMPARE(listview->count(), 7); + QCOMPARE(visualModel->items()->count(), 7); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: index out of range"); + evaluate(visualModel, "items.remove(5, 3)"); + QCOMPARE(listview->count(), 7); + QCOMPARE(visualModel->items()->count(), 7); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: remove: invalid count"); + evaluate(visualModel, "items.remove(5, -2)"); + QCOMPARE(listview->count(), 7); + QCOMPARE(visualModel->items()->count(), 7); + } +} + +void tst_qquickvisualdatamodel::move_data() +{ + QTest::addColumn("source"); + QTest::addColumn("package delegate"); + + QTest::newRow("item delegate") + << QUrl::fromLocalFile(TESTDATA("groups.qml")) + << QString(); + QTest::newRow("package") + << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) + << QString("package."); +} + +void tst_qquickvisualdatamodel::move() +{ + QQuickView view; + + SingleRoleModel model; + model.list = QStringList() + << "one" + << "two" + << "three" + << "four" + << "five" + << "six" + << "seven" + << "eight" + << "nine" + << "ten" + << "eleven" + << "twelve"; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); + QVERIFY(visualModel); + + { + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.move(2, 4)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 0, 1, 3, 4, 2, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.move(4, 2)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.move(8, 0, 4)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 8, 9,10,11, 0, 1, 2, 3, 4, 5, 6, 7 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + evaluate(visualModel, "items.move(3, 4, 5)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + static const int mIndex[] = { 8, 9,10,4, 11, 0, 1, 2, 3, 5, 6, 7 }; + static const int iIndex[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + + for (int i = 0; i < lengthOf(mIndex); ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(delegate->property("test1").toString(), model.list.at(mIndex[i])); + QCOMPARE(delegate->property("test2").toInt(), mIndex[i]); + QCOMPARE(delegate->property("test3").toInt(), iIndex[i]); + } + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: invalid count"); + evaluate(visualModel, "items.move(5, 2, -2)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); + evaluate(visualModel, "items.move(-6, 2, 1)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); + evaluate(visualModel, "items.move(15, 2, 1)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: from index out of range"); + evaluate(visualModel, "items.move(11, 1, 3)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); + evaluate(visualModel, "items.move(2, -5, 1)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); + evaluate(visualModel, "items.move(2, 14, 1)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: move: to index out of range"); + evaluate(visualModel, "items.move(2, 11, 4)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } +} + +void tst_qquickvisualdatamodel::groups_data() +{ + QTest::addColumn("source"); + QTest::addColumn("part"); + + QTest::newRow("item delegate") + << QUrl::fromLocalFile(TESTDATA("groups.qml")) + << QString(); + QTest::newRow("package") + << QUrl::fromLocalFile(TESTDATA("groups-package.qml")) + << QString("visualModel.parts.package."); +} + +template void tst_qquickvisualdatamodel::groups_verify( + const SingleRoleModel &model, + QQuickItem *contentItem, + const int (&mIndex)[N], + const int (&iIndex)[N], + const int (&vIndex)[N], + const int (&sIndex)[N], + const bool (&vMember)[N], + const bool (&sMember)[N]) +{ + failed = true; + for (int i = 0; i < N; ++i) { + QQuickItem *delegate = findItem(contentItem, "delegate", mIndex[i]); + QVERIFY(delegate); + QCOMPARE(evaluate(delegate, "test1"), model.list.at(mIndex[i])); + QCOMPARE(evaluate(delegate, "test2") , mIndex[i]); + QCOMPARE(evaluate(delegate, "test3") , iIndex[i]); + QCOMPARE(evaluate(delegate, "test4"), true); + QCOMPARE(evaluate(delegate, "test5") , vIndex[i]); + QCOMPARE(evaluate(delegate, "test6"), vMember[i]); + QCOMPARE(evaluate(delegate, "test7") , sIndex[i]); + QCOMPARE(evaluate(delegate, "test8"), sMember[i]); + QCOMPARE(evaluate(delegate, "test9").contains("items") , QBool(true)); + QCOMPARE(evaluate(delegate, "test9").contains("visible") , QBool(vMember[i])); + QCOMPARE(evaluate(delegate, "test9").contains("selected"), QBool(sMember[i])); + } + failed = false; +} + +#define VERIFY_GROUPS \ + groups_verify(model, contentItem, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \ + QVERIFY(!failed) + + +void tst_qquickvisualdatamodel::groups() +{ + QFETCH(QUrl, source); + QFETCH(QString, part); + + QQuickView view; + + SingleRoleModel model; + model.list = QStringList() + << "one" + << "two" + << "three" + << "four" + << "five" + << "six" + << "seven" + << "eight" + << "nine" + << "ten" + << "eleven" + << "twelve"; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(source); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *visualModel = listview->findChild("visualModel"); + QVERIFY(visualModel); + + QQuickVisualDataGroup *visibleItems = listview->findChild("visibleItems"); + QVERIFY(visibleItems); + + QQuickVisualDataGroup *selectedItems = listview->findChild("selectedItems"); + QVERIFY(selectedItems); + + const bool f = false; + const bool t = true; + + { + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 0); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f }; + VERIFY_GROUPS; + } { + evaluate(visualModel, "items.addGroups(8, \"selected\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 1); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f }; + VERIFY_GROUPS; + } { + evaluate(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 4); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 }; + static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f }; + VERIFY_GROUPS; + } { + evaluate(visualModel, "items.setGroups(2, [\"items\", \"selected\"])"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 11); + QCOMPARE(selectedItems->count(), 5); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 }; + static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 }; + static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f }; + VERIFY_GROUPS; + } { + evaluate(selectedItems, "setGroups(0, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; + static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; + VERIFY_GROUPS; + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: invalid count"); + evaluate(visualModel, "items.addGroups(11, -4, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); + evaluate(visualModel, "items.addGroups(-1, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); + evaluate(visualModel, "items.addGroups(14, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: addGroups: index out of range"); + evaluate(visualModel, "items.addGroups(11, 5, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: invalid count"); + evaluate(visualModel, "items.setGroups(11, -4, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); + evaluate(visualModel, "items.setGroups(-1, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); + evaluate(visualModel, "items.setGroups(14, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: setGroups: index out of range"); + evaluate(visualModel, "items.setGroups(11, 5, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: invalid count"); + evaluate(visualModel, "items.removeGroups(11, -4, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); + evaluate(visualModel, "items.removeGroups(-1, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); + evaluate(visualModel, "items.removeGroups(14, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: removeGroups: index out of range"); + evaluate(visualModel, "items.removeGroups(11, 5, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + } { + evaluate(visualModel, part + "filterOnGroup = \"visible\""); + QCOMPARE(listview->count(), 9); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("visible")); + } { + evaluate(visualModel, part + "filterOnGroup = \"selected\""); + QCOMPARE(listview->count(), 2); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("selected")); + } { + evaluate(visualModel, part + "filterOnGroup = undefined"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + QCOMPARE(evaluate(visualModel, part + "filterOnGroup"), QString("items")); + } { + QQuickItem *delegate = findItem(contentItem, "delegate", 5); + QVERIFY(delegate); + + evaluate(delegate, "hide()"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 8); + QCOMPARE(selectedItems->count(), 2); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; + static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; + VERIFY_GROUPS; + } { + QQuickItem *delegate = findItem(contentItem, "delegate", 5); + QVERIFY(delegate); + + evaluate(delegate, "select()"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 8); + QCOMPARE(selectedItems->count(), 3); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; + static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 }; + static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f }; + VERIFY_GROUPS; + } { + evaluate(visualModel, "items.move(2, 6, 3)"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 8); + QCOMPARE(selectedItems->count(), 3); + static const int mIndex [] = { 0, 1, 5, 6, 7, 8, 2, 3, 4, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 2, 2, 3, 3, 4, 5, 6, 7 }; + static const bool vMember[] = { t, t, f, f, f, t, f, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3 }; + static const bool sMember[] = { f, f, t, f, f, t, f, f, f, t, f, f }; + VERIFY_GROUPS; + } +} + +template void tst_qquickvisualdatamodel::get_verify( + const SingleRoleModel &model, + QQuickVisualDataModel *visualModel, + QQuickVisualDataGroup *visibleItems, + QQuickVisualDataGroup *selectedItems, + const int (&mIndex)[N], + const int (&iIndex)[N], + const int (&vIndex)[N], + const int (&sIndex)[N], + const bool (&vMember)[N], + const bool (&sMember)[N]) +{ + failed = true; + for (int i = 0; i < N; ++i) { + QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.name").arg(i)), model.list.at(mIndex[i])); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.modelData").arg(i)), model.list.at(mIndex[i])); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).model.index").arg(i)), mIndex[i]); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).itemsIndex").arg(i)), iIndex[i]); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).inItems").arg(i)), true); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).visibleIndex").arg(i)), vIndex[i]); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).inVisible").arg(i)), vMember[i]); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).selectedIndex").arg(i)), sIndex[i]); + QCOMPARE(evaluate(visualModel, QString("items.get(%1).inSelected").arg(i)), sMember[i]); + QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"items\")").arg(i)), true); + QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"visible\")").arg(i)), vMember[i]); + QCOMPARE(evaluate(visualModel, QString("contains(items.get(%1).groups, \"selected\")").arg(i)), sMember[i]); + + if (vMember[i]) { + QCOMPARE(evaluate(visibleItems, QString("get(%1).model.name").arg(vIndex[i])), model.list.at(mIndex[i])); + QCOMPARE(evaluate(visibleItems, QString("get(%1).model.modelData").arg(vIndex[i])), model.list.at(mIndex[i])); + QCOMPARE(evaluate(visibleItems, QString("get(%1).model.index").arg(vIndex[i])), mIndex[i]); + QCOMPARE(evaluate(visibleItems, QString("get(%1).itemsIndex").arg(vIndex[i])), iIndex[i]); + QCOMPARE(evaluate(visibleItems, QString("get(%1).inItems").arg(vIndex[i])), true); + QCOMPARE(evaluate(visibleItems, QString("get(%1).visibleIndex").arg(vIndex[i])), vIndex[i]); + QCOMPARE(evaluate(visibleItems, QString("get(%1).inVisible").arg(vIndex[i])), vMember[i]); + QCOMPARE(evaluate(visibleItems, QString("get(%1).selectedIndex").arg(vIndex[i])), sIndex[i]); + QCOMPARE(evaluate(visibleItems, QString("get(%1).inSelected").arg(vIndex[i])), sMember[i]); + + QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"items\")").arg(vIndex[i])), true); + QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"visible\")").arg(vIndex[i])), vMember[i]); + QCOMPARE(evaluate(visibleItems, QString("contains(get(%1).groups, \"selected\")").arg(vIndex[i])), sMember[i]); + } + if (sMember[i]) { + QCOMPARE(evaluate(selectedItems, QString("get(%1).model.name").arg(sIndex[i])), model.list.at(mIndex[i])); + QCOMPARE(evaluate(selectedItems, QString("get(%1).model.modelData").arg(sIndex[i])), model.list.at(mIndex[i])); + QCOMPARE(evaluate(selectedItems, QString("get(%1).model.index").arg(sIndex[i])), mIndex[i]); + QCOMPARE(evaluate(selectedItems, QString("get(%1).itemsIndex").arg(sIndex[i])), iIndex[i]); + QCOMPARE(evaluate(selectedItems, QString("get(%1).inItems").arg(sIndex[i])), true); + QCOMPARE(evaluate(selectedItems, QString("get(%1).visibleIndex").arg(sIndex[i])), vIndex[i]); + QCOMPARE(evaluate(selectedItems, QString("get(%1).inVisible").arg(sIndex[i])), vMember[i]); + QCOMPARE(evaluate(selectedItems, QString("get(%1).selectedIndex").arg(sIndex[i])), sIndex[i]); + QCOMPARE(evaluate(selectedItems, QString("get(%1).inSelected").arg(sIndex[i])), sMember[i]); + QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"items\")").arg(sIndex[i])), true); + QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"visible\")").arg(sIndex[i])), vMember[i]); + QCOMPARE(evaluate(selectedItems, QString("contains(get(%1).groups, \"selected\")").arg(sIndex[i])), sMember[i]); + } + } + failed = false; +} + +#define VERIFY_GET \ + get_verify(model, visualModel, visibleItems, selectedItems, mIndex, iIndex, vIndex, sIndex, vMember, sMember); \ + QVERIFY(!failed) + +void tst_qquickvisualdatamodel::get() +{ + QQuickView view; + + SingleRoleModel model; + model.list = QStringList() + << "one" + << "two" + << "three" + << "four" + << "five" + << "six" + << "seven" + << "eight" + << "nine" + << "ten" + << "eleven" + << "twelve"; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("groups.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); + QVERIFY(visualModel); + + QQuickVisualDataGroup *visibleItems = visualModel->findChild("visibleItems"); + QVERIFY(visibleItems); + + QQuickVisualDataGroup *selectedItems = visualModel->findChild("selectedItems"); + QVERIFY(selectedItems); + + QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(ctxt->engine()); + QVERIFY(v8Engine); + + const bool f = false; + const bool t = true; + + { + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 0); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, f, f, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.addGroups(8, \"selected\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 1); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, f, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.addGroups(6, 4, [\"visible\", \"selected\"])"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 12); + QCOMPARE(selectedItems->count(), 4); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const bool vMember[] = { t, t, t, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 4 }; + static const bool sMember[] = { f, f, f, f, f, f, t, t, t, t, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.setGroups(2, [\"items\", \"selected\"])"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 11); + QCOMPARE(selectedItems->count(), 5); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10 }; + static const bool vMember[] = { t, t, f, t, t, t, t, t, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 1, 1, 1, 1, 2, 3, 4, 5, 5 }; + static const bool sMember[] = { f, f, t, f, f, f, t, t, t, t, f, f }; + VERIFY_GET; + } { + evaluate(selectedItems, "setGroups(0, 3, \"items\")"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; + static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.get(5).inVisible = false"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 8); + QCOMPARE(selectedItems->count(), 2); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; + static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.get(5).inSelected = true"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 8); + QCOMPARE(selectedItems->count(), 3); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 4, 4, 4, 5, 6, 7 }; + static const bool vMember[] = { t, t, f, t, t, f, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3 }; + static const bool sMember[] = { f, f, f, f, f, t, f, f, t, t, f, f }; + VERIFY_GET; + } { + evaluate(visualModel, "items.get(5).groups = [\"visible\", \"items\"]"); + QCOMPARE(listview->count(), 12); + QCOMPARE(visualModel->items()->count(), 12); + QCOMPARE(visibleItems->count(), 9); + QCOMPARE(selectedItems->count(), 2); + static const int mIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int iIndex [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 }; + static const int vIndex [] = { 0, 1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 8 }; + static const bool vMember[] = { t, t, f, t, t, t, f, f, t, t, t, t }; + static const int sIndex [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2 }; + static const bool sMember[] = { f, f, f, f, f, f, f, f, t, t, f, f }; + VERIFY_GET; + } +} + +void tst_qquickvisualdatamodel::invalidGroups() +{ + QUrl source = QUrl::fromLocalFile(TESTDATA("groups-invalid.qml")); + QTest::ignoreMessage(QtWarningMsg, (source.toString() + ":12:9: QML VisualDataGroup: " + QQuickVisualDataGroup::tr("Group names must start with a lower case letter")).toUtf8()); + + QDeclarativeComponent component(&engine, source); + QScopedPointer object(component.create()); + QVERIFY(object); + + QCOMPARE(evaluate(object.data(), "groups.length"), 4); + QCOMPARE(evaluate(object.data(), "groups[0].name"), QString("items")); + QCOMPARE(evaluate(object.data(), "groups[1].name"), QString("persistedItems")); + QCOMPARE(evaluate(object.data(), "groups[2].name"), QString("visible")); + QCOMPARE(evaluate(object.data(), "groups[3].name"), QString("selected")); +} + +void tst_qquickvisualdatamodel::onChanged_data() +{ + QTest::addColumn("expression"); + QTest::addColumn("tests"); + + QTest::newRow("item appended") + << QString("listModel.append({\"number\": \"five\"})") + << (QStringList() + << "verify(vm.removed, [], [], [])" + << "verify(vm.inserted, [4], [1], [undefined])" + << "verify(vi.removed, [], [], [])" + << "verify(vi.inserted, [4], [1], [undefined])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + QTest::newRow("item prepended") + << QString("listModel.insert(0, {\"number\": \"five\"})") + << (QStringList() + << "verify(vm.removed, [], [], [])" + << "verify(vm.inserted, [0], [1], [undefined])" + << "verify(vi.removed, [], [], [])" + << "verify(vi.inserted, [0], [1], [undefined])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + QTest::newRow("item inserted") + << QString("listModel.insert(2, {\"number\": \"five\"})") + << (QStringList() + << "verify(vm.removed, [], [], [])" + << "verify(vm.inserted, [2], [1], [undefined])" + << "verify(vi.removed, [], [], [])" + << "verify(vi.inserted, [2], [1], [undefined])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + + QTest::newRow("item removed tail") + << QString("listModel.remove(3)") + << (QStringList() + << "verify(vm.removed, [3], [1], [undefined])" + << "verify(vm.inserted, [], [], [])" + << "verify(vi.removed, [3], [1], [undefined])" + << "verify(vi.inserted, [], [], [])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + QTest::newRow("item removed head") + << QString("listModel.remove(0)") + << (QStringList() + << "verify(vm.removed, [0], [1], [undefined])" + << "verify(vm.inserted, [], [], [])" + << "verify(vi.removed, [0], [1], [undefined])" + << "verify(vi.inserted, [], [], [])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + QTest::newRow("item removed middle") + << QString("listModel.remove(1)") + << (QStringList() + << "verify(vm.removed, [1], [1], [undefined])" + << "verify(vm.inserted, [], [], [])" + << "verify(vi.removed, [1], [1], [undefined])" + << "verify(vi.inserted, [], [], [])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + + + QTest::newRow("item moved from tail") + << QString("listModel.move(3, 0, 1)") + << (QStringList() + << "verify(vm.removed, [3], [1], [vm.inserted[0].moveId])" + << "verify(vm.inserted, [0], [1], [vm.removed[0].moveId])" + << "verify(vi.removed, [3], [1], [vi.inserted[0].moveId])" + << "verify(vi.inserted, [0], [1], [vi.removed[0].moveId])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + QTest::newRow("item moved from head") + << QString("listModel.move(0, 2, 2)") + << (QStringList() + << "verify(vm.removed, [0], [2], [vm.inserted[0].moveId])" + << "verify(vm.inserted, [2], [2], [vm.removed[0].moveId])" + << "verify(vi.removed, [0], [2], [vi.inserted[0].moveId])" + << "verify(vi.inserted, [2], [2], [vi.removed[0].moveId])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); + + QTest::newRow("groups changed") + << QString("items.setGroups(1, 2, [\"items\", \"selected\"])") + << (QStringList() + << "verify(vm.inserted, [], [], [])" + << "verify(vm.removed, [], [], [])" + << "verify(vi.removed, [1], [2], [undefined])" + << "verify(vi.inserted, [], [], [])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [0], [2], [undefined])"); + + QTest::newRow("multiple removes") + << QString("{ vi.remove(1, 1); " + "vi.removeGroups(0, 2, \"items\") }") + << (QStringList() + << "verify(vm.removed, [0, 1], [1, 1], [undefined, undefined])" + << "verify(vm.inserted, [], [], [])" + << "verify(vi.removed, [1], [1], [undefined])" + << "verify(vi.inserted, [], [], [])" + << "verify(si.removed, [], [], [])" + << "verify(si.inserted, [], [], [])"); +} + +void tst_qquickvisualdatamodel::onChanged() +{ + QFETCH(QString, expression); + QFETCH(QStringList, tests); + + QDeclarativeComponent component(&engine, QUrl::fromLocalFile(TESTDATA("onChanged.qml"))); + QScopedPointer object(component.create()); + QVERIFY(object); + + evaluate(object.data(), expression); + + foreach (const QString &test, tests) { + bool passed = evaluate(object.data(), test); + if (!passed) + qWarning() << test; + QVERIFY(passed); + } +} + +void tst_qquickvisualdatamodel::create() +{ + QQuickView view; + + SingleRoleModel model; + model.list = QStringList() + << "one" + << "two" + << "three" + << "four" + << "five" + << "six" + << "seven" + << "eight" + << "nine" + << "ten" + << "eleven" + << "twelve" + << "thirteen" + << "fourteen" + << "fifteen" + << "sixteen" + << "seventeen" + << "eighteen" + << "nineteen" + << "twenty"; + + QDeclarativeContext *ctxt = view.rootContext(); + ctxt->setContextProperty("myModel", &model); + + view.setSource(QUrl::fromLocalFile(TESTDATA("create.qml"))); + + QQuickListView *listview = qobject_cast(view.rootObject()); + QVERIFY(listview != 0); + + QQuickItem *contentItem = listview->contentItem(); + QVERIFY(contentItem != 0); + + QQuickVisualDataModel *visualModel = qobject_cast(qvariant_cast(listview->model())); + QVERIFY(visualModel); + + QCOMPARE(listview->count(), 20); + + QQuickItem *delegate; + + // persistedItems.includeByDefault is true, so all items belong to persistedItems initially. + QVERIFY(delegate = findItem(contentItem, "delegate", 1)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + + // changing include by default doesn't remove persistance. + evaluate(visualModel, "persistedItems.includeByDefault = false"); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + + // removing from persistedItems does. + evaluate(visualModel, "persistedItems.remove(0, 20)"); + QCOMPARE(listview->count(), 20); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); + + // Request an item instantiated by the view. + QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(1)"))); + QCOMPARE(delegate, findItem(contentItem, "delegate", 1)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); + + evaluate(delegate, "VisualDataModel.inPersistedItems = false"); + QCOMPARE(listview->count(), 20); + QCOMPARE(evaluate(delegate, "destroyed"), false); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); + + // Request an item not instantiated by the view. + QVERIFY(!findItem(contentItem, "delegate", 15)); + QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(15)"))); + QCOMPARE(delegate, findItem(contentItem, "delegate", 15)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); + + evaluate(visualModel, "persistedItems.remove(0)"); + QCOMPARE(evaluate(delegate, "destroyed"), true); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); + + // Request an item not instantiated by the view, then scroll the view so it will request it. + QVERIFY(!findItem(contentItem, "delegate", 16)); + QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(16)"))); + QCOMPARE(delegate, findItem(contentItem, "delegate", 16)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); + + evaluate(listview, "positionViewAtIndex(19, ListView.End)"); + QCOMPARE(listview->count(), 20); + evaluate(delegate, "VisualDataModel.groups = [\"items\"]"); + QCOMPARE(evaluate(delegate, "destroyed"), false); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); + + // Request and release an item instantiated by the view, then scroll the view so it releases it. + QVERIFY(findItem(contentItem, "delegate", 17)); + QVERIFY(delegate = qobject_cast(evaluate(visualModel, "items.create(17)"))); + QCOMPARE(delegate, findItem(contentItem, "delegate", 17)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); + + evaluate(visualModel, "items.removeGroups(17, \"persistedItems\")"); + QCOMPARE(evaluate(delegate, "destroyed"), false); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), false); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 0); + evaluate(listview, "positionViewAtIndex(1, ListView.Beginning)"); + QCOMPARE(listview->count(), 20); + QCOMPARE(evaluate(delegate, "destroyed"), true); + + // Adding an item to the persistedItems group won't instantiate it, but if later requested by + // the view it will be persisted. + evaluate(visualModel, "items.addGroups(18, \"persistedItems\")"); + QCOMPARE(evaluate(visualModel, "persistedItems.count"), 1); + QVERIFY(!findItem(contentItem, "delegate", 18)); + evaluate(listview, "positionViewAtIndex(19, ListView.End)"); + QCOMPARE(listview->count(), 20); + QVERIFY(delegate = findItem(contentItem, "delegate", 18)); + QCOMPARE(evaluate(delegate, "VisualDataModel.inPersistedItems"), true); + QCOMPARE(evaluate(delegate, "destroyed"), false); + evaluate(listview, "positionViewAtIndex(1, ListView.Beginning)"); + QCOMPARE(listview->count(), 20); + QCOMPARE(evaluate(delegate, "destroyed"), false); +} + + +void tst_qquickvisualdatamodel::incompleteModel() +{ + // VisualDataModel is first populated in componentComplete. Verify various functions are + // harmlessly ignored until then. + + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 2.0\n VisualDataModel {}", QUrl::fromLocalFile(TESTDATA(""))); + + QScopedPointer object(component.beginCreate(engine.rootContext())); + + QQuickVisualDataModel *model = qobject_cast(object.data()); + QVERIFY(model); + + QSignalSpy itemsSpy(model->items(), SIGNAL(countChanged())); + QSignalSpy persistedItemsSpy(model->items(), SIGNAL(countChanged())); + + evaluate(model, "items.removeGroups(0, items.count, \"items\")"); + QCOMPARE(itemsSpy.count(), 0); + QCOMPARE(persistedItemsSpy.count(), 0); + + evaluate(model, "items.setGroups(0, items.count, \"persistedItems\")"); + QCOMPARE(itemsSpy.count(), 0); + QCOMPARE(persistedItemsSpy.count(), 0); + + evaluate(model, "items.addGroups(0, items.count, \"persistedItems\")"); + QCOMPARE(itemsSpy.count(), 0); + QCOMPARE(persistedItemsSpy.count(), 0); + + evaluate(model, "items.remove(0, items.count)"); + QCOMPARE(itemsSpy.count(), 0); + QCOMPARE(persistedItemsSpy.count(), 0); + + evaluate(model, "items.insert([ \"color\": \"blue\" ])"); + QCOMPARE(itemsSpy.count(), 0); + QCOMPARE(persistedItemsSpy.count(), 0); + + QTest::ignoreMessage(QtWarningMsg, ": QML VisualDataGroup: get: index out of range"); + QVERIFY(evaluate(model, "items.get(0) === undefined")); + + component.completeCreate(); +} + +template +T *tst_qquickvisualdatamodel::findItem(QQuickItem *parent, const QString &objectName, int index) +{ + const QMetaObject &mo = T::staticMetaObject; + //qDebug() << parent->childItems().count() << "children"; + for (int i = 0; i < parent->childItems().count(); ++i) { + QQuickItem *item = qobject_cast(parent->childItems().at(i)); + if (!item) + continue; + //qDebug() << "try" << item; + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + if (index != -1) { + QDeclarativeExpression e(qmlContext(item), item, "index"); + if (e.evaluate().toInt() == index) + return static_cast(item); + } else { + return static_cast(item); + } + } + item = findItem(item, objectName, index); + if (item) + return static_cast(item); + } + + return 0; +} + +QTEST_MAIN(tst_qquickvisualdatamodel) + +#include "tst_qquickvisualdatamodel.moc" diff --git a/tests/auto/qtquick2/qtquick2.pro b/tests/auto/qtquick2/qtquick2.pro new file mode 100644 index 0000000000..af468a6393 --- /dev/null +++ b/tests/auto/qtquick2/qtquick2.pro @@ -0,0 +1,63 @@ +TEMPLATE = subdirs + +PUBLICTESTS += \ + examples \ + geometry \ + nodes \ + qdeclarativepixmapcache + +PRIVATETESTS += \ + qdeclarativeanimations \ + qdeclarativeapplication \ + qdeclarativebehaviors \ + qdeclarativefontloader \ + qdeclarativepath \ + qdeclarativesmoothedanimation \ + qdeclarativespringanimation \ + qdeclarativestyledtext \ + qdeclarativestates \ + qdeclarativesystempalette \ + qdeclarativetimer \ + qdeclarativexmllistmodel + +# This test requires the xmlpatterns module +!contains(QT_CONFIG,xmlpatterns):PRIVATETESTS -= qdeclarativexmllistmodel + +QUICKTESTS = \ + qquickanchors \ + qquickanimatedimage \ + qquickborderimage \ + qquickcanvas \ + qquickdrag \ + qquickdroparea \ + qquickflickable \ + qquickflipable \ + qquickfocusscope \ + qquickgridview \ + qquickimage \ + qquickitem \ + qquickitem2 \ + qquicklistview \ + qquickloader \ + qquickmousearea \ + qquickmultipointtoucharea \ + qquickpathview \ + qquickpincharea \ + qquickpositioners \ + qquickrepeater \ + qquickshadereffect \ + qquickspriteimage \ + qquicktext \ + qquicktextedit \ + qquicktextinput \ + qquickvisualdatamodel \ + qquickview \ + qquickcanvasitem \ + + +SUBDIRS += $$PUBLICTESTS + +contains(QT_CONFIG, private_tests) { + SUBDIRS += $$PRIVATETESTS + SUBDIRS += $$QUICKTESTS +} diff --git a/tests/auto/shared/testhttpserver.cpp b/tests/auto/shared/testhttpserver.cpp new file mode 100644 index 0000000000..206094924c --- /dev/null +++ b/tests/auto/shared/testhttpserver.cpp @@ -0,0 +1,324 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "testhttpserver.h" +#include +#include +#include +#include + +/*! +\internal +\class TestHTTPServer +\brief provides a very, very basic HTTP server for testing. + +Inside the test case, an instance of TestHTTPServer should be created, with the +appropriate port to listen on. The server will listen on the localhost interface. + +Directories to serve can then be added to server, which will be added as "roots". +Each root can be added as a Normal, Delay or Disconnect root. Requests for files +within a Normal root are returned immediately. Request for files within a Delay +root are delayed for 500ms, and then served. Requests for files within a Disconnect +directory cause the server to disconnect immediately. A request for a file that isn't +found in any root will return a 404 error. + +If you have the following directory structure: + +\code +disconnect/disconnectTest.qml +files/main.qml +files/Button.qml +files/content/WebView.qml +slowFiles/slowMain.qml +\endcode +it can be added like this: +\code +TestHTTPServer server(14445); +server.serveDirectory("disconnect", TestHTTPServer::Disconnect); +server.serveDirectory("files"); +server.serveDirectory("slowFiles", TestHTTPServer::Delay); +\endcode + +The following request urls will then result in the appropriate action: +\table +\header \o URL \o Action +\row \o http://localhost:14445/disconnectTest.qml \o Disconnection +\row \o http://localhost:14445/main.qml \o main.qml returned immediately +\row \o http://localhost:14445/Button.qml \o Button.qml returned immediately +\row \o http://localhost:14445/content/WebView.qml \o content/WebView.qml returned immediately +\row \o http://localhost:14445/slowMain.qml \o slowMain.qml returned after 500ms +\endtable +*/ +TestHTTPServer::TestHTTPServer(quint16 port) +: m_hasFailed(false) +{ + QObject::connect(&server, SIGNAL(newConnection()), this, SLOT(newConnection())); + + server.listen(QHostAddress::LocalHost, port); +} + +bool TestHTTPServer::isValid() const +{ + return server.isListening(); +} + +bool TestHTTPServer::serveDirectory(const QString &dir, Mode mode) +{ + dirs.append(qMakePair(dir, mode)); + return true; +} + +/* + Add an alias, so that if filename is requested and does not exist, + alias may be returned. +*/ +void TestHTTPServer::addAlias(const QString &filename, const QString &alias) +{ + aliases.insert(filename, alias); +} + +void TestHTTPServer::addRedirect(const QString &filename, const QString &redirectName) +{ + redirects.insert(filename, redirectName); +} + +bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &body) +{ + m_hasFailed = false; + + QFile expectFile(expect.toLocalFile()); + if (!expectFile.open(QIODevice::ReadOnly)) return false; + + QFile replyFile(reply.toLocalFile()); + if (!replyFile.open(QIODevice::ReadOnly)) return false; + + bodyData = QByteArray(); + if (body.isValid()) { + QFile bodyFile(body.toLocalFile()); + if (!bodyFile.open(QIODevice::ReadOnly)) return false; + bodyData = bodyFile.readAll(); + } + + waitData = expectFile.readAll(); + /* + while (waitData.endsWith('\n')) + waitData = waitData.left(waitData.count() - 1); + */ + + replyData = replyFile.readAll(); + + if (!replyData.endsWith('\n')) + replyData.append("\n"); + replyData.append("Content-length: " + QByteArray::number(bodyData.length())); + replyData .append("\n\n"); + + for (int ii = 0; ii < replyData.count(); ++ii) { + if (replyData.at(ii) == '\n' && (!ii || replyData.at(ii - 1) != '\r')) { + replyData.insert(ii, '\r'); + ++ii; + } + } + replyData.append(bodyData); + + return true; +} + +bool TestHTTPServer::hasFailed() const +{ + return m_hasFailed; +} + +void TestHTTPServer::newConnection() +{ + QTcpSocket *socket = server.nextPendingConnection(); + if (!socket) return; + + if (!dirs.isEmpty()) + dataCache.insert(socket, QByteArray()); + + QObject::connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); + QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead())); +} + +void TestHTTPServer::disconnected() +{ + QTcpSocket *socket = qobject_cast(sender()); + if (!socket) return; + + dataCache.remove(socket); + for (int ii = 0; ii < toSend.count(); ++ii) { + if (toSend.at(ii).first == socket) { + toSend.removeAt(ii); + --ii; + } + } + socket->disconnect(); + socket->deleteLater(); +} + +void TestHTTPServer::readyRead() +{ + QTcpSocket *socket = qobject_cast(sender()); + if (!socket || socket->state() == QTcpSocket::ClosingState) return; + + QByteArray ba = socket->readAll(); + + if (!dirs.isEmpty()) { + serveGET(socket, ba); + return; + } + + if (m_hasFailed || waitData.isEmpty()) { + qWarning() << "TestHTTPServer: Unexpected data" << ba; + return; + } + + for (int ii = 0; ii < ba.count(); ++ii) { + const char c = ba.at(ii); + if (c == '\r' && waitData.isEmpty()) + continue; + else if (!waitData.isEmpty() && c == waitData.at(0)) + waitData = waitData.mid(1); + else if (c == '\r') + continue; + else { + QByteArray data = ba.mid(ii); + qWarning() << "TestHTTPServer: Unexpected data" << data << "\nExpected: " << waitData; + m_hasFailed = true; + socket->disconnectFromHost(); + return; + } + } + + if (waitData.isEmpty()) { + socket->write(replyData); + socket->disconnectFromHost(); + } +} + +bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName) +{ + if (redirects.contains(fileName)) { + QByteArray response = "HTTP/1.1 302 Found\r\nContent-length: 0\r\nContent-type: text/html; charset=UTF-8\r\nLocation: " + redirects[fileName].toUtf8() + "\r\n\r\n"; + socket->write(response); + return true; + } + + for (int ii = 0; ii < dirs.count(); ++ii) { + QString dir = dirs.at(ii).first; + Mode mode = dirs.at(ii).second; + + QString dirFile = dir + QLatin1String("/") + QLatin1String(fileName); + + if (!QFile::exists(dirFile)) { + if (aliases.contains(fileName)) + dirFile = dir + QLatin1String("/") + aliases.value(fileName); + } + + QFile file(dirFile); + if (file.open(QIODevice::ReadOnly)) { + + if (mode == Disconnect) + return true; + + QByteArray data = file.readAll(); + + QByteArray response = "HTTP/1.0 200 OK\r\nContent-type: text/html; charset=UTF-8\r\nContent-length: "; + response += QByteArray::number(data.count()); + response += "\r\n\r\n"; + response += data; + + if (mode == Delay) { + toSend.append(qMakePair(socket, response)); + QTimer::singleShot(500, this, SLOT(sendOne())); + return false; + } else { + socket->write(response); + return true; + } + } + } + + + QByteArray response = "HTTP/1.0 404 Not found\r\nContent-type: text/html; charset=UTF-8\r\n\r\n"; + socket->write(response); + + return true; +} + +void TestHTTPServer::sendOne() +{ + if (!toSend.isEmpty()) { + toSend.first().first->write(toSend.first().second); + toSend.first().first->close(); + toSend.removeFirst(); + } +} + +void TestHTTPServer::serveGET(QTcpSocket *socket, const QByteArray &data) +{ + if (!dataCache.contains(socket)) + return; + + QByteArray total = dataCache[socket] + data; + dataCache[socket] = total; + + if (total.contains("\n\r\n")) { + + bool close = true; + + if (total.startsWith("GET /")) { + + int space = total.indexOf(' ', 4); + if (space != -1) { + + QByteArray req = total.mid(5, space - 5); + close = reply(socket, req); + + } + } + dataCache.remove(socket); + + if (close) + socket->disconnectFromHost(); + } +} + diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h new file mode 100644 index 0000000000..3e8f70fea4 --- /dev/null +++ b/tests/auto/shared/testhttpserver.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTHTTPSERVER_H +#define TESTHTTPSERVER_H + +#include +#include +#include +#include + +class TestHTTPServer : public QObject +{ + Q_OBJECT +public: + TestHTTPServer(quint16 port); + + bool isValid() const; + + enum Mode { Normal, Delay, Disconnect }; + bool serveDirectory(const QString &, Mode = Normal); + + bool wait(const QUrl &expect, const QUrl &reply, const QUrl &body); + bool hasFailed() const; + + void addAlias(const QString &filename, const QString &aliasName); + void addRedirect(const QString &filename, const QString &redirectName); + +private slots: + void newConnection(); + void disconnected(); + void readyRead(); + void sendOne(); + +private: + void serveGET(QTcpSocket *, const QByteArray &); + bool reply(QTcpSocket *, const QByteArray &); + + QList > dirs; + QHash dataCache; + QList > toSend; + + QByteArray waitData; + QByteArray replyData; + QByteArray bodyData; + bool m_hasFailed; + + QHash aliases; + QHash redirects; + + QTcpServer server; +}; + +#endif // TESTHTTPSERVER_H + diff --git a/tests/auto/shared/util.h b/tests/auto/shared/util.h new file mode 100644 index 0000000000..eac2c4ec12 --- /dev/null +++ b/tests/auto/shared/util.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDECLARATIVETESTUTILS_H +#define QDECLARATIVETESTUTILS_H + +#include +#include + +namespace QDeclarativeTestUtils +{ + /* + Returns the path to some testdata file. + + We first check relative to the binary, and then look in the source tree. + + Note we are looking for a _directory_ which exists, but the _file_ itself need not exist, + to support the case of finding a path to a testdata file which doesn't exist yet (i.e. + a file we are about to create). + */ + QString testdata(QString const& name, const char *sourceFile) + { + // Try to find it relative to the binary. + QFileInfo relative = QDir(QCoreApplication::applicationDirPath()).filePath(QLatin1String("data/") + name); + if (relative.dir().exists()) { + return relative.absoluteFilePath(); + } + + // Else try to find it in the source tree + QFileInfo from_source = QFileInfo(sourceFile).absoluteDir().filePath(QLatin1String("data/") + name); + if (from_source.dir().exists()) { + return from_source.absoluteFilePath(); + } + + qWarning("requested testdata %s could not be found (looked at: %s, %s)", + qPrintable(name), + qPrintable(relative.filePath()), + qPrintable(from_source.filePath()) + ); + + return QString(); + } +} + +#define TESTDATA(name) QDeclarativeTestUtils::testdata(name, __FILE__) + +#endif // QDECLARATIVETESTUTILS_H diff --git a/tests/benchmarks/particles/affectors/affectors.pro b/tests/benchmarks/particles/affectors/affectors.pro index 4d1926da22..17b23255ac 100644 --- a/tests/benchmarks/particles/affectors/affectors.pro +++ b/tests/benchmarks/particles/affectors/affectors.pro @@ -7,4 +7,4 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib diff --git a/tests/benchmarks/particles/emission/emission.pro b/tests/benchmarks/particles/emission/emission.pro index 6e5e8ec019..343bdf0430 100644 --- a/tests/benchmarks/particles/emission/emission.pro +++ b/tests/benchmarks/particles/emission/emission.pro @@ -7,4 +7,4 @@ testDataFiles.files = data testDataFiles.path = . DEPLOYMENT += testDataFiles -QT += core-private gui-private v8-private declarative-private opengl-private testlib +QT += core-private gui-private v8-private declarative-private quick-private opengl-private testlib -- cgit v1.2.3