aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 18:46:38 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 19:02:37 +0200
commitc2f8b9535d34da6948ccf45b7d5fd90de2f1bc9e (patch)
treec6f7e058a985d7c18b51cadc76283caf555071c9 /tests
parent9e633bbda7608ac0231809e2a6a97ae8f2d849d6 (diff)
parent803f18f02e5609a1ca00a5b78ea6d3613d44e1a0 (diff)
Merge remote-tracking branch 'origin/dev' into wip/cmake
Removed dependencies.yaml because we don't use it yet in wip/cmake. Fixed conflict in qmlcachegen.cpp. Change-Id: Ie1060c737bee1daa85779903598e5b6d5020d922
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/qmlcachegen/data/module.mjs6
-rw-r--r--tests/auto/qml/qmlcachegen/data/retain.qrc (renamed from tests/auto/qml/qmlcachegen/retain.qrc)2
-rw-r--r--tests/auto/qml/qmlcachegen/data/utils.mjs4
-rw-r--r--tests/auto/qml/qmlcachegen/qmlcachegen.pro6
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp30
-rw-r--r--tests/auto/qml/qmllint/data/Form.ui.qml4
-rw-r--r--tests/auto/qml/qmllint/data/FormUser.qml7
-rw-r--r--tests/auto/qml/qmllint/data/ImportWithPrefix.qml5
-rw-r--r--tests/auto/qml/qmllint/data/MethodInItem.qml5
-rw-r--r--tests/auto/qml/qmllint/data/MethodInScope.qml5
-rw-r--r--tests/auto/qml/qmllint/data/Things/SomethingElse.qml2
-rw-r--r--tests/auto/qml/qmllint/data/Things/plugins.qmltypes16
-rw-r--r--tests/auto/qml/qmllint/data/Things/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/UnmatchedSignalHandler.qml15
-rw-r--r--tests/auto/qml/qmllint/data/forLoop.qml9
-rw-r--r--tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml6
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp158
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp2
-rw-r--r--tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml30
-rw-r--r--tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp64
-rw-r--r--tests/auto/qml/qqmlcomponent/data/AliasToSubcomponentRequiredBase.qml10
-rw-r--r--tests/auto/qml/qqmlcomponent/data/BaseWithRequired.qml6
-rw-r--r--tests/auto/qml/qqmlcomponent/data/aliasToSubcomponentNotSet.qml4
-rw-r--r--tests/auto/qml/qqmlcomponent/data/createdFromQml.qml11
-rw-r--r--tests/auto/qml/qqmlcomponent/data/createdFromQmlFail.qml11
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredNotSet.qml5
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml6
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetLater.qml5
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasAfterSameFile.qml8
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasBeforeSameFile.qml8
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasParentFile.qml7
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredSetViaChainedAlias.qml9
-rw-r--r--tests/auto/qml/qqmlcomponent/data/setViaAliasToSubcomponent.qml5
-rw-r--r--tests/auto/qml/qqmlcomponent/data/shadowing.qml5
-rw-r--r--tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp113
-rw-r--r--tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp2
-rw-r--r--tests/auto/qml/qqmlconsole/data/logging.qml4
-rw-r--r--tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp8
-rw-r--r--tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp2
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-October.qml12
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml11
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml16
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml15
-rw-r--r--tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml1
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h8
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp189
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testIncubatedComponent.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testLoaderComponent.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testReloadComponent.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testScriptComponent.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testTopLevelComponent.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testTransientComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testTransientComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.1.qml1
-rw-r--r--tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.2.qml1
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp35
-rw-r--r--tests/auto/qml/qqmlincubator/data/requiredProperty.qml5
-rw-r--r--tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp39
-rw-r--r--tests/auto/qml/qqmlinstantiator/data/createAndRemove.qml11
-rw-r--r--tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp4
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.17.qml31
-rw-r--r--tests/auto/qml/qqmllanguage/data/fakeDotProperty.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/foreignExtended.qml20
-rw-r--r--tests/auto/qml/qqmllanguage/data/fuzzed.2.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidGroupedProperty.2.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/objectValueTypeProperty.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.1.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp4
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h34
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp175
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp57
-rw-r--r--tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/data/multiSingleton.qml6
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml17
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton2.qml6
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/internal/InternalType.qml6
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/moduleWithQmlSingleton.pro18
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/plugin.cpp50
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/qmldir2
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp4
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro3
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp17
-rw-r--r--tests/auto/qml/qqmlnotifier/data/connectnotify.qml3
-rw-r--r--tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp7
-rw-r--r--tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml17
-rw-r--r--tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp12
-rw-r--r--tests/auto/qml/qqmlproperty/data/aliasToBinding.qml23
-rw-r--r--tests/auto/qml/qqmlproperty/data/assignEmptyVariantMap.qml1
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp26
-rw-r--r--tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml5
-rw-r--r--tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml5
-rw-r--r--tests/auto/qml/qqmlpropertycache/data/noDuckType.qml7
-rw-r--r--tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp11
-rw-r--r--tests/auto/qml/qqmlqt/data/formatting.qml5
-rw-r--r--tests/auto/qml/qqmlqt/data/timeRoundtrip.qml2
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp19
-rw-r--r--tests/auto/qml/qqmltranslation/data/mylibrary.js5
-rw-r--r--tests/auto/qml/qqmltranslation/data/nested_js_translation.js3
-rw-r--r--tests/auto/qml/qqmltranslation/data/preferjs.qml8
-rw-r--r--tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp23
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml5
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml7
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir2
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml6
-rw-r--r--tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir2
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp20
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/data/userType.qml1
-rw-r--r--tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp6
-rw-r--r--tests/auto/qml/qqmlvaluetypes/data/color_read.qml3
-rw-r--r--tests/auto/qml/qqmlvaluetypes/testtypes.h3
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp16
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp42
-rw-r--r--tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp25
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp99
-rw-r--r--tests/auto/quick/qquickanimatedimage/data/currentframe.qml13
-rw-r--r--tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp46
-rw-r--r--tests/auto/quick/qquickboundaryrule/data/dragHandler.qml1
-rw-r--r--tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro2
-rw-r--r--tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp24
-rw-r--r--tests/auto/quick/qquickdrag/tst_qquickdrag.cpp8
-rw-r--r--tests/auto/quick/qquickdroparea/data/nested1.qml93
-rw-r--r--tests/auto/quick/qquickdroparea/data/nested2.qml93
-rw-r--r--tests/auto/quick/qquickdroparea/qquickdroparea.pro7
-rw-r--r--tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp88
-rw-r--r--tests/auto/quick/qquickflickable/data/resize.qml1
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp7
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml95
-rw-r--r--tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml47
-rw-r--r--tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml77
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp125
-rw-r--r--tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml8
-rw-r--r--tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml20
-rw-r--r--tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml20
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp10
-rw-r--r--tests/auto/quick/qquickmousearea/BLACKLIST4
-rw-r--r--tests/auto/quick/qquickmousearea/data/dragreset.qml1
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp34
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp37
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml59
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml64
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml53
-rw-r--r--tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml52
-rw-r--r--tests/auto/quick/qquickpathview/data/nestedmousearea2.qml101
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp103
-rw-r--r--tests/auto/quick/qquickpositioners/data/transitions-padding.qml10
-rw-r--r--tests/auto/quick/qquickpositioners/data/transitions.qml10
-rw-r--r--tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp63
-rw-r--r--tests/auto/quick/qquickrepeater/data/objlist_required.qml23
-rw-r--r--tests/auto/quick/qquickrepeater/data/requiredProperty.qml16
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp25
-rw-r--r--tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml72
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp17
-rw-r--r--tests/auto/quick/qquicktableview/data/delegateWithRequired.qml70
-rw-r--r--tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml71
-rw-r--r--tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml89
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp72
-rw-r--r--tests/auto/quick/qquicktext/data/transparentBackground.qml16
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp22
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp23
-rw-r--r--tests/auto/quick/qquicktextinput/BLACKLIST3
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp40
-rw-r--r--tests/auto/quick/qquickwindow/data/shortcut.qml47
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp28
-rw-r--r--tests/manual/nodetypes_ng/nodetypes_ng.cpp7
-rw-r--r--tests/manual/pointer/pointerDrag.qml65
-rw-r--r--tests/manual/pointer/tapWithModifiers.qml14
-rw-r--r--tests/manual/scenegraph_lancelot/hostinfo.sh76
-rw-r--r--tests/manual/scenegraph_lancelot/scenegrabber/main.cpp9
-rw-r--r--tests/manual/scenegraph_lancelot/scenegraph/scenegraph.pro4
-rw-r--r--tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp24
210 files changed, 3665 insertions, 535 deletions
diff --git a/tests/auto/qml/qmlcachegen/data/module.mjs b/tests/auto/qml/qmlcachegen/data/module.mjs
new file mode 100644
index 0000000000..6838766329
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/data/module.mjs
@@ -0,0 +1,6 @@
+
+import { helper } from "utils.mjs"
+
+export function entry() {
+ return helper()
+}
diff --git a/tests/auto/qml/qmlcachegen/retain.qrc b/tests/auto/qml/qmlcachegen/data/retain.qrc
index e5eed9b12f..e1b9045fbe 100644
--- a/tests/auto/qml/qmlcachegen/retain.qrc
+++ b/tests/auto/qml/qmlcachegen/data/retain.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/">
- <file alias="Retain.qml">data/Retain.qml</file>
+ <file alias="Retain.qml">Retain.qml</file>
</qresource>
</RCC>
diff --git a/tests/auto/qml/qmlcachegen/data/utils.mjs b/tests/auto/qml/qmlcachegen/data/utils.mjs
new file mode 100644
index 0000000000..25a1f38709
--- /dev/null
+++ b/tests/auto/qml/qmlcachegen/data/utils.mjs
@@ -0,0 +1,4 @@
+
+export function helper() {
+ return "ok"
+}
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index 7bd4414302..1a334b68ce 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -15,7 +15,9 @@ RESOURCES += \
data/Enums.qml \
data/componentInItem.qml \
data/jsmoduleimport.qml \
- data/script.mjs
+ data/script.mjs \
+ data/module.mjs \
+ data/utils.mjs
workerscripts_test.files = \
data/worker.js \
@@ -25,7 +27,7 @@ workerscripts_test.prefix = /workerscripts
RESOURCES += \
workerscripts_test \
trickypaths.qrc \
- retain.qrc
+ data/retain.qrc
# QTBUG-46375
!win32: RESOURCES += trickypaths_umlaut.qrc
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 102acf73d6..5d87c319f3 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -65,6 +65,7 @@ private slots:
void qrcScriptImport();
void fsScriptImport();
void moduleScriptImport();
+ void esModulesViaQJSEngine();
void enums();
@@ -360,7 +361,7 @@ static QQmlPrivate::CachedQmlUnit *temporaryModifiedCachedUnit = nullptr;
void tst_qmlcachegen::versionChecksForAheadOfTimeUnits()
{
QVERIFY(QFile::exists(":/data/versionchecks.qml"));
- QCOMPARE(QFileInfo(":/data/versionchecks.qml").size(), 0);
+ QVERIFY(QFileInfo(":/data/versionchecks.qml").size() > 0);
Q_ASSERT(!temporaryModifiedCachedUnit);
QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
@@ -387,12 +388,8 @@ void tst_qmlcachegen::versionChecksForAheadOfTimeUnits()
{
QQmlEngine engine;
- QQmlComponent component(&engine, QUrl("qrc:/data/versionchecks.qml"));
- QCOMPARE(component.status(), QQmlComponent::Error);
- QCOMPARE(component.errorString(),
- QString("qrc:/data/versionchecks.qml:-1 File was compiled ahead of time with an "
- "incompatible version of Qt and the original file cannot be found. Please "
- "recompile\n"));
+ CleanlyLoadingComponent component(&engine, QUrl("qrc:/data/versionchecks.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Ready);
}
Q_ASSERT(temporaryModifiedCachedUnit);
@@ -414,7 +411,7 @@ void tst_qmlcachegen::workerScripts()
{
QVERIFY(QFile::exists(":/workerscripts/data/worker.js"));
QVERIFY(QFile::exists(":/workerscripts/data/worker.qml"));
- QCOMPARE(QFileInfo(":/workerscripts/data/worker.js").size(), 0);
+ QVERIFY(QFileInfo(":/workerscripts/data/worker.js").size() > 0);
QQmlEngine engine;
CleanlyLoadingComponent component(&engine, QUrl("qrc:///workerscripts/data/worker.qml"));
@@ -503,7 +500,7 @@ void tst_qmlcachegen::trickyPaths()
{
QFETCH(QString, filePath);
QVERIFY2(QFile::exists(filePath), qPrintable(filePath));
- QCOMPARE(QFileInfo(filePath).size(), 0);
+ QVERIFY(QFileInfo(filePath).size() > 0);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc" + filePath));
QScopedPointer<QObject> obj(component.create());
@@ -584,7 +581,7 @@ void tst_qmlcachegen::moduleScriptImport()
QTRY_VERIFY(obj->property("ok").toBool());
QVERIFY(QFile::exists(":/data/script.mjs"));
- QCOMPARE(QFileInfo(":/data/script.mjs").size(), 0);
+ QVERIFY(QFileInfo(":/data/script.mjs").size() > 0);
{
auto componentPrivate = QQmlComponentPrivate::get(&component);
@@ -605,6 +602,14 @@ void tst_qmlcachegen::moduleScriptImport()
}
}
+void tst_qmlcachegen::esModulesViaQJSEngine()
+{
+ QJSEngine engine;
+ QJSValue module = engine.importModule(":/data/module.mjs");
+ QJSValue result = module.property("entry").call();
+ QCOMPARE(result.toString(), "ok");
+}
+
void tst_qmlcachegen::enums()
{
QQmlEngine engine;
@@ -617,7 +622,7 @@ void tst_qmlcachegen::enums()
void tst_qmlcachegen::sourceFileIndices()
{
QVERIFY(QFile::exists(":/data/versionchecks.qml"));
- QCOMPARE(QFileInfo(":/data/versionchecks.qml").size(), 0);
+ QVERIFY(QFileInfo(":/data/versionchecks.qml").size() > 0);
QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError;
const QV4::CompiledData::Unit *unitFromResources = QQmlMetaType::findCachedCompilationUnit(
@@ -632,8 +637,7 @@ void tst_qmlcachegen::reproducibleCache_data()
QTest::addColumn<QString>("filePath");
QDir dir(dataDirectory());
- for (const QString &entry : dir.entryList(QDir::Files)) {
- QVERIFY(entry.endsWith(".qml") || entry.endsWith(".js") || entry.endsWith(".mjs"));
+ for (const QString &entry : dir.entryList((QStringList() << "*.qml" << "*.js" << "*.mjs"), QDir::Files)) {
QTest::newRow(entry.toUtf8().constData()) << dir.filePath(entry);
}
}
diff --git a/tests/auto/qml/qmllint/data/Form.ui.qml b/tests/auto/qml/qmllint/data/Form.ui.qml
new file mode 100644
index 0000000000..459c82afbb
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Form.ui.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.0
+
+Item {
+}
diff --git a/tests/auto/qml/qmllint/data/FormUser.qml b/tests/auto/qml/qmllint/data/FormUser.qml
new file mode 100644
index 0000000000..ea3621586f
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/FormUser.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+Form {
+ x: 12
+ y: 13
+ objectName: "horst"
+}
diff --git a/tests/auto/qml/qmllint/data/ImportWithPrefix.qml b/tests/auto/qml/qmllint/data/ImportWithPrefix.qml
new file mode 100644
index 0000000000..6d070da21a
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/ImportWithPrefix.qml
@@ -0,0 +1,5 @@
+import "." as MyStuff
+
+MyStuff.Simple {
+ property bool something: contains(Qt.point(12, 34))
+}
diff --git a/tests/auto/qml/qmllint/data/MethodInItem.qml b/tests/auto/qml/qmllint/data/MethodInItem.qml
new file mode 100644
index 0000000000..dbdaf8bcc1
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MethodInItem.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ function doThings() { console.log("things") }
+}
diff --git a/tests/auto/qml/qmllint/data/MethodInScope.qml b/tests/auto/qml/qmllint/data/MethodInScope.qml
new file mode 100644
index 0000000000..7ba0829f61
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/MethodInScope.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+MethodInItem {
+ Component.onCompleted: doThings()
+}
diff --git a/tests/auto/qml/qmllint/data/Things/SomethingElse.qml b/tests/auto/qml/qmllint/data/Things/SomethingElse.qml
new file mode 100644
index 0000000000..0e69012662
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Things/SomethingElse.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+QtObject {}
diff --git a/tests/auto/qml/qmllint/data/Things/plugins.qmltypes b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
new file mode 100644
index 0000000000..00cda191cc
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
@@ -0,0 +1,16 @@
+import QtQuick.tooling 1.2
+Module {
+ dependencies: []
+ Component {
+ name: "SomethingEntirelyStrange"
+ prototype: "QObject"
+ Enum {
+ name: "AnEnum"
+ values: {
+ "AAA": 0,
+ "BBB": 1,
+ "CCC": 2
+ }
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/Things/qmldir b/tests/auto/qml/qmllint/data/Things/qmldir
new file mode 100644
index 0000000000..c53af3a340
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Things/qmldir
@@ -0,0 +1,3 @@
+module Things
+Something 1.0 SomethingElse.qml
+plugin doesNotExistPlugin
diff --git a/tests/auto/qml/qmllint/data/UnmatchedSignalHandler.qml b/tests/auto/qml/qmllint/data/UnmatchedSignalHandler.qml
new file mode 100644
index 0000000000..064444e182
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/UnmatchedSignalHandler.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.12
+
+Item {
+ width: 640
+ height: 480
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: console.log("okok")
+
+ Connections {
+ onClicked: console.log(mouse.x)
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/forLoop.qml b/tests/auto/qml/qmllint/data/forLoop.qml
new file mode 100644
index 0000000000..be8b12409b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/forLoop.qml
@@ -0,0 +1,9 @@
+import QtQml 2.0
+
+QtObject {
+ Component.onCompleted: {
+ var stuff = [1, 2, 3, 4]
+ for (var a in stuff)
+ console.log(a);
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml b/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml
new file mode 100644
index 0000000000..4847fc9196
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml
@@ -0,0 +1,6 @@
+import Things 1.0
+
+Something {
+ property var a: SomethingEntirelyStrange {}
+ property var b: SomethingEntirelyStrange.AAA
+}
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 582f146dca..04f554ac48 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -38,13 +38,21 @@ class TestQmllint: public QQmlDataTest
private Q_SLOTS:
void initTestCase() override;
- void test();
- void test_data();
+
void testUnqualified();
void testUnqualified_data();
+
+ void cleanQmlCode_data();
+ void cleanQmlCode();
+
+ void dirtyQmlCode_data();
+ void dirtyQmlCode();
+
void testUnqualifiedNoSpuriousParentWarning();
- void catchIdentifierNoFalsePositive();
+
private:
+ QString runQmllint(const QString &fileToLint, bool shouldSucceed);
+
QString m_qmllintPath;
};
@@ -61,37 +69,14 @@ void TestQmllint::initTestCase()
}
}
-void TestQmllint::test_data()
-{
- QTest::addColumn<QString>("filename");
- QTest::addColumn<bool>("isValid");
-
- // Valid files:
- QTest::newRow("Simple_QML") << QStringLiteral("Simple.qml") << true;
- QTest::newRow("QML_importing_JS") << QStringLiteral("importing_js.qml") << true;
- QTest::newRow("QTBUG-45916_JS_with_pragma_and_import") << QStringLiteral("QTBUG-45916.js") << true;
-
- // Invalid files:
- QTest::newRow("Invalid_syntax_QML") << QStringLiteral("failure1.qml") << false;
- QTest::newRow("Invalid_syntax_JS") << QStringLiteral("failure1.js") << false;
-}
-
void TestQmllint::testUnqualified()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
QFETCH(QString, filename);
QFETCH(QString, warningMessage);
QFETCH(int, warningLine);
QFETCH(int, warningColumn);
- QStringList args;
- args << QStringLiteral("-U") << testFile(filename) << QStringLiteral("-I") << qmlImportDir;
-
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode());
- QString output = process.readAllStandardError();
+
+ const QString output = runQmllint(filename, false);
QVERIFY(output.contains(QString::asprintf("Warning: unqualified access at %d:%d", warningLine, warningColumn)));
QVERIFY(output.contains(warningMessage));
}
@@ -118,56 +103,97 @@ void TestQmllint::testUnqualified_data()
QTest::newRow("SignalHandlerShort2") << QStringLiteral("SignalHandler.qml") << QStringLiteral("onPressAndHold: (mouse) => {...") << 12 << 34;
// access catch identifier outside catch block
QTest::newRow("CatchStatement") << QStringLiteral("CatchStatement.qml") << QStringLiteral("err") << 6 << 21;
+
+ QTest::newRow("NonSpuriousParent") << QStringLiteral("nonSpuriousParentWarning.qml") << QStringLiteral("property int x: <id>.parent.x") << 6 << 25;
}
void TestQmllint::testUnqualifiedNoSpuriousParentWarning()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
- {
- QString filename = testFile("spuriousParentWarning.qml");
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode() == 0);
- }
- {
- QString filename = testFile("nonSpuriousParentWarning.qml");
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode());
- }
+ const QString unknownNotFound = runQmllint("spuriousParentWarning.qml", true);
+ QVERIFY(unknownNotFound.contains(
+ QStringLiteral("warning: Unknown was not found. Did you add all import paths?")));
}
-void TestQmllint::catchIdentifierNoFalsePositive()
+void TestQmllint::dirtyQmlCode_data()
{
- auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
- QString filename = QLatin1String("catchIdentifierNoWarning.qml");
- filename.prepend(QStringLiteral("data/"));
- QStringList args;
- args << QStringLiteral("-U") << filename << QStringLiteral("-I") << qmlImportDir;
- QProcess process;
- process.start(m_qmllintPath, args);
- QVERIFY(process.waitForFinished());
- QVERIFY(process.exitStatus() == QProcess::NormalExit);
- QVERIFY(process.exitCode() == 0);
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("warningMessage");
+ QTest::addColumn<QString>("notContained");
+
+ QTest::newRow("Invalid_syntax_QML")
+ << QStringLiteral("failure1.qml")
+ << QStringLiteral("failure1.qml:4 : Expected token `:'")
+ << QString();
+ QTest::newRow("Invalid_syntax_JS")
+ << QStringLiteral("failure1.js")
+ << QStringLiteral("failure1.js:4 : Expected token `;'")
+ << QString();
+ QTest::newRow("UnmatchedSignalHandler")
+ << QStringLiteral("UnmatchedSignalHandler.qml")
+ << QString("Warning: no matching signal found for handler \"onClicked\" at 12:13")
+ << QStringLiteral("onMouseXChanged");
}
-void TestQmllint::test()
+void TestQmllint::dirtyQmlCode()
{
QFETCH(QString, filename);
- QFETCH(bool, isValid);
- QStringList args;
- args << QStringLiteral("--silent") << testFile(filename);
+ QFETCH(QString, warningMessage);
+ QFETCH(QString, notContained);
+
+ const QString output = runQmllint(filename, false);
+ QVERIFY(output.contains(warningMessage));
+ if (!notContained.isEmpty())
+ QVERIFY(!output.contains(notContained));
+}
+
+void TestQmllint::cleanQmlCode_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::newRow("Simple_QML") << QStringLiteral("Simple.qml");
+ QTest::newRow("QML_importing_JS") << QStringLiteral("importing_js.qml");
+ QTest::newRow("JS_with_pragma_and_import") << QStringLiteral("QTBUG-45916.js");
+ QTest::newRow("uiQml") << QStringLiteral("FormUser.qml");
+ QTest::newRow("methodInScope") << QStringLiteral("MethodInScope.qml");
+ QTest::newRow("importWithPrefix") << QStringLiteral("ImportWithPrefix.qml");
+ QTest::newRow("catchIdentifier") << QStringLiteral("catchIdentifierNoWarning.qml");
+ QTest::newRow("qmldirAndQmltypes") << QStringLiteral("qmldirAndQmltypes.qml");
+ QTest::newRow("forLoop") << QStringLiteral("forLoop.qml");
+}
+
+void TestQmllint::cleanQmlCode()
+{
+ QFETCH(QString, filename);
+ const QString warnings = runQmllint(filename, true);
+ QVERIFY(warnings.isEmpty());
+}
- bool success = QProcess::execute(m_qmllintPath, args) == 0;
- QCOMPARE(success, isValid);
+QString TestQmllint::runQmllint(const QString &fileToLint, bool shouldSucceed)
+{
+ auto qmlImportDir = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
+ QStringList args;
+ args << QStringLiteral("-U") << testFile(fileToLint)
+ << QStringLiteral("-I") << qmlImportDir
+ << QStringLiteral("-I") << dataDirectory()
+ << QStringLiteral("--silent");
+ QString errors;
+ auto verify = [&](bool isSilent) {
+ QProcess process;
+ process.start(m_qmllintPath, args);
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ if (shouldSucceed)
+ QCOMPARE(process.exitCode(), 0);
+ else
+ QVERIFY(process.exitCode() != 0);
+ errors = process.readAllStandardError();
+
+ if (isSilent)
+ QVERIFY(errors.isEmpty());
+ };
+ verify(true);
+ args.removeLast();
+ verify(false);
+ return errors;
}
QTEST_MAIN(TestQmllint)
diff --git a/tests/auto/qml/qmlmin/tst_qmlmin.cpp b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
index cae833cd60..79a73299a4 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -130,6 +130,8 @@ void tst_qmlmin::initTestCase()
invalidFiles << "tests/auto/qml/qjsengine/script/com/trolltech/syntaxerror/__init__.js";
invalidFiles << "tests/auto/qml/debugger/qqmlpreview/data/broken.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml";
// generatorFunction.qml is not invalid per se, but the minifier cannot handle yield statements
invalidFiles << "tests/auto/qml/qqmlecmascript/data/generatorFunction.qml";
#endif
diff --git a/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml b/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml
new file mode 100644
index 0000000000..d0f30c5da5
--- /dev/null
+++ b/tests/auto/qml/qqmlbinding/data/noUnexpectedStringConversion.qml
@@ -0,0 +1,30 @@
+import QtQuick 2.12
+import QtQuick.Window 2.12
+
+Window {
+visible: true
+width: 640
+height: 480
+title: qsTr("Hello World")
+
+ Rectangle {
+ id: colorRect
+ objectName: "colorRect"
+ anchors.fill: parent
+ Text {
+ objectName: "colorLabel"
+ id: colorLabel
+ }
+ }
+
+ Binding {
+ target: colorLabel
+ property: "text"
+ value: "red"
+ }
+ Binding {
+ target: colorRect
+ property: "color"
+ value: "red"
+ }
+}
diff --git a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
index 9b66cd828a..2c2d311ff7 100644
--- a/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
+++ b/tests/auto/qml/qqmlbinding/tst_qqmlbinding.cpp
@@ -55,6 +55,7 @@ private slots:
void delayed();
void bindingOverwriting();
void bindToQmlComponent();
+ void bindingDoesNoWeirdConversion();
private:
QQmlEngine engine;
@@ -68,7 +69,7 @@ void tst_qqmlbinding::binding()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("test-binding.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect { qobject_cast<QQuickRectangle*>(c.create()) };
QVERIFY(rect != nullptr);
QQmlBind *binding3 = qobject_cast<QQmlBind*>(rect->findChild<QQmlBind*>("binding3"));
@@ -85,18 +86,16 @@ void tst_qqmlbinding::binding()
QQmlBind *binding = qobject_cast<QQmlBind*>(rect->findChild<QQmlBind*>("binding1"));
QVERIFY(binding != nullptr);
- QCOMPARE(binding->object(), qobject_cast<QObject*>(rect));
+ QCOMPARE(binding->object(), qobject_cast<QObject*>(rect.get()));
QCOMPARE(binding->property(), QLatin1String("text"));
QCOMPARE(binding->value().toString(), QLatin1String("Hello"));
-
- delete rect;
}
void tst_qqmlbinding::whenAfterValue()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("test-binding2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())};
QVERIFY(rect != nullptr);
QCOMPARE(rect->color(), QColor("yellow"));
@@ -104,15 +103,13 @@ void tst_qqmlbinding::whenAfterValue()
rect->setProperty("changeColor", true);
QCOMPARE(rect->color(), QColor("red"));
-
- delete rect;
}
void tst_qqmlbinding::restoreBinding()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("restoreBinding.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect { qobject_cast<QQuickRectangle*>(c.create()) };
QVERIFY(rect != nullptr);
QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem"));
@@ -134,8 +131,6 @@ void tst_qqmlbinding::restoreBinding()
//original binding restored
myItem->setY(49);
QCOMPARE(myItem->x(), qreal(100-49));
-
- delete rect;
}
void tst_qqmlbinding::restoreBindingValue()
@@ -214,7 +209,7 @@ void tst_qqmlbinding::restoreBindingWithLoop()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("restoreBindingWithLoop.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())};
QVERIFY(rect != nullptr);
QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem"));
@@ -242,15 +237,13 @@ void tst_qqmlbinding::restoreBindingWithLoop()
myItem->setY(49);
QCOMPARE(myItem->x(), qreal(49 + 100));
-
- delete rect;
}
void tst_qqmlbinding::restoreBindingWithoutCrash()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("restoreBindingWithoutCrash.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())};
QVERIFY(rect != nullptr);
QQuickRectangle *myItem = qobject_cast<QQuickRectangle*>(rect->findChild<QQuickRectangle*>("myItem"));
@@ -281,8 +274,6 @@ void tst_qqmlbinding::restoreBindingWithoutCrash()
//original binding restored
myItem->setY(49);
QCOMPARE(myItem->x(), qreal(100-49));
-
- delete rect;
}
//QTBUG-20692
@@ -290,15 +281,13 @@ void tst_qqmlbinding::deletedObject()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("deletedObject.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QQuickRectangle> rect {qobject_cast<QQuickRectangle*>(c.create())};
QVERIFY(rect != nullptr);
QGuiApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
//don't crash
rect->setProperty("activateBinding", true);
-
- delete rect;
}
void tst_qqmlbinding::warningOnUnknownProperty()
@@ -307,9 +296,8 @@ void tst_qqmlbinding::warningOnUnknownProperty()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("unknownProperty.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) };
QVERIFY(item);
- delete item;
QCOMPARE(messageHandler.messages().count(), 1);
@@ -323,9 +311,8 @@ void tst_qqmlbinding::warningOnReadOnlyProperty()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("readonlyProperty.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) };
QVERIFY(item);
- delete item;
QCOMPARE(messageHandler.messages().count(), 1);
@@ -339,9 +326,8 @@ void tst_qqmlbinding::disabledOnUnknownProperty()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("disabledUnknown.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) };
QVERIFY(item);
- delete item;
QCOMPARE(messageHandler.messages().count(), 0);
}
@@ -352,10 +338,8 @@ void tst_qqmlbinding::disabledOnReadonlyProperty()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("disabledReadonly.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item { qobject_cast<QQuickItem *>(c.create()) };
QVERIFY(item);
- delete item;
-
QCOMPARE(messageHandler.messages().count(), 0);
}
@@ -363,21 +347,19 @@ void tst_qqmlbinding::delayed()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("delayed.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item {qobject_cast<QQuickItem*>(c.create())};
QVERIFY(item != nullptr);
// update on creation
QCOMPARE(item->property("changeCount").toInt(), 1);
- QMetaObject::invokeMethod(item, "updateText");
+ QMetaObject::invokeMethod(item.get(), "updateText");
// doesn't update immediately
QCOMPARE(item->property("changeCount").toInt(), 1);
QCoreApplication::processEvents();
// only updates once (non-delayed would update twice)
QCOMPARE(item->property("changeCount").toInt(), 2);
-
- delete item;
}
void tst_qqmlbinding::bindingOverwriting()
@@ -387,9 +369,8 @@ void tst_qqmlbinding::bindingOverwriting()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("bindingOverwriting.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QQuickItem> item {qobject_cast<QQuickItem*>(c.create())};
QVERIFY(item);
- delete item;
QLoggingCategory::setFilterRules(QString());
QCOMPARE(messageHandler.messages().count(), 2);
@@ -402,6 +383,21 @@ void tst_qqmlbinding::bindToQmlComponent()
QVERIFY(c.create());
}
+// QTBUG-78943
+void tst_qqmlbinding::bindingDoesNoWeirdConversion()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("noUnexpectedStringConversion.qml"));
+ QScopedPointer<QObject> o {c.create()};
+ QVERIFY(o);
+ QObject *colorRect = o->findChild<QObject*>("colorRect");
+ QVERIFY(colorRect);
+ QCOMPARE(qvariant_cast<QColor>(colorRect->property("color")), QColorConstants::Red);
+ QObject *colorLabel = o->findChild<QObject*>("colorLabel");
+ QCOMPARE(colorLabel->property("text").toString(), QLatin1String("red"));
+ QVERIFY(colorLabel);
+}
+
QTEST_MAIN(tst_qqmlbinding)
#include "tst_qqmlbinding.moc"
diff --git a/tests/auto/qml/qqmlcomponent/data/AliasToSubcomponentRequiredBase.qml b/tests/auto/qml/qqmlcomponent/data/AliasToSubcomponentRequiredBase.qml
new file mode 100644
index 0000000000..f693cb4c2e
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/AliasToSubcomponentRequiredBase.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.13
+
+Item {
+ property alias i_alias: sub.i
+
+ Item {
+ id: sub
+ required property int i
+ }
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/BaseWithRequired.qml b/tests/auto/qml/qqmlcomponent/data/BaseWithRequired.qml
new file mode 100644
index 0000000000..0ce61c8d9d
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/BaseWithRequired.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.14
+
+Item {
+ id: base
+ required property int i
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/aliasToSubcomponentNotSet.qml b/tests/auto/qml/qqmlcomponent/data/aliasToSubcomponentNotSet.qml
new file mode 100644
index 0000000000..527eb417e5
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/aliasToSubcomponentNotSet.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.13
+
+AliasToSubcomponentRequiredBase {
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/createdFromQml.qml b/tests/auto/qml/qqmlcomponent/data/createdFromQml.qml
new file mode 100644
index 0000000000..60a2077606
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/createdFromQml.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ property Item it
+ Component.onCompleted: function() {
+ let component = Qt.createComponent("requiredNotSet.qml", Component.PreferSynchronous, root)
+ console.assert(component.status == Component.Ready)
+ it = component.createObject(component, {i: 42})
+ }
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/createdFromQmlFail.qml b/tests/auto/qml/qqmlcomponent/data/createdFromQmlFail.qml
new file mode 100644
index 0000000000..e09ddcccc1
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/createdFromQmlFail.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ property Item it
+ Component.onCompleted: function() {
+ let component = Qt.createComponent("requiredNotSet.qml", Component.PreferSynchronous, root)
+ console.assert(component.status == Component.Ready)
+ root.it = component.createObject(component)
+ }
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredNotSet.qml b/tests/auto/qml/qqmlcomponent/data/requiredNotSet.qml
new file mode 100644
index 0000000000..c0b5d695f1
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredNotSet.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.14
+
+Item {
+ required property int i
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml
new file mode 100644
index 0000000000..76dfcd87e5
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetInSameFile.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.14
+
+Item {
+ required property int i
+ i: 42
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetLater.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetLater.qml
new file mode 100644
index 0000000000..3b7811e453
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetLater.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.14
+
+BaseWithRequired {
+ i: 13
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasAfterSameFile.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasAfterSameFile.qml
new file mode 100644
index 0000000000..163616bc8a
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasAfterSameFile.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.14
+
+Item {
+ id: withAlias
+ j: 42
+ required property int i
+ property alias j: withAlias.i
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasBeforeSameFile.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasBeforeSameFile.qml
new file mode 100644
index 0000000000..e59bccf379
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasBeforeSameFile.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.14
+
+Item {
+ id: withAlias
+ required property int i
+ j: 42
+ property alias j: withAlias.i
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasParentFile.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasParentFile.qml
new file mode 100644
index 0000000000..0bc2f8a7df
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetViaAliasParentFile.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.14
+
+BaseWithRequired {
+ id: withAlias
+ property alias j: withAlias.i
+ j: 42
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredSetViaChainedAlias.qml b/tests/auto/qml/qqmlcomponent/data/requiredSetViaChainedAlias.qml
new file mode 100644
index 0000000000..45cf02d3d8
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredSetViaChainedAlias.qml
@@ -0,0 +1,9 @@
+import QtQml 2.12
+
+QtObject {
+ id: stuff
+ required property int x;
+ property alias y: stuff.x
+ property alias z: stuff.y
+ z: 5
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/setViaAliasToSubcomponent.qml b/tests/auto/qml/qqmlcomponent/data/setViaAliasToSubcomponent.qml
new file mode 100644
index 0000000000..2dc182ea82
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/setViaAliasToSubcomponent.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.13
+
+AliasToSubcomponentRequiredBase {
+ i_alias: 42
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/shadowing.qml b/tests/auto/qml/qqmlcomponent/data/shadowing.qml
new file mode 100644
index 0000000000..4d119d8884
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/shadowing.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.14
+
+BaseWithRequired {
+ property int i: 13
+}
diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
index 79ec507388..2acc62ca28 100644
--- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
+++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp
@@ -121,6 +121,9 @@ private slots:
void relativeUrl_data();
void relativeUrl();
void setDataNoEngineNoSegfault();
+ void testRequiredProperties_data();
+ void testRequiredProperties();
+ void testRequiredPropertiesFromQml();
void testSetInitialProperties();
private:
@@ -222,12 +225,12 @@ void tst_qqmlcomponent::qmlCreateObjectAutoParent()
QVERIFY(window_item);
QVERIFY(window_window);
- QCOMPARE(qtobject_item->metaObject()->className(), "QQuickItem");
- QCOMPARE(qtobject_window->metaObject()->className(), "QQuickWindow");
- QCOMPARE(item_item->metaObject()->className(), "QQuickItem");
- QCOMPARE(item_window->metaObject()->className(), "QQuickWindow");
- QCOMPARE(window_item->metaObject()->className(), "QQuickItem");
- QCOMPARE(window_window->metaObject()->className(), "QQuickWindow");
+ QVERIFY(QByteArray(qtobject_item->metaObject()->className()).startsWith("QQuickItem"));
+ QVERIFY(QByteArray(qtobject_window->metaObject()->className()).startsWith("QQuickWindow"));
+ QVERIFY(QByteArray(item_item->metaObject()->className()).startsWith("QQuickItem"));
+ QVERIFY(QByteArray(item_window->metaObject()->className()).startsWith("QQuickWindow"));
+ QVERIFY(QByteArray(window_item->metaObject()->className()).startsWith("QQuickItem"));
+ QVERIFY(QByteArray(window_window->metaObject()->className()).startsWith("QQuickWindow"));
QCOMPARE(qtobject_qtobject->parent(), qtobjectParent);
QCOMPARE(qtobject_item->parent(), qtobjectParent);
@@ -668,35 +671,80 @@ void tst_qqmlcomponent::setDataNoEngineNoSegfault()
QVERIFY(!c);
}
-void tst_qqmlcomponent::testSetInitialProperties()
+void tst_qqmlcomponent::testRequiredProperties_data()
+{
+ QTest::addColumn<QUrl>("testFile");
+ QTest::addColumn<bool>("shouldSucceed");
+ QTest::addColumn<QString>("errorMsg");
+
+ QTest::addRow("requiredSetViaChainedAlias") << testFileUrl("requiredSetViaChainedAlias.qml") << true << "";
+ QTest::addRow("requiredNotSet") << testFileUrl("requiredNotSet.qml") << false << "Required property i was not initialized";
+ QTest::addRow("requiredSetInSameFile") << testFileUrl("requiredSetInSameFile.qml") << true << "";
+ QTest::addRow("requiredSetViaAlias1") << testFileUrl("requiredSetViaAliasBeforeSameFile.qml") << true << "";
+ QTest::addRow("requiredSetViaAlias2") << testFileUrl("requiredSetViaAliasAfterSameFile.qml") << true << "";
+ QTest::addRow("requiredSetViaAlias3") << testFileUrl("requiredSetViaAliasParentFile.qml") << true << "";
+ QTest::addRow("shadowing") << testFileUrl("shadowing.qml") << false << "Required property i was not initialized";
+ QTest::addRow("setLater") << testFileUrl("requiredSetLater.qml") << true << "";
+ QTest::addRow("setViaAliasToSubcomponent") << testFileUrl("setViaAliasToSubcomponent.qml") << true << "";
+ QTest::addRow("aliasToSubcomponentNotSet") << testFileUrl("aliasToSubcomponentNotSet.qml") << false << "It can be set via the alias property i_alias";
+}
+
+
+void tst_qqmlcomponent::testRequiredProperties()
+{
+ QQmlEngine eng;
+ using QScopedObjPointer = QScopedPointer<QObject>;
+ QFETCH(QUrl, testFile);
+ QFETCH(bool, shouldSucceed);
+ QQmlComponent comp(&eng);
+ comp.loadUrl(testFile);
+ QScopedObjPointer obj {comp.create()};
+ if (shouldSucceed)
+ QVERIFY(obj);
+ else {
+ QVERIFY(!obj);
+ QFETCH(QString, errorMsg);
+ QVERIFY(comp.errorString().contains(errorMsg));
+ }
+}
+
+void tst_qqmlcomponent::testRequiredPropertiesFromQml()
{
QQmlEngine eng;
{
- // JSON based initialization
QQmlComponent comp(&eng);
- comp.loadUrl(testFileUrl("allJSONTypes.qml"));
- QScopedPointer<QObject> obj { comp.beginCreate(eng.rootContext()) };
+ comp.loadUrl(testFileUrl("createdFromQml.qml"));
+ QScopedPointer<QObject> obj { comp.create() };
QVERIFY(obj);
- comp.setInitialProperties(obj.get(), QVariantMap {
- {QLatin1String("i"), 42},
- {QLatin1String("b"), true},
- {QLatin1String("d"), 3.1416},
- {QLatin1String("s"), QLatin1String("hello world")},
- {QLatin1String("nothing"), QVariant::fromValue(nullptr)}
- });
- comp.completeCreate();
- if (!comp.errors().empty())
- qDebug() << comp.errorString() << comp.errors();
- QVERIFY(comp.errors().empty());
- QCOMPARE(obj->property("i"), 42);
- QCOMPARE(obj->property("b"), true);
- QCOMPARE(obj->property("d"), 3.1416);
- QCOMPARE(obj->property("s"), QLatin1String("hello world"));
- QCOMPARE(obj->property("nothing"), QVariant::fromValue(nullptr));
+ auto root = qvariant_cast<QQuickItem*>(obj->property("it"));
+ QVERIFY(root);
+ QCOMPARE(root->property("i").toInt(), 42);
}
{
- // QVariant
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(".*requiredNotSet.qml:4:5: Required property i was not initialized"));
QQmlComponent comp(&eng);
+ comp.loadUrl(testFileUrl("createdFromQmlFail.qml"));
+ QScopedPointer<QObject> obj { comp.create() };
+ QVERIFY(obj);
+ QCOMPARE(qvariant_cast<QQuickItem *>(obj->property("it")), nullptr);
+ }
+}
+
+struct ComponentWithPublicSetInitial : QQmlComponent
+{
+ using QQmlComponent::QQmlComponent;
+ void setInitialProperties(QObject *o, QVariantMap map)
+ {
+ QQmlComponent::setInitialProperties(o, map);
+ }
+};
+
+void tst_qqmlcomponent::testSetInitialProperties()
+{
+ QQmlEngine eng;
+ {
+ // QVariant
+ ComponentWithPublicSetInitial comp(&eng);
comp.loadUrl(testFileUrl("variantBasedInitialization.qml"));
QScopedPointer<QObject> obj { comp.beginCreate(eng.rootContext()) };
QVERIFY(obj);
@@ -728,8 +776,6 @@ void tst_qqmlcomponent::testSetInitialProperties()
});
#undef ASJSON
comp.completeCreate();
- if (!comp.errors().empty())
- qDebug() << comp.errorString() << comp.errors();
QVERIFY(comp.errors().empty());
QCOMPARE(obj->property("i"), 42);
QCOMPARE(obj->property("b"), true);
@@ -751,13 +797,20 @@ void tst_qqmlcomponent::testSetInitialProperties()
}
{
+ // createWithInitialProperties convenience function
+ QQmlComponent comp(&eng);
+ comp.loadUrl(testFileUrl("requiredNotSet.qml"));
+ QScopedPointer<QObject> obj {comp.createWithInitialProperties( QVariantMap { {QLatin1String("i"), QJsonValue{42}} })};
+ QVERIFY(obj);
+ QCOMPARE(obj->property("i"), 42);
+ }
+ {
// createWithInitialProperties: setting a nonexistent property
QQmlComponent comp(&eng);
comp.loadUrl(testFileUrl("allJSONTypes.qml"));
QScopedPointer<QObject> obj {
comp.createWithInitialProperties(QVariantMap { {"notThePropertiesYoureLookingFor", 42} })
};
- qDebug() << comp.errorString();
QVERIFY(obj);
QVERIFY(comp.errorString().contains("Could not set property notThePropertiesYoureLookingFor"));
}
diff --git a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
index cf0f3c7bb3..07af519a3d 100644
--- a/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
+++ b/tests/auto/qml/qqmlconnections/tst_qqmlconnections.cpp
@@ -470,7 +470,7 @@ void tst_qqmlconnections::noAcceleratedGlobalLookup()
QVERIFY(c.isReady());
QScopedPointer<QObject> object(c.create());
const QVariant val = object->property("testEnum");
- QCOMPARE(val.type(), int(QMetaType::Int));
+ QCOMPARE(val.type(), QVariant::Int);
QCOMPARE(val.toInt(), int(Proxy::EnumValue));
}
diff --git a/tests/auto/qml/qqmlconsole/data/logging.qml b/tests/auto/qml/qqmlconsole/data/logging.qml
index 1f929d311b..f5eaeb442a 100644
--- a/tests/auto/qml/qqmlconsole/data/logging.qml
+++ b/tests/auto/qml/qqmlconsole/data/logging.qml
@@ -31,6 +31,8 @@ import QtQuick 2.0
QtObject {
id:root
+ required property var customObject
+ required property var stringListProperty
function consoleCount() {
console.count("console.count", "Ignore additional argument");
@@ -67,7 +69,7 @@ QtObject {
console.log(1, "pong!", new Object);
console.log(1, ["ping","pong"], new Object, 2);
- console.log(contextStringListProperty);
+ console.log(stringListProperty);
console.log(customObject);
console.log([[1,2,3,[2,2,2,2],4],[5,6,7,8]]);
diff --git a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
index b157314071..48613d04f1 100644
--- a/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
+++ b/tests/auto/qml/qqmlconsole/tst_qqmlconsole.cpp
@@ -95,16 +95,16 @@ void tst_qqmlconsole::logging()
QTest::ignoreMessage(QtDebugMsg, "QVariant(CustomObject, MY OBJECT)");
QTest::ignoreMessage(QtDebugMsg, "[[1,2,3,[2,2,2,2],4],[5,6,7,8]]");
- QScopedPointer<QQmlContext> loggingContext(new QQmlContext(engine.rootContext()));
QStringList stringList; stringList << QStringLiteral("Hello") << QStringLiteral("World");
- loggingContext->setContextProperty("contextStringListProperty", stringList);
CustomObject customObject;
QVERIFY(QMetaType::registerDebugStreamOperator<CustomObject>());
- loggingContext->setContextProperty("customObject", QVariant::fromValue(customObject));
QQmlComponent component(&engine, testUrl);
- QScopedPointer<QObject> object(component.create(loggingContext.data()));
+ QScopedPointer<QObject> object(component.createWithInitialProperties({
+ {"customObject", QVariant::fromValue(customObject)},
+ {"stringListProperty", stringList}
+ }));
QVERIFY(object != nullptr);
}
diff --git a/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp b/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp
index 99cabb4b09..13e4d4c53b 100644
--- a/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp
+++ b/tests/auto/qml/qqmlcpputils/tst_qqmlcpputils.cpp
@@ -71,7 +71,7 @@ void tst_qqmlcpputils::fastConnect()
{
MyObject obj;
- qmlobject_connect(&obj, MyObject, SIGNAL(signal1()), &obj, MyObject, SLOT(slot1()))
+ qmlobject_connect(&obj, MyObject, SIGNAL(signal1()), &obj, MyObject, SLOT(slot1()));
obj.signal1();
QCOMPARE(obj.slotCount, 1);
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml
new file mode 100644
index 0000000000..6686831e1c
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml
@@ -0,0 +1,12 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ // QTBUG-78996
+ dateProperty = new Date(2019, 9, 3)
+ boolProperty = (dateProperty.getFullYear() == 2019
+ && dateProperty.getMonth() == 9
+ && dateProperty.getDate() == 3)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml
new file mode 100644
index 0000000000..29ec40ffbd
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateProperty = new Date(2019, 2, 0) // Feb 28th
+ boolProperty = (dateProperty.getFullYear() == 2019
+ && dateProperty.getMonth() == 1
+ && dateProperty.getDate() == 28)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml
new file mode 100644
index 0000000000..7fc8bf43bd
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateProperty = new Date(2019, 1, 29) // March 1st
+ boolProperty = (dateProperty.getFullYear() == 2019
+ && dateProperty.getMonth() == 2
+ && dateProperty.getDate() == 1)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml
new file mode 100644
index 0000000000..6dd84810e6
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateProperty = new Date(2020, 2, 0) // Feb 29th
+ boolProperty = (dateProperty.getFullYear() == 2020
+ && dateProperty.getMonth() == 1
+ && dateProperty.getDate() == 29)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml
new file mode 100644
index 0000000000..ddb79727ef
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateProperty = new Date(2017, 40, -61) // 2020, Feb 29th
+ boolProperty = (dateProperty.getFullYear() == 2020
+ && dateProperty.getMonth() == 1
+ && dateProperty.getDate() == 29)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml
new file mode 100644
index 0000000000..90514c39c8
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml
@@ -0,0 +1,11 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateProperty = new Date(2019, 12, 0) // Dec 31
+ boolProperty = (dateProperty.getFullYear() == 2019
+ && dateProperty.getMonth() == 11
+ && dateProperty.getDate() == 31)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml
new file mode 100644
index 0000000000..c97076f887
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml
@@ -0,0 +1,16 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ // QTBUG-78996
+ dateTimeProperty = new Date(2019, 9, 3, 12)
+ boolProperty = (dateTimeProperty.getFullYear() == 2019
+ && dateTimeProperty.getMonth() == 9
+ && dateTimeProperty.getDate() == 3
+ && dateTimeProperty.getHours() == 12
+ && dateTimeProperty.getMinutes() == 0
+ && dateTimeProperty.getSeconds() == 0
+ && dateTimeProperty.getMilliseconds() == 0)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml
new file mode 100644
index 0000000000..2b6b9af3e1
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateTimeProperty = new Date(2019, 1, 28, 23, 59, 59, 1001) // 2019-3-1 0:0:0.001
+ boolProperty = (dateTimeProperty.getFullYear() == 2019
+ && dateTimeProperty.getMonth() == 2
+ && dateTimeProperty.getDate() == 1
+ && dateTimeProperty.getHours() == 0
+ && dateTimeProperty.getMinutes() == 0
+ && dateTimeProperty.getSeconds() == 0
+ && dateTimeProperty.getMilliseconds() == 1)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml
new file mode 100644
index 0000000000..7d018e2904
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateTimeProperty = new Date(2019, 11, 31, 1440) // 2020-2-29 0:0:0
+ boolProperty = (dateTimeProperty.getFullYear() == 2020
+ && dateTimeProperty.getMonth() == 1
+ && dateTimeProperty.getDate() == 29
+ && dateTimeProperty.getHours() == 0
+ && dateTimeProperty.getMinutes() == 0
+ && dateTimeProperty.getSeconds() == 0
+ && dateTimeProperty.getMilliseconds() == 0)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml
new file mode 100644
index 0000000000..0a7687c669
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateTimeProperty = new Date(2020, 2, 1, 0, 0, 0, -1) // 2020-2-29 23:59:59.999
+ boolProperty = (dateTimeProperty.getFullYear() == 2020
+ && dateTimeProperty.getMonth() == 1
+ && dateTimeProperty.getDate() == 29
+ && dateTimeProperty.getHours() == 23
+ && dateTimeProperty.getMinutes() == 59
+ && dateTimeProperty.getSeconds() == 59
+ && dateTimeProperty.getMilliseconds() == 999)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml
new file mode 100644
index 0000000000..738d603b4b
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateTimeProperty = new Date(2020, 1, 28, 0, 1440) // 2020-2-29 0:0:0
+ boolProperty = (dateTimeProperty.getFullYear() == 2020
+ && dateTimeProperty.getMonth() == 1
+ && dateTimeProperty.getDate() == 29
+ && dateTimeProperty.getHours() == 0
+ && dateTimeProperty.getMinutes() == 0
+ && dateTimeProperty.getSeconds() == 0
+ && dateTimeProperty.getMilliseconds() == 0)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml
new file mode 100644
index 0000000000..d48534f0d0
--- /dev/null
+++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml
@@ -0,0 +1,15 @@
+import Qt.test 1.0
+import QtQuick 2.0
+
+MyTypeObject {
+ Component.onCompleted: {
+ dateTimeProperty = new Date(2020, 1, 28, 23, 0, 3600) // 2020-2-29 0:0:0
+ boolProperty = (dateTimeProperty.getFullYear() == 2020
+ && dateTimeProperty.getMonth() == 1
+ && dateTimeProperty.getDate() == 29
+ && dateTimeProperty.getHours() == 0
+ && dateTimeProperty.getMinutes() == 0
+ && dateTimeProperty.getSeconds() == 0
+ && dateTimeProperty.getMilliseconds() == 0)
+ }
+}
diff --git a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
index 54d29dfc94..9fdb7f92f3 100644
--- a/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
+++ b/tests/auto/qml/qqmlecmascript/data/signalParameterTypes.qml
@@ -1,4 +1,5 @@
import Qt.test 1.0
+import QtQuick 2.0 // We need the the QtQuick color provider for colorProperty
MyQmlObject
{
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 730dc7cab8..3233e7f105 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -1098,13 +1098,11 @@ class MyItemUsingRevisionedObject : public QObject
Q_PROPERTY(MyRevisionedClass *revisioned READ revisioned)
public:
- MyItemUsingRevisionedObject() {
- m_revisioned = new MyRevisionedClass;
- }
+ MyItemUsingRevisionedObject() : m_revisioned (new MyRevisionedClass) {}
- MyRevisionedClass *revisioned() const { return m_revisioned; }
+ MyRevisionedClass *revisioned() const { return m_revisioned.get(); }
private:
- MyRevisionedClass *m_revisioned;
+ QScopedPointer<MyRevisionedClass> m_revisioned;
};
QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 269d90c891..f4de83eb87 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -79,6 +79,10 @@ private slots:
void assignDate();
void exportDate_data();
void exportDate();
+ void checkDate_data();
+ void checkDate();
+ void checkDateTime_data();
+ void checkDateTime();
void idShortcutInvalidates();
void boolPropertiesEvaluateAsBool();
void methods();
@@ -568,6 +572,82 @@ void tst_qqmlecmascript::exportDate()
QCOMPARE(object->boolProperty(), true);
}
+void tst_qqmlecmascript::checkDate_data()
+{
+ QTest::addColumn<QUrl>("source");
+ QTest::addColumn<QDate>("date");
+ // NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12.
+ QTest::newRow("denormal-March")
+ << testFileUrl("checkDate-denormal-March.qml")
+ << QDate(2019, 3, 1);
+ QTest::newRow("denormal-leap")
+ << testFileUrl("checkDate-denormal-leap.qml")
+ << QDate(2020, 2, 29);
+ QTest::newRow("denormal-Feb")
+ << testFileUrl("checkDate-denormal-Feb.qml")
+ << QDate(2019, 2, 28);
+ QTest::newRow("denormal-year")
+ << testFileUrl("checkDate-denormal-year.qml")
+ << QDate(2019, 12, 31);
+ QTest::newRow("denormal-wrap")
+ << testFileUrl("checkDate-denormal-wrap.qml")
+ << QDate(2020, 2, 29);
+ QTest::newRow("October")
+ << testFileUrl("checkDate-October.qml")
+ << QDate(2019, 10, 3);
+}
+
+void tst_qqmlecmascript::checkDate()
+{
+ QFETCH(const QUrl, source);
+ QFETCH(const QDate, date);
+ QQmlEngine e;
+ QQmlComponent component(&e, source);
+ QScopedPointer<QObject> obj(component.create());
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
+ QVERIFY(object != nullptr);
+ QCOMPARE(object->dateProperty(), date);
+ QVERIFY(object->boolProperty());
+}
+
+void tst_qqmlecmascript::checkDateTime_data()
+{
+ QTest::addColumn<QUrl>("source");
+ QTest::addColumn<QDateTime>("when");
+ // NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12.
+ QTest::newRow("denormal-March")
+ << testFileUrl("checkDateTime-denormal-March.qml")
+ << QDateTime(QDate(2019, 3, 1), QTime(0, 0, 0, 1), Qt::LocalTime);
+ QTest::newRow("denormal-leap")
+ << testFileUrl("checkDateTime-denormal-leap.qml")
+ << QDateTime(QDate(2020, 2, 29), QTime(23, 59, 59, 999), Qt::LocalTime);
+ QTest::newRow("denormal-hours")
+ << testFileUrl("checkDateTime-denormal-hours.qml")
+ << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
+ QTest::newRow("denormal-minutes")
+ << testFileUrl("checkDateTime-denormal-minutes.qml")
+ << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
+ QTest::newRow("denormal-seconds")
+ << testFileUrl("checkDateTime-denormal-seconds.qml")
+ << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime);
+ QTest::newRow("October")
+ << testFileUrl("checkDateTime-October.qml")
+ << QDateTime(QDate(2019, 10, 3), QTime(12, 0), Qt::LocalTime);
+}
+
+void tst_qqmlecmascript::checkDateTime()
+{
+ QFETCH(const QUrl, source);
+ QFETCH(const QDateTime, when);
+ QQmlEngine e;
+ QQmlComponent component(&e, source);
+ QScopedPointer<QObject> obj(component.create());
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data());
+ QVERIFY(object != nullptr);
+ QCOMPARE(object->dateTimeProperty(), when);
+ QVERIFY(object->boolProperty());
+}
+
void tst_qqmlecmascript::idShortcutInvalidates()
{
QQmlEngine engine;
@@ -1693,10 +1773,10 @@ void tst_qqmlecmascript::componentCreation()
}
QQmlComponent component(&engine, testUrl);
- MyTypeObject *object = qobject_cast<MyTypeObject*>(component.create());
+ QScopedPointer<MyTypeObject> object(qobject_cast<MyTypeObject*>(component.create()));
QVERIFY(object != nullptr);
- QMetaObject::invokeMethod(object, method.toUtf8());
+ QMetaObject::invokeMethod(object.get(), method.toUtf8());
QQmlComponent *created = object->componentProperty();
if (creationError.isEmpty()) {
@@ -1704,7 +1784,7 @@ void tst_qqmlecmascript::componentCreation()
QObject *expectedParent = reinterpret_cast<QObject *>(quintptr(-1));
if (createdParent == QLatin1String("obj")) {
- expectedParent = object;
+ expectedParent = object.get();
} else if ((createdParent == QLatin1String("null")) || createdParent.isEmpty()) {
expectedParent = nullptr;
}
@@ -2050,7 +2130,7 @@ void tst_qqmlecmascript::functionErrors()
QObject *resource = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>());
warning = url + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function");
- warning = warning.arg(QString::number((quintptr)resource, 16));
+ warning = warning.arg(QString::number(quintptr(resource), 16));
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData()); // we expect a meaningful warning to be printed.
QMetaObject::invokeMethod(object, "retrieveScarceResource");
delete object;
@@ -3124,13 +3204,13 @@ void tst_qqmlecmascript::callQtInvokables()
void tst_qqmlecmascript::resolveClashingProperties()
{
- ClashingNames *o = new ClashingNames();
+ QScopedPointer<ClashingNames> o(new ClashingNames());
QQmlEngine qmlengine;
QV4::ExecutionEngine *engine = qmlengine.handle();
QV4::Scope scope(engine);
- QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o));
+ QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(engine, o.get()));
QV4::ObjectIterator it(scope, object->as<QV4::Object>(), QV4::ObjectIterator::EnumerableOnly);
QV4::ScopedValue name(scope);
QV4::ScopedValue value(scope);
@@ -4575,7 +4655,7 @@ void tst_qqmlecmascript::scarceResources_other()
eo = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>());
QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
expectedWarning = varComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function");
- expectedWarning = expectedWarning.arg(QString::number((quintptr)eo, 16));
+ expectedWarning = expectedWarning.arg(QString::number(quintptr(eo), 16));
QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
QMetaObject::invokeMethod(object, "retrieveScarceResource");
QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
@@ -4649,7 +4729,7 @@ void tst_qqmlecmascript::scarceResources_other()
eo = qobject_cast<ScarceResourceObject*>(QQmlProperty::read(object, "a").value<QObject*>());
QVERIFY(eo->scarceResourceIsDetached()); // should be no other copies of it at this stage.
expectedWarning = variantComponentTwelve.url().toString() + QLatin1String(":16: TypeError: Property 'scarceResource' of object ScarceResourceObject(0x%1) is not a function");
- expectedWarning = expectedWarning.arg(QString::number((quintptr)eo, 16));
+ expectedWarning = expectedWarning.arg(QString::number(quintptr(eo), 16));
QTest::ignoreMessage(QtWarningMsg, qPrintable(expectedWarning)); // we expect a meaningful warning to be printed.
QMetaObject::invokeMethod(object, "retrieveScarceResource");
QVERIFY(!object->property("scarceResourceCopy").isValid()); // due to exception, assignment will NOT have occurred.
@@ -6093,7 +6173,7 @@ void tst_qqmlecmascript::variants()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("variants.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("undefinedVariant").type(), QVariant::Invalid);
@@ -6102,13 +6182,13 @@ void tst_qqmlecmascript::variants()
QCOMPARE(object->property("doubleVariant").type(), QVariant::Double);
QVariant result;
- QMetaObject::invokeMethod(object, "checkNull", Q_RETURN_ARG(QVariant, result));
+ QMetaObject::invokeMethod(object.get(), "checkNull", Q_RETURN_ARG(QVariant, result));
QCOMPARE(result.toBool(), true);
- QMetaObject::invokeMethod(object, "checkUndefined", Q_RETURN_ARG(QVariant, result));
+ QMetaObject::invokeMethod(object.get(), "checkUndefined", Q_RETURN_ARG(QVariant, result));
QCOMPARE(result.toBool(), true);
- QMetaObject::invokeMethod(object, "checkNumber", Q_RETURN_ARG(QVariant, result));
+ QMetaObject::invokeMethod(object.get(), "checkNumber", Q_RETURN_ARG(QVariant, result));
QCOMPARE(result.toBool(), true);
}
@@ -6357,6 +6437,8 @@ void tst_qqmlecmascript::topLevelGeneratorFunction()
QQmlComponent component(&engine, testFileUrl("generatorFunction.qml"));
QScopedPointer<QObject> o {component.create()};
+ if (!o)
+ qDebug() << component.errorString();
QVERIFY(o != nullptr);
// check that generator works correctly in QML
@@ -6998,12 +7080,12 @@ void tst_qqmlecmascript::realToInt()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("realToInt.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
- QMetaObject::invokeMethod(object, "test1");
+ QMetaObject::invokeMethod(object.get(), "test1");
QCOMPARE(object->value(), int(4));
- QMetaObject::invokeMethod(object, "test2");
+ QMetaObject::invokeMethod(object.get(), "test2");
QCOMPARE(object->value(), int(7));
}
@@ -7012,7 +7094,7 @@ void tst_qqmlecmascript::urlProperty()
QQmlEngine engine;
{
QQmlComponent component(&engine, testFileUrl("urlProperty.1.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
object->setStringProperty("http://qt-project.org");
QCOMPARE(object->urlProperty(), QUrl("http://qt-project.org/index.html"));
@@ -7027,7 +7109,7 @@ void tst_qqmlecmascript::urlPropertyWithEncoding()
QQmlEngine engine;
{
QQmlComponent component(&engine, testFileUrl("urlProperty.2.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
object->setStringProperty("http://qt-project.org");
const QUrl encoded = QUrl::fromEncoded("http://qt-project.org/?get%3cDATA%3e", QUrl::TolerantMode);
@@ -7062,7 +7144,7 @@ void tst_qqmlecmascript::dynamicString()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("dynamicString.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
QCOMPARE(object->property("stringProperty").toString(),
QString::fromLatin1("string:Hello World false:0 true:1 uint32:100 int32:-100 double:3.14159 date:2011-02-11 05::30:50!"));
@@ -7072,7 +7154,7 @@ void tst_qqmlecmascript::deleteLaterObjectMethodCall()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("deleteLaterObjectMethodCall.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7080,7 +7162,7 @@ void tst_qqmlecmascript::automaticSemicolon()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("automaticSemicolon.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7088,7 +7170,7 @@ void tst_qqmlecmascript::compatibilitySemicolon()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("compatibilitySemicolon.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7096,7 +7178,7 @@ void tst_qqmlecmascript::incrDecrSemicolon1()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon1.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7104,7 +7186,7 @@ void tst_qqmlecmascript::incrDecrSemicolon2()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon2.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7120,7 +7202,7 @@ void tst_qqmlecmascript::unaryExpression()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("unaryExpression.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -7260,7 +7342,7 @@ void tst_qqmlecmascript::switchStatement()
QQmlEngine engine;
{
QQmlComponent component(&engine, testFileUrl("switchStatement.1.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7283,7 +7365,7 @@ void tst_qqmlecmascript::switchStatement()
{
QQmlComponent component(&engine, testFileUrl("switchStatement.2.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7306,7 +7388,7 @@ void tst_qqmlecmascript::switchStatement()
{
QQmlComponent component(&engine, testFileUrl("switchStatement.3.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7333,7 +7415,7 @@ void tst_qqmlecmascript::switchStatement()
QString warning = component.url().toString() + ":4:5: Unable to assign [undefined] to int";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7357,7 +7439,7 @@ void tst_qqmlecmascript::switchStatement()
{
QQmlComponent component(&engine, testFileUrl("switchStatement.5.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7380,7 +7462,7 @@ void tst_qqmlecmascript::switchStatement()
{
QQmlComponent component(&engine, testFileUrl("switchStatement.6.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
// `object->value()' is the number of executed statements
@@ -7408,7 +7490,7 @@ void tst_qqmlecmascript::withStatement()
{
QUrl url = testFileUrl("withStatement.1.qml");
QQmlComponent component(&engine, url);
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->value(), 123);
@@ -7420,7 +7502,7 @@ void tst_qqmlecmascript::tryStatement()
QQmlEngine engine;
{
QQmlComponent component(&engine, testFileUrl("tryStatement.1.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->value(), 123);
@@ -7428,7 +7510,7 @@ void tst_qqmlecmascript::tryStatement()
{
QQmlComponent component(&engine, testFileUrl("tryStatement.2.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QCOMPARE(object->value(), 321);
@@ -7436,7 +7518,7 @@ void tst_qqmlecmascript::tryStatement()
{
QQmlComponent component(&engine, testFileUrl("tryStatement.3.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->qjsvalue().isUndefined());
@@ -7444,7 +7526,7 @@ void tst_qqmlecmascript::tryStatement()
{
QQmlComponent component(&engine, testFileUrl("tryStatement.4.qml"));
- MyQmlObject *object = qobject_cast<MyQmlObject *>(component.create());
+ QScopedPointer<MyQmlObject> object(qobject_cast<MyQmlObject*>(component.create()));
QVERIFY(object != nullptr);
QVERIFY(object->qjsvalue().isUndefined());
@@ -7585,7 +7667,7 @@ void tst_qqmlecmascript::onDestruction()
// component instance. This shouldn't crash.
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("onDestruction.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
QVERIFY(obj != nullptr);
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
@@ -7926,19 +8008,19 @@ void tst_qqmlecmascript::dateParse()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("date.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
if (object == nullptr)
qDebug() << component.errorString();
QVERIFY(object != nullptr);
QVariant q;
- QMetaObject::invokeMethod(object, "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q));
+ QMetaObject::invokeMethod(object.get(), "test_is_invalid_jsDateTime", Q_RETURN_ARG(QVariant, q));
QVERIFY(q.toBool());
- QMetaObject::invokeMethod(object, "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q));
+ QMetaObject::invokeMethod(object.get(), "test_is_invalid_qtDateTime", Q_RETURN_ARG(QVariant, q));
QVERIFY(q.toBool());
- QMetaObject::invokeMethod(object, "test_rfc2822_date", Q_RETURN_ARG(QVariant, q));
+ QMetaObject::invokeMethod(object.get(), "test_rfc2822_date", Q_RETURN_ARG(QVariant, q));
QCOMPARE(q.toLongLong(), 1379512851000LL);
}
@@ -7947,14 +8029,14 @@ void tst_qqmlecmascript::utcDate()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("utcdate.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
if (object == nullptr)
qDebug() << component.errorString();
QVERIFY(object != nullptr);
QVariant q;
QVariant val = QString::fromLatin1("2014-07-16T23:30:31");
- QMetaObject::invokeMethod(object, "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val));
+ QMetaObject::invokeMethod(object.get(), "check_utc", Q_RETURN_ARG(QVariant, q), Q_ARG(QVariant, val));
QVERIFY(q.toBool());
}
@@ -7963,20 +8045,20 @@ void tst_qqmlecmascript::negativeYear()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("negativeyear.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
if (object == nullptr)
qDebug() << component.errorString();
QVERIFY(object != nullptr);
QVariant q;
- QMetaObject::invokeMethod(object, "check_negative_tostring", Q_RETURN_ARG(QVariant, q));
+ QMetaObject::invokeMethod(object.get(), "check_negative_tostring", Q_RETURN_ARG(QVariant, q));
// Only check for the year. We hope that every language writes the year in arabic numerals and
// in relation to a specific dude's date of birth. We also hope that no language adds a "-2001"
// junk string somewhere in the middle.
QVERIFY(q.toString().indexOf(QStringLiteral("-2001")) != -1);
- QMetaObject::invokeMethod(object, "check_negative_toisostring", Q_RETURN_ARG(QVariant, q));
+ QMetaObject::invokeMethod(object.get(), "check_negative_toisostring", Q_RETURN_ARG(QVariant, q));
QCOMPARE(q.toString().left(16), QStringLiteral("result: -002000-"));
}
@@ -8019,6 +8101,7 @@ void tst_qqmlecmascript::jsOwnedObjectsDeletedOnEngineDestroy()
QCOMPARE(spy1.count(), 1);
QCOMPARE(spy2.count(), 1);
+ deleteObject.deleteNestedObject();
delete object;
}
@@ -8030,7 +8113,7 @@ void tst_qqmlecmascript::updateCall()
QString file("updateCall.qml");
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl(file));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
@@ -8041,7 +8124,7 @@ void tst_qqmlecmascript::numberParsing()
QString file("numberParsing.%1.qml");
file = file.arg(i);
QQmlComponent component(&engine, testFileUrl(file));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
}
for (int i = 1; i < 3; ++i) {
@@ -8224,8 +8307,8 @@ void tst_qqmlecmascript::idsAsLValues()
QString err = QString(QLatin1String("%1:5: Error: left-hand side of assignment operator is not an lvalue")).arg(testFileUrl("idAsLValue.qml").toString());
QQmlComponent component(&engine, testFileUrl("idAsLValue.qml"));
QTest::ignoreMessage(QtWarningMsg, qPrintable(err));
- MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create());
- QVERIFY(!object);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!qobject_cast<MyQmlObject*>(object.get()));
}
void tst_qqmlecmascript::qtbug_34792()
@@ -8440,10 +8523,10 @@ void tst_qqmlecmascript::readUnregisteredQObjectProperty()
qmlRegisterType<ObjectContainer>("Test", 1, 0, "ObjectContainer");
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("accessUnregisteredQObjectProperty.qml"));
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root);
- QMetaObject::invokeMethod(root, "readProperty");
+ QMetaObject::invokeMethod(root.get(), "readProperty");
QCOMPARE(root->property("container").value<ObjectContainer*>()->mGetterCalled, true);
}
@@ -8452,10 +8535,10 @@ void tst_qqmlecmascript::writeUnregisteredQObjectProperty()
qmlRegisterType<ObjectContainer>("Test", 1, 0, "ObjectContainer");
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("accessUnregisteredQObjectProperty.qml"));
- QObject *root = component.create();
+ QScopedPointer<QObject> root(component.create());
QVERIFY(root);
- QMetaObject::invokeMethod(root, "writeProperty");
+ QMetaObject::invokeMethod(root.get(), "writeProperty");
QCOMPARE(root->property("container").value<ObjectContainer*>()->mSetterCalled, true);
}
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.1.qml
index 812242f146..a37461a173 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.2.qml
index a171ee6b28..1dc06ee6ae 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyAggregateEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.1.qml
index de40284452..ea945eebb0 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.2.qml
index 4939087b31..9a4fc53833 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyAggregateVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyComponent.1.qml
index 5cee0341fe..155dbdcb91 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyComponent.2.qml
index 2a13822fab..940d54be90 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.1.qml
index 2f238175fa..46d20e38bb 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.2.qml
index d36e95fec3..ffdb30f072 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyExtendEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.1.qml
index 53dd5a17e9..ca669a9708 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.2.qml
index e5cd7d60de..a93c3b302c 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyExtendVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.1.qml
index d98aef2932..5930e12df6 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.2.qml
index 7f438aa995..8f929c20b2 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyPropertyEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.1.qml
index 83d6226e83..20bde6d0af 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.2.qml
index 98dfb7241b..10ae369459 100644
--- a/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testEmptyPropertyVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testIncubatedComponent.qml b/tests/auto/qml/qqmlengine/data/testIncubatedComponent.qml
index 50af9c4f16..422637fe31 100644
--- a/tests/auto/qml/qqmlengine/data/testIncubatedComponent.qml
+++ b/tests/auto/qml/qqmlengine/data/testIncubatedComponent.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testLoaderComponent.qml b/tests/auto/qml/qqmlengine/data/testLoaderComponent.qml
index a04ca41c26..67d7ddd1c9 100644
--- a/tests/auto/qml/qqmlengine/data/testLoaderComponent.qml
+++ b/tests/auto/qml/qqmlengine/data/testLoaderComponent.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testReloadComponent.qml b/tests/auto/qml/qqmlengine/data/testReloadComponent.qml
index 74442108cd..79d4f29db0 100644
--- a/tests/auto/qml/qqmlengine/data/testReloadComponent.qml
+++ b/tests/auto/qml/qqmlengine/data/testReloadComponent.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testScriptComponent.qml b/tests/auto/qml/qqmlengine/data/testScriptComponent.qml
index b33eb48461..4952a08a6c 100644
--- a/tests/auto/qml/qqmlengine/data/testScriptComponent.qml
+++ b/tests/auto/qml/qqmlengine/data/testScriptComponent.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testTopLevelComponent.qml b/tests/auto/qml/qqmlengine/data/testTopLevelComponent.qml
index 6cf8ec4203..a6a1f4d4d3 100644
--- a/tests/auto/qml/qqmlengine/data/testTopLevelComponent.qml
+++ b/tests/auto/qml/qqmlengine/data/testTopLevelComponent.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testTransientComponent.1.qml b/tests/auto/qml/qqmlengine/data/testTransientComponent.1.qml
index d3e6ffd7cf..c661cb6fe4 100644
--- a/tests/auto/qml/qqmlengine/data/testTransientComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testTransientComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testTransientComponent.2.qml b/tests/auto/qml/qqmlengine/data/testTransientComponent.2.qml
index acb0113e61..8b6c7eda4d 100644
--- a/tests/auto/qml/qqmlengine/data/testTransientComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testTransientComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.1.qml
index a5beede469..8c0596eae4 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.2.qml
index 4c8e52f251..39b604d42f 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEAggregateEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.1.qml
index 983d6e824c..807203b6c7 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.2.qml
index fc8e5a0cd4..100b287cfd 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEAggregateVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEComponent.1.qml
index fcfd05c51f..dddf51b926 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEComponent.2.qml
index f434406eec..fa508f16ac 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.1.qml
index 1dcaec90e6..b36d6ebf14 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.2.qml
index fd7d7e454c..fce617046b 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEExtendEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.1.qml
index d2dab32fc9..39629d47df 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.2.qml
index 813e43896c..a4c947cc17 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEExtendVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.1.qml
index c6f0b7928b..a87372cd27 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.2.qml
index 255138520c..c4b16d8ec9 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEPropertyEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.1.qml
index 0ad59b32d3..a18a88884c 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.2.qml
index 60f72a92fe..eb042e82f8 100644
--- a/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMEPropertyVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.1.qml
index 6c7f959f49..1f97e587e0 100644
--- a/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.2.qml
index 86060c3998..794686494b 100644
--- a/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMETransientEmptyComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.1.qml b/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.1.qml
index c50fd70dec..f442500c7f 100644
--- a/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.1.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.1.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.2.qml b/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.2.qml
index 120d249bc0..d57cd8a739 100644
--- a/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.2.qml
+++ b/tests/auto/qml/qqmlengine/data/testVMETransientVMEComponent.2.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
Item {
property bool success: false
+ required property QtObject componentCache
function reportError(s) { console.warn(s) }
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index aae42e9ebb..2a3b945509 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -424,12 +424,13 @@ void tst_qqmlengine::trimComponentCache()
QQmlEngine engine;
ComponentCacheFunctions componentCache(engine);
- engine.rootContext()->setContextProperty("componentCache", &componentCache);
engine.setIncubationController(&componentCache);
QQmlComponent component(&engine, testFileUrl(file));
QVERIFY2(component.isReady(), qPrintable(component.errorString()));
- QScopedPointer<QObject> object(component.create());
+ QScopedPointer<QObject> object(component.createWithInitialProperties({
+ {"componentCache", QVariant::fromValue(&componentCache)}
+ }));
QVERIFY(object != nullptr);
QCOMPARE(object->property("success").toBool(), true);
}
@@ -511,6 +512,7 @@ void tst_qqmlengine::failedCompilation()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl(file));
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QQmlComponent: Component is not ready");
QVERIFY(!component.isReady());
QScopedPointer<QObject> object(component.create());
QVERIFY(object.isNull());
@@ -601,11 +603,10 @@ void tst_qqmlengine::objectOwnership()
{
QQmlEngine engine;
QQmlComponent c(&engine);
- engine.rootContext()->setContextProperty("test", this);
QQmlEngine::setObjectOwnership(ptr, QQmlEngine::JavaScriptOwnership);
- c.setData("import QtQuick 2.0; Item { property int data: test.createAQObjectForOwnershipTest() ? 0 : 1 }", QUrl());
+ c.setData("import QtQuick 2.0; Item { required property QtObject test; property int data: test.createAQObjectForOwnershipTest() ? 0 : 1 }", QUrl());
QVERIFY(c.isReady());
- QObject *o = c.create();
+ QObject *o = c.createWithInitialProperties( {{"test", QVariant::fromValue(this)}} );
QVERIFY(o != nullptr);
}
QTRY_VERIFY(spy.count());
@@ -616,13 +617,13 @@ void tst_qqmlengine::objectOwnership()
{
QQmlEngine engine;
QQmlComponent c(&engine);
- engine.rootContext()->setContextProperty("test", ptr);
QQmlEngine::setObjectOwnership(ptr, QQmlEngine::JavaScriptOwnership);
- c.setData("import QtQuick 2.0; QtObject { property var object: { var i = test; test ? 0 : 1 } }", QUrl());
+ c.setData("import QtQuick 2.0; QtObject { required property QtObject test; property var object: { var i = test; test ? 0 : 1 } }", QUrl());
QVERIFY(c.isReady());
- QObject *o = c.create();
+ QObject *o = c.createWithInitialProperties({{"test", QVariant::fromValue(ptr)}});
QVERIFY(o != nullptr);
- engine.rootContext()->setContextProperty("test", nullptr);
+ QQmlProperty testProp(o, "test");
+ testProp.write(QVariant::fromValue<QObject*>(nullptr));
}
QTRY_VERIFY(spy.count());
}
@@ -772,6 +773,7 @@ public:
};
Q_DECLARE_METATYPE(QList<QQmlAbstractUrlInterceptor::DataType>);
+
void tst_qqmlengine::urlInterceptor_data()
{
QTest::addColumn<QUrl>("testFile");
@@ -940,14 +942,15 @@ void tst_qqmlengine::cppSignalAndEval()
{
ObjectCaller objectCaller;
QQmlEngine engine;
- engine.rootContext()->setContextProperty(QLatin1String("CallerCpp"), &objectCaller);
+ qmlRegisterSingletonInstance("Test", 1, 0, "CallerCpp", &objectCaller);
QQmlComponent c(&engine);
c.setData("import QtQuick 2.9\n"
+ "import Test 1.0\n"
"Item {\n"
" property var r: 0\n"
" Connections {\n"
" target: CallerCpp;\n"
- " onDoubleReply: {\n"
+ " function onDoubleReply() {\n"
" eval('var z = 1');\n"
" r = a;\n"
" }\n"
@@ -1107,6 +1110,16 @@ void tst_qqmlengine::singletonInstance()
SomeQObjectClass * instance = engine.singletonInstance<SomeQObjectClass*>(cppSingletonTypeId);
QVERIFY(!instance);
}
+
+ {
+ // deleted object
+ auto dayfly = new QObject{};
+ auto id = qmlRegisterSingletonInstance("Vanity", 1, 0, "Dayfly", dayfly);
+ delete dayfly;
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: The registered singleton has already been deleted. Ensure that it outlives the engine.");
+ QObject *instance = engine.singletonInstance<QObject*>(id);
+ QVERIFY(!instance);
+ }
}
void tst_qqmlengine::aggressiveGc()
diff --git a/tests/auto/qml/qqmlincubator/data/requiredProperty.qml b/tests/auto/qml/qqmlincubator/data/requiredProperty.qml
new file mode 100644
index 0000000000..9e355dce72
--- /dev/null
+++ b/tests/auto/qml/qqmlincubator/data/requiredProperty.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.12
+
+Item {
+ required property int requiredProperty
+}
diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
index 8e25079703..756b3b1d7c 100644
--- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
+++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
@@ -70,6 +70,7 @@ private slots:
void selfDelete();
void contextDelete();
void garbageCollection();
+ void requiredProperties();
private:
QQmlIncubationController controller;
@@ -1174,6 +1175,44 @@ void tst_qqmlincubator::garbageCollection()
QVERIFY(weakIncubatorRef.isNullOrUndefined());
}
+void tst_qqmlincubator::requiredProperties()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperty.qml"));
+ QVERIFY(component.isReady());
+ // forceCompletion immediately after creating an asynchronous object completes it
+ QQmlIncubator incubator;
+ incubator.setInitialProperties({{"requiredProperty", 42}});
+ QVERIFY(incubator.isNull());
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isReady());
+ QVERIFY(incubator.object() != nullptr);
+ QCOMPARE(incubator.object()->property("requiredProperty").toInt(), 42);
+
+ delete incubator.object();
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperty.qml"));
+ QVERIFY(component.isReady());
+ // forceCompletion immediately after creating an asynchronous object completes it
+ QQmlIncubator incubator;
+ QVERIFY(incubator.isNull());
+ component.create(incubator);
+ QVERIFY(incubator.isLoading());
+
+ incubator.forceCompletion();
+
+ QVERIFY(incubator.isError());
+ auto error = incubator.errors().first();
+ QVERIFY(error.description().contains(QLatin1String("Required property requiredProperty was not initialized")));
+ QVERIFY(incubator.object() == nullptr);
+ }
+}
+
QTEST_MAIN(tst_qqmlincubator)
#include "tst_qqmlincubator.moc"
diff --git a/tests/auto/qml/qqmlinstantiator/data/createAndRemove.qml b/tests/auto/qml/qqmlinstantiator/data/createAndRemove.qml
index 5dd322b5f5..40e996ee4a 100644
--- a/tests/auto/qml/qqmlinstantiator/data/createAndRemove.qml
+++ b/tests/auto/qml/qqmlinstantiator/data/createAndRemove.qml
@@ -1,18 +1,19 @@
import QtQml 2.1
import QtQuick 2.1
+import Test 1.0
Rectangle {
Instantiator {
objectName: "instantiator1"
- model: model1
+ model: Model1
delegate: QtObject {
property string datum: model.text
}
}
Component.onCompleted: {
- model1.add("Delta");
- model1.add("Gamma");
- model1.add("Beta");
- model1.add("Alpha");
+ Model1.add("Delta");
+ Model1.add("Gamma");
+ Model1.add("Beta");
+ Model1.add("Alpha");
}
}
diff --git a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp
index 9c5e09c77c..84e08c471a 100644
--- a/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp
+++ b/tests/auto/qml/qqmlinstantiator/tst_qqmlinstantiator.cpp
@@ -190,9 +190,9 @@ void tst_qqmlinstantiator::intModelChange()
void tst_qqmlinstantiator::createAndRemove()
{
QQmlEngine engine;
+ QScopedPointer<StringModel> model {new StringModel("model1")};
+ qmlRegisterSingletonInstance("Test", 1, 0, "Model1", model.get());
QQmlComponent component(&engine, testFileUrl("createAndRemove.qml"));
- StringModel *model = new StringModel("model1");
- engine.rootContext()->setContextProperty("model1", model);
QObject *rootObject = component.create();
QVERIFY(rootObject != nullptr);
diff --git a/tests/auto/qml/qqmllanguage/data/alias.17.qml b/tests/auto/qml/qqmllanguage/data/alias.17.qml
new file mode 100644
index 0000000000..a76dd120b6
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.17.qml
@@ -0,0 +1,31 @@
+import QtQuick 2.12
+
+Item {
+ id: root
+ anchors.fill: parent
+ width: 100
+ height: 100
+ property bool success: checkValue === aliasUser.topMargin
+ property int checkValue: 42
+ Rectangle {
+ id: myItem
+ objectName: "myItem"
+ color: "blue"
+ anchors.topMargin: root.checkValue
+ width: 50
+ height: 50
+ Text {text: "source:\n" + myItem.anchors.topMargin}
+ }
+
+ Rectangle {
+ property alias topMargin: myItem.anchors.topMargin
+ id: aliasUser
+ objectName: "aliasUser"
+ color: "red"
+ anchors.left: myItem.right
+ width: 50
+ height: 50
+ Text {objectName: "myText"; text: "alias:\n" + aliasUser.topMargin}
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/fakeDotProperty.errors.txt b/tests/auto/qml/qqmllanguage/data/fakeDotProperty.errors.txt
index 30748234bc..5a144f2db5 100644
--- a/tests/auto/qml/qqmllanguage/data/fakeDotProperty.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/fakeDotProperty.errors.txt
@@ -1 +1 @@
-3:5:Invalid grouped property access
+3:5:Invalid grouped property access: Property "value" with primitive type "int".
diff --git a/tests/auto/qml/qqmllanguage/data/foreignExtended.qml b/tests/auto/qml/qqmllanguage/data/foreignExtended.qml
new file mode 100644
index 0000000000..182d60fd02
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/foreignExtended.qml
@@ -0,0 +1,20 @@
+import QtQml 2.12
+import Test 1.0
+
+QtObject {
+ property Foreign foreign: Foreign {
+ objectName: "foreign"
+ }
+ property Extended extended: Extended {}
+ property ForeignExtended foreignExtended: ForeignExtended {
+ objectName: "foreignExtended"
+ }
+
+ property int extendedBase: extended.base
+
+ property int extendedExtension: extended.extension
+ property int foreignExtendedExtension: foreignExtended.extension
+
+ property string foreignObjectName: foreign.objectName
+ property string foreignExtendedObjectName: foreignExtended.objectName
+}
diff --git a/tests/auto/qml/qqmllanguage/data/fuzzed.2.errors.txt b/tests/auto/qml/qqmllanguage/data/fuzzed.2.errors.txt
index 92ce4c649f..8dca84b34e 100644
--- a/tests/auto/qml/qqmllanguage/data/fuzzed.2.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/fuzzed.2.errors.txt
@@ -1,2 +1 @@
5:1:TetZ$ is not a type
--1:-1:Invalid QML type name "TetZ$"
diff --git a/tests/auto/qml/qqmllanguage/data/invalidGroupedProperty.2.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidGroupedProperty.2.errors.txt
index 810fd31b41..5deec4ccf9 100644
--- a/tests/auto/qml/qqmllanguage/data/invalidGroupedProperty.2.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/invalidGroupedProperty.2.errors.txt
@@ -1 +1 @@
-5:5:Invalid grouped property access
+5:5:Invalid grouped property access: Property "o" with primitive type "int".
diff --git a/tests/auto/qml/qqmllanguage/data/objectValueTypeProperty.errors.txt b/tests/auto/qml/qqmllanguage/data/objectValueTypeProperty.errors.txt
index 945dacf8ab..043f714636 100644
--- a/tests/auto/qml/qqmllanguage/data/objectValueTypeProperty.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/objectValueTypeProperty.errors.txt
@@ -1 +1 @@
-4:18:Can not assign value of type "int" to property "x", expecting an object
+4:18:Can not assign value of type "MyTypeObject" to property "x", expecting "int"
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.1.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.1.qml
new file mode 100644
index 0000000000..dac43c6d88
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.1.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.13
+Item {
+ property var required: 32 // required is still allowed as an identifier for properties
+ function f(required) { // for javascript
+ required = required + required;
+ console.log(required);
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml
new file mode 100644
index 0000000000..4c12c7b602
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.13
+Item {
+ required property int test: 42 // cannot specify value for required property
+}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml
new file mode 100644
index 0000000000..534322215f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.13
+Item {
+ default required property int test // cannot have required default property
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 6956533196..462745eb93 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.cpp
+++ b/tests/auto/qml/qqmllanguage/testtypes.cpp
@@ -57,7 +57,7 @@ void registerTypes()
qmlRegisterType<MyNamespace::MySecondNamespacedType>("Test",1,0,"MySecondNamespacedType");
qmlRegisterUncreatableMetaObject(MyNamespace::staticMetaObject, "Test", 1, 0, "MyNamespace", "Access to enums & flags only");
qmlRegisterType<MyParserStatus>("Test",1,0,"MyParserStatus");
- qmlRegisterType<MyGroupedObject>();
+ qmlRegisterAnonymousType<MyGroupedObject>("Test", 1);
qmlRegisterType<MyRevisionedClass>("Test",1,0,"MyRevisionedClass");
qmlRegisterType<MyRevisionedClass,1>("Test",1,1,"MyRevisionedClass");
qmlRegisterType<MyRevisionedIllegalOverload>("Test",1,0,"MyRevisionedIllegalOverload");
@@ -118,6 +118,8 @@ void registerTypes()
qmlRegisterType<LazyDeferredSubObject>("Test", 1, 0, "LazyDeferredSubObject");
qmlRegisterType<DeferredProperties>("Test", 1, 0, "DeferredProperties");
+
+ qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1);
}
QVariant myCustomVariantTypeConverter(const QString &data)
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 1aab24841a..bfbd3e66f5 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -1420,6 +1420,40 @@ public:
enum class OtherScopedEnum : int { ScopedVal1, ScopedVal2, ScopedVal3 };
};
+class Extension : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int extension READ extension CONSTANT)
+public:
+ Extension(QObject *parent = nullptr) : QObject(parent) {}
+ int extension() const { return 42; }
+};
+
+class Extended : public QObject
+{
+ Q_OBJECT
+ QML_EXTENDED(Extension)
+ QML_NAMED_ELEMENT(Extended)
+ Q_PROPERTY(int base READ base CONSTANT)
+
+public:
+ int base() const { return 43; }
+};
+
+class Foreign
+{
+ Q_GADGET
+ QML_FOREIGN(QObject)
+ QML_NAMED_ELEMENT(Foreign)
+};
+
+class ForeignExtended
+{
+ Q_GADGET
+ QML_FOREIGN(QObject)
+ QML_NAMED_ELEMENT(ForeignExtended)
+ QML_EXTENDED(Extension)
+};
void registerTypes();
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 8adacd8829..e2032c3b86 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -132,6 +132,7 @@ private slots:
void autoComponentCreation();
void autoComponentCreationInGroupProperty();
void propertyValueSource();
+ void requiredProperty();
void attachedProperties();
void dynamicObjects();
void customVariantTypes();
@@ -243,12 +244,11 @@ private slots:
void compositeSingletonModuleQualified();
void compositeSingletonInstantiateError();
void compositeSingletonDynamicPropertyError();
- void compositeSingletonDynamicSignal();
+ void compositeSingletonDynamicSignalAndJavaScriptPragma();
void compositeSingletonQmlRegisterTypeError();
void compositeSingletonQmldirNoPragmaError();
void compositeSingletonQmlDirError();
void compositeSingletonRemote();
- void compositeSingletonJavaScriptPragma();
void compositeSingletonSelectors();
void compositeSingletonRegistered();
void compositeSingletonCircular();
@@ -304,6 +304,8 @@ private slots:
void typeWrapperToVariant();
+ void extendedForeignTypes();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -1634,6 +1636,25 @@ void tst_qqmllanguage::propertyValueSource()
}
}
+void tst_qqmllanguage::requiredProperty()
+{
+ QQmlEngine engine;
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.1.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.2.qml"));
+ QVERIFY(!component.errors().empty());
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.3.qml"));
+ QVERIFY(!component.errors().empty());
+ }
+}
+
void tst_qqmllanguage::attachedProperties()
{
QQmlComponent component(&engine, testFileUrl("attachedProperties.qml"));
@@ -1970,6 +1991,69 @@ void tst_qqmllanguage::aliasProperties()
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
}
+
+ // Alias to grouped property
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.17.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QVERIFY(object->property("success").toBool());
+ }
+
+ // Alias to grouped property updates
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.17.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser"));
+ QVERIFY(aliasUser);
+ QQmlProperty checkValueProp(object.get(), "checkValue");
+ QVERIFY(checkValueProp.isValid());
+ checkValueProp.write(777);
+ QCOMPARE(object->property("checkValue").toInt(), 777);
+ QCOMPARE(aliasUser->property("topMargin").toInt(), 777);
+ }
+
+ // Write to alias to grouped property
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.17.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser"));
+ QVERIFY(aliasUser);
+ QQmlProperty topMarginProp {aliasUser, "topMargin"};
+ QVERIFY(topMarginProp.isValid());
+ topMarginProp.write(777);
+ QObject *myItem = object->findChild<QObject*>(QLatin1String("myItem"));
+ QVERIFY(myItem);
+ auto anchors = myItem->property("anchors").value<QObject*>();
+ QVERIFY(anchors);
+ QCOMPARE(anchors->property("topMargin").toInt(), 777);
+ }
+
+ // Binding to alias to grouped property gets updated
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.17.qml"));
+ VERIFY_ERRORS(0);
+
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QObject *aliasUser = object->findChild<QObject*>(QLatin1String("aliasUser"));
+ QVERIFY(aliasUser);
+ QQmlProperty topMarginProp {aliasUser, "topMargin"};
+ QVERIFY(topMarginProp.isValid());
+ topMarginProp.write(20);
+ QObject *myText = object->findChild<QObject*>(QLatin1String("myText"));
+ QVERIFY(myText);
+ auto text = myText->property("text").toString();
+ QCOMPARE(text, "alias:\n20");
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist
@@ -2500,7 +2584,15 @@ void tst_qqmllanguage::testType(const QString& qml, const QString& type, const Q
VERIFY_ERRORS(0);
QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QCOMPARE(QString(object->metaObject()->className()), type);
+ const QMetaObject *meta = object->metaObject();
+ for (; meta; meta = meta->superClass()) {
+ const QString className(meta->className());
+ if (!className.contains("_QMLTYPE_") && !className.contains("_QML_")) {
+ QCOMPARE(className, type);
+ break;
+ }
+ }
+ QVERIFY(meta != nullptr);
}
engine.setImportPathList(defaultImportPathList);
@@ -4043,10 +4135,12 @@ void tst_qqmllanguage::implicitImportsLast()
VERIFY_ERRORS(0);
QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QVERIFY(QString(object->metaObject()->className()).startsWith(QLatin1String("QQuickMouseArea")));
+ QVERIFY(QString(object->metaObject()->superClass()->superClass()->className())
+ .startsWith(QLatin1String("QQuickMouseArea")));
QObject* object2 = object->property("item").value<QObject*>();
QVERIFY(object2 != nullptr);
- QCOMPARE(QString(object2->metaObject()->className()), QLatin1String("QQuickRectangle"));
+ QCOMPARE(QString(object2->metaObject()->superClass()->className()),
+ QLatin1String("QQuickRectangle"));
engine.setImportPathList(defaultImportPathList);
}
@@ -4267,16 +4361,35 @@ void tst_qqmllanguage::compositeSingletonDynamicPropertyError()
VERIFY_ERRORS(0);
}
-// Having a composite singleton type as dynamic signal parameter succeeds
-// (like C++ singleton)
-void tst_qqmllanguage::compositeSingletonDynamicSignal()
+void tst_qqmllanguage::compositeSingletonDynamicSignalAndJavaScriptPragma()
{
- QQmlComponent component(&engine, testFileUrl("singletonTest11.qml"));
- VERIFY_ERRORS(0);
- QScopedPointer<QObject> o(component.create());
- QVERIFY(o != nullptr);
+ {
+ // Having a composite singleton type as dynamic signal parameter succeeds
+ // (like C++ singleton)
- verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", -55);
+ QQmlComponent component(&engine, testFileUrl("singletonTest11.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o != nullptr);
+
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", -55);
+ }
+ {
+ // Load a composite singleton type and a javascript file that has .pragma library
+ // in it. This will make sure that the javascript .pragma does not get mixed with
+ // the pragma Singleton changes.
+
+ QQmlComponent component(&engine, testFileUrl("singletonTest16.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o != nullptr);
+
+ // The value1 that is read from the SingletonType was changed from 125 to 99
+ // above. As the type is a singleton and
+ // the engine has not been destroyed, we just retrieve the old instance and
+ // the value is still 99.
+ verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", 333);
+ }
}
// Use qmlRegisterType to register a qml composite type with pragma Singleton defined in it.
@@ -4328,23 +4441,6 @@ void tst_qqmllanguage::compositeSingletonRemote()
verifyCompositeSingletonPropertyValues(o.data(), "value1", 525, "value2", 355);
}
-// Load a composite singleton type and a javascript file that has .pragma library
-// in it. This will make sure that the javascript .pragma does not get mixed with
-// the pragma Singleton changes.
-void tst_qqmllanguage::compositeSingletonJavaScriptPragma()
-{
- QQmlComponent component(&engine, testFileUrl("singletonTest16.qml"));
- VERIFY_ERRORS(0);
- QScopedPointer<QObject> o(component.create());
- QVERIFY(o != nullptr);
-
- // The value1 that is read from the SingletonType was changed from 125 to 99
- // in compositeSingletonDynamicSignal() above. As the type is a singleton and
- // the engine has not been destroyed, we just retrieve the old instance and
- // the value is still 99.
- verifyCompositeSingletonPropertyValues(o.data(), "value1", 99, "value2", 333);
-}
-
// Reads values from a Singleton accessed through selectors.
void tst_qqmllanguage::compositeSingletonSelectors()
{
@@ -5030,7 +5126,6 @@ void tst_qqmllanguage::instanceof()
if (QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomRectangle") ||
QTest::currentDataTag() == QLatin1String("customRectangleWithPropInstance instanceof CustomImport.CustomRectangle"))
- QEXPECT_FAIL("", "QTBUG-58477: QML type rules are a little lax", Continue);
QCOMPARE(returnValue, expectedValue.toBool());
} else {
QVERIFY(expr.hasError());
@@ -5066,7 +5161,8 @@ void tst_qqmllanguage::accessDeletedObject()
{
QQmlEngine engine;
- engine.rootContext()->setContextProperty("objectCreator", new ObjectCreator);
+ QScopedPointer<ObjectCreator> creator(new ObjectCreator);
+ engine.rootContext()->setContextProperty("objectCreator", creator.get());
QQmlComponent component(&engine, testFileUrl("accessDeletedObject.qml"));
VERIFY_ERRORS(0);
@@ -5163,6 +5259,21 @@ void tst_qqmllanguage::typeWrapperToVariant()
QVERIFY(target);
}
+void tst_qqmllanguage::extendedForeignTypes()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("foreignExtended.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+
+ QCOMPARE(o->property("extendedBase").toInt(), 43);
+ QCOMPARE(o->property("extendedExtension").toInt(), 42);
+ QCOMPARE(o->property("foreignExtendedExtension").toInt(), 42);
+ QCOMPARE(o->property("foreignObjectName").toString(), QLatin1String("foreign"));
+ QCOMPARE(o->property("foreignExtendedObjectName").toString(), QLatin1String("foreignExtended"));
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 77ab0ecbc0..75a932b6f4 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -128,6 +128,8 @@ private slots:
void qobjectTrackerForDynamicModelObjects();
void crash_append_empty_array();
void dynamic_roles_crash_QTBUG_38907();
+ void nestedListModelIteration();
+ void undefinedAppendShouldCauseError();
};
bool tst_qqmllistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1667,6 +1669,61 @@ void tst_qqmllistmodel::dynamic_roles_crash_QTBUG_38907()
QVERIFY(retVal.toBool());
}
+void tst_qqmllistmodel::nestedListModelIteration()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg ,R"({"subItems":[{"a":1,"b":0,"c":0},{"a":0,"b":2,"c":0},{"a":0,"b":0,"c":3}]})");
+ component.setData(
+ R"(import QtQuick 2.5
+ Item {
+ visible: true
+ width: 640
+ height: 480
+ ListModel {
+ id : model
+ }
+ Component.onCompleted: {
+ var tempData = {
+ subItems: [{a: 1}, {b: 2}, {c: 3}]
+ }
+ model.insert(0, tempData)
+ console.log(JSON.stringify(model.get(0)))
+ }
+ })",
+ QUrl());
+ QScopedPointer<QObject>(component.create());
+}
+
+// QTBUG-63569
+void tst_qqmllistmodel::undefinedAppendShouldCauseError()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(
+ R"(import QtQuick 2.5
+ Item {
+ width: 640
+ height: 480
+ ListModel {
+ id : model
+ }
+ Component.onCompleted: {
+ var tempData = {
+ faulty: undefined
+ }
+ model.insert(0, tempData)
+ tempData.faulty = null
+ model.insert(0, tempData)
+ }
+ })",
+ QUrl());
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: faulty is undefined. Adding an object with a undefined member does not create a role for it.");
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "<Unknown File>: faulty is null. Adding an object with a null member does not create a role for it.");
+ QScopedPointer<QObject>(component.create());
+}
+
+
QTEST_MAIN(tst_qqmllistmodel)
#include "tst_qqmllistmodel.moc"
diff --git a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
index 199f7bc7e4..8efaedf5b5 100644
--- a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
+++ b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
@@ -87,7 +87,7 @@ public:
void tst_qqmllistreference::initTestCase()
{
QQmlDataTest::initTestCase();
- qmlRegisterType<TestType>();
+ qmlRegisterAnonymousType<TestType>("Test", 1);
}
void tst_qqmllistreference::qmllistreference()
diff --git a/tests/auto/qml/qqmlmoduleplugin/data/multiSingleton.qml b/tests/auto/qml/qqmlmoduleplugin/data/multiSingleton.qml
new file mode 100644
index 0000000000..2fc2e9f076
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/data/multiSingleton.qml
@@ -0,0 +1,6 @@
+import org.qtproject.ModuleWithQmlSingleton 1.0
+import QtQuick 2.0
+
+Item {
+ Component.onCompleted: MySingleton
+}
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml
new file mode 100644
index 0000000000..258667be18
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml
@@ -0,0 +1,17 @@
+pragma Singleton
+import QtQuick 2.0
+import Test 1.0
+
+QtObject {
+ property Loader _loader: Loader {
+ source: "internal/InternalType.qml"
+ }
+
+ Component.onCompleted: {
+ if (Tracker.objectName === "first")
+ Tracker.objectName = "second"
+ else
+ Tracker.objectName = "first"
+ //console.log("created singleton", this)
+ }
+}
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton2.qml b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton2.qml
new file mode 100644
index 0000000000..9be34eb061
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton2.qml
@@ -0,0 +1,6 @@
+pragma Singleton
+import QtQuick 2.0
+import org.qtproject.ModuleWithQmlSingleton 1.0
+import "."
+
+QtObject {}
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/internal/InternalType.qml b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/internal/InternalType.qml
new file mode 100644
index 0000000000..4a8badefd2
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/internal/InternalType.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import ".."
+
+QtObject {
+ Component.onCompleted: MySingleton
+}
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/moduleWithQmlSingleton.pro b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/moduleWithQmlSingleton.pro
new file mode 100644
index 0000000000..b16e0743c8
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/moduleWithQmlSingleton.pro
@@ -0,0 +1,18 @@
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = plugin.cpp
+QT = core qml
+DESTDIR = ../imports/org/qtproject/ModuleWithQmlSingleton
+
+QT += core-private gui-private qml-private
+
+IMPORT_FILES = \
+ qmldir \
+ MySingleton.qml \
+ MySingleton2.qml
+
+include (../../../shared/imports.pri)
+
+subfiles.files = internal/InternalType.qml
+subfiles.path = $$DESTDIR/internal
+COPIES += subfiles
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/plugin.cpp
new file mode 100644
index 0000000000..6329927c34
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/plugin.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtQml/qqmlextensionplugin.h>
+#include <QtQml/qqml.h>
+#include <QDir>
+#include <QDebug>
+
+class MyPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+
+public:
+ MyPlugin() {}
+
+ void registerTypes(const char *uri)
+ {
+ Q_ASSERT(QLatin1String(uri) == "org.qtproject.ModuleWithQmlSingleton");
+ qmlRegisterSingletonType(baseUrl().resolved(QUrl("ModuleWithQmlSingleton/MySingleton.qml")), uri, 1, 0, "MySingleton");
+ qmlRegisterSingletonType(baseUrl().resolved(QUrl("ModuleWithQmlSingleton/MySingleton2.qml")), uri, 1, 0, "MySingleton2");
+ }
+};
+
+#include "plugin.moc"
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/qmldir b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/qmldir
new file mode 100644
index 0000000000..3483f80ab1
--- /dev/null
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/qmldir
@@ -0,0 +1,2 @@
+module org.qtproject.ModuleWithQmlSingleton
+plugin moduleWithQmlSingleton
diff --git a/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp
index ae8c231aab..bb5bb00adb 100644
--- a/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp
@@ -47,9 +47,9 @@ public:
void registerTypes(const char *uri)
{
- // Because the module is protected, this plugin should never be loaded
+ // The module is protected. The plugin can still be loaded, but it cannot register
+ // any types.
Q_UNUSED(uri);
- Q_ASSERT(0);
}
};
diff --git a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
index ae13a041cc..44b3ab14e6 100644
--- a/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
+++ b/tests/auto/qml/qqmlmoduleplugin/qqmlmoduleplugin.pro
@@ -20,7 +20,8 @@ SUBDIRS =\
plugin/childplugin\
plugin.2/childplugin\
plugin.2.1/childplugin\
- plugin.2.2
+ plugin.2.2\
+ moduleWithQmlSingleton
tst_qqmlmoduleplugin_pro.depends += plugin
SUBDIRS += tst_qqmlmoduleplugin.pro
diff --git a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index 82aa265465..f15d53d022 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -82,6 +82,7 @@ private slots:
void importsChildPlugin2();
void importsChildPlugin21();
void parallelPluginImport();
+ void multiSingleton();
private:
QString m_importsDirectory;
@@ -627,7 +628,7 @@ void tst_qqmlmoduleplugin::importStrictModule_data()
<< "import org.qtproject.NonstrictModule 1.0\n"
"MyPluginType {}"
<< "Module 'org.qtproject.NonstrictModule' does not contain a module identifier directive - it cannot be protected from external registrations."
- << ":1:1: plugin cannot be loaded for module \"org.qtproject.NonstrictModule\": Cannot install element 'MyPluginType' into protected namespace 'org.qtproject.StrictModule'";
+ << ":1:1: plugin cannot be loaded for module \"org.qtproject.NonstrictModule\": Cannot install element 'MyPluginType' into protected module 'org.qtproject.StrictModule' version '1'";
QTest::newRow("non-strict preemption")
<< "import org.qtproject.PreemptiveModule 1.0\n"
@@ -791,6 +792,20 @@ void tst_qqmlmoduleplugin::parallelPluginImport()
worker.wait();
}
+void tst_qqmlmoduleplugin::multiSingleton()
+{
+ QQmlEngine engine;
+ QObject obj;
+ qmlRegisterSingletonInstance("Test", 1, 0, "Tracker", &obj);
+ engine.addImportPath(m_importsDirectory);
+ QQmlComponent component(&engine, testFileUrl("multiSingleton.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != nullptr);
+ QCOMPARE(obj.objectName(), QLatin1String("first"));
+ delete object;
+}
+
+
QTEST_MAIN(tst_qqmlmoduleplugin)
#include "tst_qqmlmoduleplugin.moc"
diff --git a/tests/auto/qml/qqmlnotifier/data/connectnotify.qml b/tests/auto/qml/qqmlnotifier/data/connectnotify.qml
index 35226ee5ab..34e70e6afe 100644
--- a/tests/auto/qml/qqmlnotifier/data/connectnotify.qml
+++ b/tests/auto/qml/qqmlnotifier/data/connectnotify.qml
@@ -3,6 +3,7 @@ import Test 1.0
Item {
id: root
+ required property ExportedClass exportedObject
ExportedClass {
id: exportedClass
objectName: "exportedClass"
@@ -22,7 +23,7 @@ Item {
}
property int foo: exportedClass.qmlObjectProp
- property int baz: _exportedObject.cppObjectProp
+ property int baz: exportedObject.cppObjectProp
// v4 bindings that could share a subscription. They don't, though, and the code
// relies on that
diff --git a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
index de762d66c5..836b94ad45 100644
--- a/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
+++ b/tests/auto/qml/qqmlnotifier/tst_qqmlnotifier.cpp
@@ -185,8 +185,7 @@ void tst_qqmlnotifier::createObjects()
QQmlComponent component(&engine, testFileUrl("connectnotify.qml"));
exportedObject = new ExportedClass();
exportedObject->setObjectName("exportedObject");
- engine.rootContext()->setContextProperty("_exportedObject", exportedObject);
- root = component.create();
+ root = component.createWithInitialProperties({{"exportedObject", QVariant::fromValue(exportedObject)}});
QVERIFY(root != nullptr);
exportedClass = qobject_cast<ExportedClass *>(
@@ -324,12 +323,12 @@ void tst_qqmlnotifier::lotsOfBindings()
TestObject o;
QQmlEngine *e = new QQmlEngine;
- e->rootContext()->setContextProperty(QStringLiteral("test"), &o);
+ qmlRegisterSingletonInstance("Test", 1, 0, "Test", &o);
QList<QQmlComponent *> components;
for (int i = 0; i < 20000; ++i) {
QQmlComponent *component = new QQmlComponent(e);
- component->setData("import QtQuick 2.0; Item { width: test.a; }", QUrl());
+ component->setData("import QtQuick 2.0; import Test 1.0; Item {width: Test.a; }", QUrl());
component->create(e->rootContext());
components.append(component);
}
diff --git a/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml b/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml
new file mode 100644
index 0000000000..d23ea43e74
--- /dev/null
+++ b/tests/auto/qml/qqmlpromise/data/promisehandlerthrows.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.12
+
+Item {
+ id: root
+ property string errorMessage
+ Component.onCompleted: () => {
+ let prom = Promise.reject("Some error")
+ .then(
+ o => {console.log("Never reached");},
+ err => {
+ console.log("Rethrowing err");
+ throw err;
+ }
+ )
+ .catch(err => root.errorMessage = err)
+ }
+}
diff --git a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp
index 41850d0263..b430434526 100644
--- a/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp
+++ b/tests/auto/qml/qqmlpromise/tst_qqmlpromise.cpp
@@ -83,6 +83,7 @@ private slots:
void then_reject_non_callable();
void then_resolve_multiple_then();
void promiseChain();
+ void promiseHandlerThrows();
private:
void execute_test(QString testName);
@@ -285,6 +286,17 @@ void tst_qqmlpromise::promiseChain()
}
+void tst_qqmlpromise::promiseHandlerThrows()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("promisehandlerthrows.qml"));
+ QVERIFY(component.isReady());
+ QTest::ignoreMessage(QtDebugMsg, "Rethrowing err");
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(root);
+ QTRY_VERIFY(root->property("errorMessage") == QLatin1String("Some error"));
+}
+
QTEST_MAIN(tst_qqmlpromise)
diff --git a/tests/auto/qml/qqmlproperty/data/aliasToBinding.qml b/tests/auto/qml/qqmlproperty/data/aliasToBinding.qml
new file mode 100644
index 0000000000..54f9e3f944
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/data/aliasToBinding.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.7
+
+Item {
+ id: _window
+ property bool userFontStrikeout: true
+
+ Component.onCompleted: {
+ _box.font.strikeout = Qt.binding(function() { return _window.userFontStrikeout; });
+ }
+
+ Rectangle {
+ id: _box
+ width: 100
+ height: 100
+ property alias font: _text.font
+
+ Text {
+ id: _text
+ anchors.fill: parent
+ text: "Text"
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmlproperty/data/assignEmptyVariantMap.qml b/tests/auto/qml/qqmlproperty/data/assignEmptyVariantMap.qml
index a9e51c1255..440f07ac87 100644
--- a/tests/auto/qml/qqmlproperty/data/assignEmptyVariantMap.qml
+++ b/tests/auto/qml/qqmlproperty/data/assignEmptyVariantMap.qml
@@ -1,5 +1,6 @@
import QtQuick 2.0
Item {
+ required property QtObject o
Component.onCompleted: { o.variantMap = {}; }
}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 67da768f73..1a5927fa74 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -35,6 +35,9 @@
#include <private/qqmlboundsignal_p.h>
#include <QtCore/qfileinfo.h>
#include <QtCore/qdir.h>
+#if QT_CONFIG(regularexpression)
+#include <QtCore/qregularexpression.h>
+#endif
#include <QtCore/private/qobject_p.h>
#include "../../shared/util.h"
@@ -150,6 +153,8 @@ private slots:
void floatToStringPrecision();
void copy();
+
+ void bindingToAlias();
private:
QQmlEngine engine;
};
@@ -1989,11 +1994,9 @@ void tst_qqmlproperty::assignEmptyVariantMap()
QCOMPARE(o.variantMap().count(), 1);
QCOMPARE(o.variantMap().isEmpty(), false);
- QQmlContext context(&engine);
- context.setContextProperty("o", &o);
QQmlComponent component(&engine, testFileUrl("assignEmptyVariantMap.qml"));
- QObject *obj = component.create(&context);
+ QObject *obj = component.createWithInitialProperties({{"o", QVariant::fromValue(&o)}});
QVERIFY(obj);
QCOMPARE(o.variantMap().count(), 0);
@@ -2015,9 +2018,13 @@ void tst_qqmlproperty::warnOnInvalidBinding()
expectedWarning = testUrl.toString() + QString::fromLatin1(":7:5: Unable to assign QQuickText to QQuickRectangle");
QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+#if QT_CONFIG(regularexpression)
// V8 error message for invalid binding to anchor
- expectedWarning = testUrl.toString() + QString::fromLatin1(":14:9: Unable to assign QQuickItem_QML_8 to QQuickAnchorLine");
- QTest::ignoreMessage(QtWarningMsg, expectedWarning.toLatin1().constData());
+ const QRegularExpression warning(
+ "^" + testUrl.toString()
+ + ":14:9: Unable to assign QQuickItem_QML_\\d+ to QQuickAnchorLine$");
+ QTest::ignoreMessage(QtWarningMsg, warning);
+#endif
QQmlComponent component(&engine, testUrl);
QObject *obj = component.create();
@@ -2123,6 +2130,15 @@ void tst_qqmlproperty::initTestCase()
qmlRegisterType<MyContainer>("Test",1,0,"MyContainer");
}
+// QTBUG-60908
+void tst_qqmlproperty::bindingToAlias()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("aliasToBinding.qml"));
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+}
+
QTEST_MAIN(tst_qqmlproperty)
#include "tst_qqmlproperty.moc"
diff --git a/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml b/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml
new file mode 100644
index 0000000000..9559bc0b5f
--- /dev/null
+++ b/tests/auto/qml/qqmlpropertycache/data/SpecialObject1.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ readonly property bool fakeProperty: false
+}
diff --git a/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml b/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml
new file mode 100644
index 0000000000..ed4ad04fef
--- /dev/null
+++ b/tests/auto/qml/qqmlpropertycache/data/SpecialObject2.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ objectName: "special"
+}
diff --git a/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml b/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml
new file mode 100644
index 0000000000..5e1ea233b9
--- /dev/null
+++ b/tests/auto/qml/qqmlpropertycache/data/noDuckType.qml
@@ -0,0 +1,7 @@
+import QtQml 2.9
+
+QtObject {
+ property SpecialObject1 obj1: SpecialObject1 {}
+ property SpecialObject2 obj2: SpecialObject2 {}
+ property string result: (obj1 instanceof SpecialObject2) ? "bad" : "good"
+}
diff --git a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
index 9a1e4667dd..c9e92cd3c9 100644
--- a/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
+++ b/tests/auto/qml/qqmlpropertycache/tst_qqmlpropertycache.cpp
@@ -54,6 +54,7 @@ private slots:
void metaObjectSize_data();
void metaObjectSize();
void metaObjectChecksum();
+ void metaObjectsForRootElements();
private:
QQmlEngine engine;
@@ -543,4 +544,14 @@ void tst_qqmlpropertycache::metaObjectChecksum()
}
}
+void tst_qqmlpropertycache::metaObjectsForRootElements()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("noDuckType.qml"));
+ QVERIFY(c.isReady());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(!obj.isNull());
+ QCOMPARE(obj->property("result").toString(), QString::fromLatin1("good"));
+}
+
QTEST_MAIN(tst_qqmlpropertycache)
diff --git a/tests/auto/qml/qqmlqt/data/formatting.qml b/tests/auto/qml/qqmlqt/data/formatting.qml
index 7a462c8eeb..f2d1e1b5c8 100644
--- a/tests/auto/qml/qqmlqt/data/formatting.qml
+++ b/tests/auto/qml/qqmlqt/data/formatting.qml
@@ -41,4 +41,9 @@ QtObject {
property string err_dateTime1: Qt.formatDateTime()
property string err_dateTime2: Qt.formatDateTime(new Date, new Object)
+
+ property var qdate
+ property var qtime
+ property var qdatetime
+ property var qvariant
}
diff --git a/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml b/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml
index 9d73640c87..65732442af 100644
--- a/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml
+++ b/tests/auto/qml/qqmlqt/data/timeRoundtrip.qml
@@ -1,6 +1,8 @@
import QtQuick 2.0
+import Test 1.0
QtObject {
+ required property TimeProvider tp
Component.onCompleted: {
var t = tp.time;
tp.time = t;
diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
index 2d8115e867..15ef31464b 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -777,10 +777,6 @@ void tst_qqmlqt::dateTimeFormatting()
QQmlEngine eng;
- eng.rootContext()->setContextProperty("qdate", date);
- eng.rootContext()->setContextProperty("qtime", time);
- eng.rootContext()->setContextProperty("qdatetime", dateTime);
-
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
@@ -794,7 +790,11 @@ void tst_qqmlqt::dateTimeFormatting()
foreach (const QString &warning, warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.create();
+ QObject *object = component.createWithInitialProperties({
+ {"qdate", date},
+ {"qtime", time},
+ {"qdatetime", dateTime}
+ });
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
@@ -853,7 +853,6 @@ void tst_qqmlqt::dateTimeFormattingVariants()
QFETCH(QStringList, expectedResults);
QQmlEngine eng;
- eng.rootContext()->setContextProperty("qvariant", variant);
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
@@ -867,7 +866,7 @@ void tst_qqmlqt::dateTimeFormattingVariants()
foreach (const QString &warning, warnings)
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QObject *object = component.create();
+ QObject *object = component.createWithInitialProperties({{"qvariant", variant}});
QVERIFY2(component.errorString().isEmpty(), qPrintable(component.errorString()));
QVERIFY(object != nullptr);
@@ -1174,6 +1173,7 @@ void tst_qqmlqt::qtObjectContents()
class TimeProvider: public QObject
{
Q_OBJECT
+ QML_NAMED_ELEMENT(TimeProvider)
Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY timeChanged)
public:
@@ -1254,13 +1254,14 @@ void tst_qqmlqt::timeRoundtrip()
TimeZoneSwitch tzs(QTest::currentDataTag());
QFETCH(QTime, time);
+ qmlRegisterTypesAndRevisions<TimeProvider>("Test", 1);
TimeProvider tp(time);
QQmlEngine eng;
- eng.rootContext()->setContextProperty(QLatin1String("tp"), &tp);
+ //qmlRegisterSingletonInstance("Test", 1, 0, "TimeProvider", &tp);
QQmlComponent component(&eng, testFileUrl("timeRoundtrip.qml"));
- QObject *obj = component.create();
+ QObject *obj = component.createWithInitialProperties({{"tp", QVariant::fromValue(&tp)}});
QVERIFY(obj != nullptr);
// QML reads m_getTime and saves the result as m_putTime; this should come out the same, without
diff --git a/tests/auto/qml/qqmltranslation/data/mylibrary.js b/tests/auto/qml/qqmltranslation/data/mylibrary.js
new file mode 100644
index 0000000000..5903db3b4b
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/mylibrary.js
@@ -0,0 +1,5 @@
+Qt.include("nested_js_translation.js")
+
+function translation_success() {
+ return qsTr("English in mylibrary");
+}
diff --git a/tests/auto/qml/qqmltranslation/data/nested_js_translation.js b/tests/auto/qml/qqmltranslation/data/nested_js_translation.js
new file mode 100644
index 0000000000..336cdedfea
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/nested_js_translation.js
@@ -0,0 +1,3 @@
+function translation_fail() {
+ return qsTr("English in translation")
+}
diff --git a/tests/auto/qml/qqmltranslation/data/preferjs.qml b/tests/auto/qml/qqmltranslation/data/preferjs.qml
new file mode 100644
index 0000000000..040fa12e4e
--- /dev/null
+++ b/tests/auto/qml/qqmltranslation/data/preferjs.qml
@@ -0,0 +1,8 @@
+import QtQml 2.12
+
+import "mylibrary.js" as Lib
+
+QtObject {
+ property string german1: Lib.translation_fail()
+ property string german2: Lib.translation_success()
+}
diff --git a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
index dcfe914af6..a75a00bd01 100644
--- a/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
+++ b/tests/auto/qml/qqmltranslation/tst_qqmltranslation.cpp
@@ -46,6 +46,7 @@ private slots:
void translation();
void idTranslation();
void translationChange();
+ void preferJSContext();
};
void tst_qqmltranslation::translation_data()
@@ -175,6 +176,10 @@ class DummyTranslator : public QTranslator
Q_UNUSED(n);
if (!qstrcmp(sourceText, "translate me"))
return QString::fromUtf8("xxx");
+ if (!qstrcmp(sourceText, "English in mylibrary") && !qstrcmp(context, "mylibrary"))
+ return QString::fromUtf8("Deutsch in mylibrary");
+ if (!qstrcmp(sourceText, "English in translation") && !qstrcmp(context, "nested_js_translation"))
+ return QString::fromUtf8("Deutsch in Setzung");
return QString();
}
@@ -213,6 +218,24 @@ void tst_qqmltranslation::translationChange()
QCoreApplication::removeTranslator(&translator);
}
+void tst_qqmltranslation::preferJSContext()
+{
+ DummyTranslator translator;
+ QCoreApplication::installTranslator(&translator);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("preferjs.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QCOMPARE(object->property("german1").toString(),
+ QStringLiteral("Deutsch in Setzung"));
+ QCOMPARE(object->property("german2").toString(),
+ QStringLiteral("Deutsch in mylibrary"));
+
+ QCoreApplication::removeTranslator(&translator);
+}
+
QTEST_MAIN(tst_qqmltranslation)
#include "tst_qqmltranslation.moc"
diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml
new file mode 100644
index 0000000000..28521e3af2
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/BaseStyle.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.6
+
+Item {
+
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml
new file mode 100644
index 0000000000..b20a2def11
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/Handler.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.6
+import Com.Orga 1.0
+
+Rectangle {
+ color: Style.name
+ Text {text: "Hello world!"}
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir
new file mode 100644
index 0000000000..368cb65b35
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Handlers/qmldir
@@ -0,0 +1,2 @@
+module Com.Orga.Handlers
+Handler 1.0 Handler.qml
diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml
new file mode 100644
index 0000000000..7951f5e768
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/Style.qml
@@ -0,0 +1,6 @@
+pragma Singleton
+import QtQuick 2.6
+
+BaseStyle {
+ property color name: "black"
+}
diff --git a/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir b/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir
new file mode 100644
index 0000000000..9c5560b323
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/Com/Orga/qmldir
@@ -0,0 +1,2 @@
+singleton Style 1.0 Style.qml
+BaseStyle 1.0 BaseStyle.qml
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 63a43eebad..07f67c7843 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -60,6 +60,7 @@ private slots:
void implicitComponentModule();
void qrcRootPathUrl();
void implicitImport();
+ void compositeSingletonCycle();
private:
void checkSingleton(const QString & dataDirectory);
@@ -443,7 +444,7 @@ void tst_QQMLTypeLoader::redirect()
component.loadUrl(server.urlString("/Load.qml"), QQmlComponent::Asynchronous);
QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString()));
- QObject *object = component.create();
+ QScopedPointer<QObject> object {component.create()};
QTRY_COMPARE(object->property("xy").toInt(), 323232);
}
@@ -539,6 +540,23 @@ void tst_QQMLTypeLoader::implicitImport()
QVERIFY(!obj.isNull());
}
+void tst_QQMLTypeLoader::compositeSingletonCycle()
+{
+ TestHTTPServer server;
+ QVERIFY2(server.listen(), qPrintable(server.errorString()));
+ QVERIFY(server.serveDirectory(dataDirectory()));
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ engine.addImportPath(server.baseUrl().toString());
+ component.loadUrl(server.urlString("Com/Orga/Handlers/Handler.qml"), QQmlComponent::Asynchronous);
+ QTRY_VERIFY2(component.isReady(), qPrintable(component.errorString()));
+
+ QScopedPointer<QObject> object {component.create()};
+ QVERIFY(object);
+ QCOMPARE(qvariant_cast<QColor>(object->property("color")), QColorConstants::Black);
+}
+
QTEST_MAIN(tst_QQMLTypeLoader)
#include "tst_qqmltypeloader.moc"
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/data/userType.qml b/tests/auto/qml/qqmlvaluetypeproviders/data/userType.qml
index d2f748c4c4..2aa03ed39f 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/data/userType.qml
+++ b/tests/auto/qml/qqmlvaluetypeproviders/data/userType.qml
@@ -2,6 +2,7 @@ import QtQuick 2.0
import Test 1.0
Item {
+ required property TestValueExporter testValueExporter
property bool success: false
// Test user value type stored as both var and variant
diff --git a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
index 22074602b7..b44889798c 100644
--- a/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
+++ b/tests/auto/qml/qqmlvaluetypeproviders/tst_qqmlvaluetypeproviders.cpp
@@ -256,6 +256,7 @@ class TestValueExporter : public QObject
{
Q_OBJECT
Q_PROPERTY(TestValue testValue READ testValue WRITE setTestValue)
+ QML_NAMED_ELEMENT(TestValueExporter)
public:
TestValue testValue() const { return m_testValue; }
void setTestValue(const TestValue &v) { m_testValue = v; }
@@ -275,15 +276,14 @@ void tst_qqmlvaluetypeproviders::userType()
qRegisterMetaType<TestValue>();
QMetaType::registerComparators<TestValue>();
- qmlRegisterType<TestValueExporter>("Test", 1, 0, "TestValueExporter");
+ qmlRegisterTypesAndRevisions<TestValueExporter>("Test", 1);
TestValueExporter exporter;
QQmlEngine e;
- e.rootContext()->setContextProperty("testValueExporter", &exporter);
QQmlComponent component(&e, testFileUrl("userType.qml"));
- QScopedPointer<QObject> obj(component.create());
+ QScopedPointer<QObject> obj(component.createWithInitialProperties({{"testValueExporter", QVariant::fromValue(&exporter)}}));
QVERIFY(obj != nullptr);
QCOMPARE(obj->property("success").toBool(), true);
}
diff --git a/tests/auto/qml/qqmlvaluetypes/data/color_read.qml b/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
index 73d2b921a7..a2d303b507 100644
--- a/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
+++ b/tests/auto/qml/qqmlvaluetypes/data/color_read.qml
@@ -12,4 +12,7 @@ MyTypeObject {
property real hsl_s: color.hslSaturation
property real hsl_l: color.hslLightness
property variant copy: color
+
+ property bool valid: color.valid
+ property bool invalid: invalidColor.valid
}
diff --git a/tests/auto/qml/qqmlvaluetypes/testtypes.h b/tests/auto/qml/qqmlvaluetypes/testtypes.h
index bcfe4028c6..798c96e188 100644
--- a/tests/auto/qml/qqmlvaluetypes/testtypes.h
+++ b/tests/auto/qml/qqmlvaluetypes/testtypes.h
@@ -69,6 +69,7 @@ class MyTypeObject : public QObject
Q_PROPERTY(QMatrix4x4 matrix READ matrix WRITE setMatrix NOTIFY changed)
Q_PROPERTY(QFont font READ font WRITE setFont NOTIFY changed)
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY changed)
+ Q_PROPERTY(QColor invalidColor READ invalidColor CONSTANT)
Q_PROPERTY(QVariant variant READ variant NOTIFY changed)
public:
@@ -168,6 +169,8 @@ public:
QColor color() const { return m_color; }
void setColor(const QColor &v) { m_color = v; emit changed(); }
+ QColor invalidColor() const { return QColor(); }
+
QVariant variant() const { return sizef(); }
void emitRunScript() { emit runScript(); }
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index 8a602a0356..3e9047cc5a 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -97,6 +97,7 @@ private slots:
void enumerableProperties();
void enumProperties();
void scarceTypes();
+ void nonValueTypes();
private:
QQmlEngine engine;
@@ -934,6 +935,11 @@ void tst_qqmlvaluetypes::color()
QCOMPARE(qRound(object->property("hsl_s").toDouble() * 100), 74);
QCOMPARE(qRound(object->property("hsl_l").toDouble() * 100), 54);
+ QCOMPARE(object->property("valid").userType(), QMetaType::Bool);
+ QVERIFY(object->property("valid").toBool());
+ QCOMPARE(object->property("invalid").userType(), QMetaType::Bool);
+ QVERIFY(!object->property("invalid").toBool());
+
QColor comparison;
comparison.setRedF(0.2);
comparison.setGreenF(0.88);
@@ -1844,6 +1850,16 @@ void tst_qqmlvaluetypes::scarceTypes()
QCOMPARE(QByteArray(pixmapValue->vtable()->className), QByteArray("VariantObject"));
}
+#define CHECK_TYPE_IS_NOT_VALUETYPE(Type, typeId, cppType) \
+ QVERIFY(!QQmlValueTypeFactory::isValueType(QMetaType::Type));
+
+void tst_qqmlvaluetypes::nonValueTypes()
+{
+ CHECK_TYPE_IS_NOT_VALUETYPE(UnknownType, 0, void)
+ QT_FOR_EACH_STATIC_PRIMITIVE_TYPE(CHECK_TYPE_IS_NOT_VALUETYPE);
+}
+
+#undef CHECK_TYPE_IS_NOT_VALUETYPE
QTEST_MAIN(tst_qqmlvaluetypes)
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index b7600351b7..ae99e35467 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -75,6 +75,7 @@ private slots:
void introspectQrc();
void sortCaseSensitive_data();
void sortCaseSensitive();
+ void updateProperties();
private:
void checkNoErrors(const QQmlComponent& component);
QQmlEngine engine;
@@ -425,6 +426,47 @@ void tst_qquickfolderlistmodel::sortCaseSensitive()
QTRY_COMPARE(flm->data(flm->index(i),FileNameRole).toString(), expectedOrder.at(i));
}
+void tst_qquickfolderlistmodel::updateProperties()
+{
+ QQmlComponent component(&engine, testFileUrl("basic.qml"));
+ checkNoErrors(component);
+
+ QObject *folderListModel = component.create();
+ QVERIFY(folderListModel);
+
+ QVariant caseSensitive = folderListModel->property("caseSensitive");
+ QVERIFY(caseSensitive.isValid());
+ QCOMPARE(caseSensitive.toBool(), true);
+ folderListModel->setProperty("caseSensitive", false);
+ caseSensitive = folderListModel->property("caseSensitive");
+ QVERIFY(caseSensitive.isValid());
+ QCOMPARE(caseSensitive.toBool(), false);
+
+ QVariant showOnlyReadable = folderListModel->property("showOnlyReadable");
+ QVERIFY(showOnlyReadable.isValid());
+ QCOMPARE(showOnlyReadable.toBool(), false);
+ folderListModel->setProperty("showOnlyReadable", true);
+ showOnlyReadable = folderListModel->property("showOnlyReadable");
+ QVERIFY(showOnlyReadable.isValid());
+ QCOMPARE(showOnlyReadable.toBool(), true);
+
+ QVariant showDotAndDotDot = folderListModel->property("showDotAndDotDot");
+ QVERIFY(showDotAndDotDot.isValid());
+ QCOMPARE(showDotAndDotDot.toBool(), false);
+ folderListModel->setProperty("showDotAndDotDot", true);
+ showDotAndDotDot = folderListModel->property("showDotAndDotDot");
+ QVERIFY(showDotAndDotDot.isValid());
+ QCOMPARE(showDotAndDotDot.toBool(), true);
+
+ QVariant showHidden = folderListModel->property("showHidden");
+ QVERIFY(showHidden.isValid());
+ QCOMPARE(showHidden.toBool(), false);
+ folderListModel->setProperty("showHidden", true);
+ showHidden = folderListModel->property("showHidden");
+ QVERIFY(showHidden.isValid());
+ QCOMPARE(showHidden.toBool(), true);
+}
+
QTEST_MAIN(tst_qquickfolderlistmodel)
#include "tst_qquickfolderlistmodel.moc"
diff --git a/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp b/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
index 308fba9049..157d0f2a62 100644
--- a/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
+++ b/tests/auto/qml/qv4identifiertable/tst_qv4identifiertable.cpp
@@ -1,5 +1,6 @@
/****************************************************************************
**
+** Copyright (C) 2019 The Qt Company Ltd.
** Copyright (C) 2016 basysKom GmbH.
** Contact: https://www.qt.io/licensing/
**
@@ -110,8 +111,8 @@ void tst_qv4identifiertable::sweepCenterEntryInBucket()
table.asPropertyKey(entry2);
table.asPropertyKey(entry3);
- QCOMPARE(table.size, 3);
- QCOMPARE(table.alloc, 5);
+ QCOMPARE(table.size, 3u);
+ QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@@ -153,8 +154,8 @@ void tst_qv4identifiertable::sweepLastEntryInBucket()
table.asPropertyKey(entry2);
table.asPropertyKey(entry3);
- QCOMPARE(table.size, 3);
- QCOMPARE(table.alloc, 5);
+ QCOMPARE(table.size, 3u);
+ QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@@ -193,8 +194,8 @@ void tst_qv4identifiertable::sweepFirstEntryInSameBucketWithDifferingHash()
table.asPropertyKey(entry1);
table.asPropertyKey(entry2);
- QCOMPARE(table.size, 2);
- QCOMPARE(table.alloc, 5);
+ QCOMPARE(table.size, 2u);
+ QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@@ -231,8 +232,8 @@ void tst_qv4identifiertable::dontSweepAcrossBucketBoundaries()
table.asPropertyKey(entry1);
table.asPropertyKey(entry2);
- QCOMPARE(table.size, 2);
- QCOMPARE(table.alloc, 5);
+ QCOMPARE(table.size, 2u);
+ QCOMPARE(table.alloc, 5u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@@ -279,8 +280,8 @@ void tst_qv4identifiertable::sweepAcrossBucketBoundariesIfFirstBucketFull()
table.asPropertyKey(entry3);
table.asPropertyKey(entry4);
- QCOMPARE(table.size, 4);
- QCOMPARE(table.alloc, 11);
+ QCOMPARE(table.size, 4u);
+ QCOMPARE(table.alloc, 11u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
@@ -336,8 +337,8 @@ void tst_qv4identifiertable::sweepBucketGap()
table.asPropertyKey(entry3);
table.asPropertyKey(entry4);
- QCOMPARE(table.size, 4);
- QCOMPARE(table.alloc, 11);
+ QCOMPARE(table.size, 4u);
+ QCOMPARE(table.alloc, 11u);
QCOMPARE(table.entriesByHash[0], entry1);
QCOMPARE(table.entriesByHash[1], entry2);
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 66314f88a2..65c5ac9ef4 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -53,9 +53,12 @@ private slots:
void initTestCase();
void defaultPropertyValues();
+ void touchDrag_data();
void touchDrag();
void mouseDrag_data();
void mouseDrag();
+ void mouseDragThreshold_data();
+ void mouseDragThreshold();
void dragFromMargin();
void snapMode_data();
void snapMode();
@@ -131,9 +134,18 @@ void tst_DragHandler::defaultPropertyValues()
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), QPointF());
}
+void tst_DragHandler::touchDrag_data()
+{
+ QTest::addColumn<int>("dragThreshold");
+ QTest::newRow("threshold zero") << 0;
+ QTest::newRow("threshold one") << 1;
+ QTest::newRow("threshold 20") << 20;
+ QTest::newRow("threshold default") << -1;
+}
+
void tst_DragHandler::touchDrag()
{
- const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QFETCH(int, dragThreshold);
QScopedPointer<QQuickView> windowPtr;
createView(windowPtr, "draggables.qml");
QQuickView * window = windowPtr.data();
@@ -142,6 +154,12 @@ void tst_DragHandler::touchDrag()
QVERIFY(ball);
QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler);
+ if (dragThreshold < 0) {
+ dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QCOMPARE(dragHandler->dragThreshold(), dragThreshold);
+ } else {
+ dragHandler->setDragThreshold(dragThreshold);
+ }
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
@@ -161,7 +179,9 @@ void tst_DragHandler::touchDrag()
p1 += QPoint(dragThreshold, 0);
QTest::touchEvent(window, touchDevice).move(1, p1, window);
QQuickTouchUtils::flush(window);
- QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
+ qCDebug(lcPointerTests) << "velocity after drag" << dragHandler->centroid().velocity();
+ if (dragThreshold > 0)
+ QTRY_VERIFY(!qFuzzyIsNull(dragHandler->centroid().velocity().x()));
QCOMPARE(centroidChangedSpy.count(), 2);
QVERIFY(!dragHandler->active());
p1 += QPoint(1, 0);
@@ -282,6 +302,81 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(centroidChangedSpy.count(), shouldDrag ? 5 : 0);
}
+void tst_DragHandler::mouseDragThreshold_data()
+{
+ QTest::addColumn<int>("dragThreshold");
+ QTest::newRow("threshold zero") << 0;
+ QTest::newRow("threshold one") << 1;
+ QTest::newRow("threshold 20") << 20;
+ QTest::newRow("threshold default") << -1;
+}
+
+void tst_DragHandler::mouseDragThreshold()
+{
+ QFETCH(int, dragThreshold);
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball = window->rootObject()->childItems().first();
+ QVERIFY(ball);
+ QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+ if (dragThreshold < 0) {
+ dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QCOMPARE(dragHandler->dragThreshold(), dragThreshold);
+ } else {
+ dragHandler->setDragThreshold(dragThreshold);
+ }
+
+ QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
+ QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
+
+ QPointF ballCenter = ball->clipRect().center();
+ QPointF scenePressPos = ball->mapToScene(ballCenter);
+ QPoint p1 = scenePressPos.toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().velocity(), QVector2D());
+ QCOMPARE(centroidChangedSpy.count(), 1);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ if (dragThreshold > 0)
+ QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
+ QCOMPARE(centroidChangedSpy.count(), 2);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(translationChangedSpy.count(), 0);
+ QCOMPARE(centroidChangedSpy.count(), 3);
+ QCOMPARE(dragHandler->translation().x(), 0.0);
+ QPointF sceneGrabPos = p1;
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
+ p1 += QPoint(19, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter));
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->translation().y(), 0.0);
+ QVERIFY(dragHandler->centroid().velocity().x() > 0);
+ QCOMPARE(centroidChangedSpy.count(), 4);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
+ QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
+ QCOMPARE(translationChangedSpy.count(), 1);
+ QCOMPARE(centroidChangedSpy.count(), 5);
+}
+
void tst_DragHandler::dragFromMargin() // QTBUG-74966
{
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
diff --git a/tests/auto/quick/qquickanimatedimage/data/currentframe.qml b/tests/auto/quick/qquickanimatedimage/data/currentframe.qml
new file mode 100644
index 0000000000..b679da2a99
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedimage/data/currentframe.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+AnimatedImage {
+ property int currentFrameChangeCount: 0
+ property int frameChangeCount: 0
+ source: "stickman.gif"
+ onCurrentFrameChanged: if (currentFrame > 0) ++currentFrameChangeCount;
+ onFrameChanged: if (currentFrame > 0) ++frameChangeCount;
+ function scriptedSetCurrentFrame(frame) {
+ currentFrame = frame;
+ }
+}
+
diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
index 8026bafb9e..31c3fb9946 100644
--- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
+++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <qtest.h>
#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlexpression.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickview.h>
#include <QtQuick/private/qquickrectangle_p.h>
@@ -40,6 +41,23 @@
Q_DECLARE_METATYPE(QQuickImageBase::Status)
+template <typename T> static T evaluate(QObject *scope, const QString &expression)
+{
+ QQmlExpression expr(qmlContext(scope), scope, expression);
+ QVariant result = expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+ return result.value<T>();
+}
+
+template <> void evaluate<void>(QObject *scope, const QString &expression)
+{
+ QQmlExpression expr(qmlContext(scope), scope, expression);
+ expr.evaluate();
+ if (expr.hasError())
+ qWarning() << expr.error().toString();
+}
+
class tst_qquickanimatedimage : public QQmlDataTest
{
Q_OBJECT
@@ -68,6 +86,7 @@ private slots:
void playingAndPausedChanges();
void noCaching();
void sourceChangesOnFrameChanged();
+ void currentFrame();
};
void tst_qquickanimatedimage::cleanup()
@@ -618,6 +637,33 @@ void tst_qquickanimatedimage::sourceChangesOnFrameChanged()
qDeleteAll(images);
}
+void tst_qquickanimatedimage::currentFrame()
+{
+ QQuickView window;
+ window.setSource(testFileUrl("currentframe.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject());
+ QVERIFY(anim);
+ QSignalSpy frameChangedSpy(anim, SIGNAL(frameChanged()));
+ QSignalSpy currentFrameChangedSpy(anim, SIGNAL(currentFrameChanged()));
+
+ anim->setCurrentFrame(1);
+ QCOMPARE(anim->currentFrame(), 1);
+ QCOMPARE(frameChangedSpy.count(), 1);
+ QCOMPARE(currentFrameChangedSpy.count(), 1);
+ QCOMPARE(anim->property("currentFrameChangeCount"), 1);
+ QCOMPARE(anim->property("frameChangeCount"), 1);
+
+ evaluate<void>(anim, "scriptedSetCurrentFrame(2)");
+ QCOMPARE(anim->currentFrame(), 2);
+ QCOMPARE(frameChangedSpy.count(), 2);
+ QCOMPARE(currentFrameChangedSpy.count(), 2);
+ QCOMPARE(anim->property("currentFrameChangeCount"), 2);
+ QCOMPARE(anim->property("frameChangeCount"), 2);
+}
+
QTEST_MAIN(tst_qquickanimatedimage)
#include "tst_qquickanimatedimage.moc"
diff --git a/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml b/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
index c66fd76ff1..769a5b2c7d 100644
--- a/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
+++ b/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
@@ -14,6 +14,7 @@ Rectangle {
}
BoundaryRule on x {
+ objectName: "boundaryRule"
id: xbr
minimum: -50
maximum: 100
diff --git a/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro b/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
index ef43f4526a..c41f798d33 100644
--- a/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
+++ b/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
@@ -9,4 +9,4 @@ include (../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private qml-private quick-private testlib
+QT += quick-private qml testlib
diff --git a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
index 44f1c9a2f9..75639dba49 100644
--- a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
+++ b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
@@ -30,7 +30,6 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickview.h>
-#include <QtQuick/private/qquickboundaryrule_p.h>
#include <QtQuick/private/qquickdraghandler_p.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
@@ -57,7 +56,7 @@ void tst_qquickboundaryrule::dragHandler()
QVERIFY(target);
QQuickDragHandler *dragHandler = target->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler);
- QQuickBoundaryRule *boundaryRule = target->findChild<QQuickBoundaryRule*>();
+ QObject *boundaryRule = target->findChild<QObject *>(QLatin1String("boundaryRule"));
QVERIFY(boundaryRule);
QSignalSpy overshootChangedSpy(boundaryRule, SIGNAL(currentOvershootChanged()));
@@ -68,29 +67,34 @@ void tst_qquickboundaryrule::dragHandler()
QTest::mouseMove(&window, p1);
QTRY_VERIFY(dragHandler->active());
QCOMPARE(target->position().x(), 100);
- QCOMPARE(boundaryRule->currentOvershoot(), 0);
- QCOMPARE(boundaryRule->peakOvershoot(), 0);
+ bool ok = false;
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
QCOMPARE(overshootChangedSpy.count(), 0);
// restricted drag: halfway into overshoot
p1 += QPoint(20, 0);
QTest::mouseMove(&window, p1);
QCOMPARE(target->position().x(), 117.5);
- QCOMPARE(boundaryRule->currentOvershoot(), 20);
- QCOMPARE(boundaryRule->peakOvershoot(), 20);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(), 20);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(), 20);
QCOMPARE(overshootChangedSpy.count(), 1);
// restricted drag: maximum overshoot
p1 += QPoint(80, 0);
QTest::mouseMove(&window, p1);
QCOMPARE(target->position().x(), 140);
- QCOMPARE(boundaryRule->currentOvershoot(), 100);
- QCOMPARE(boundaryRule->peakOvershoot(), 100);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(), 100);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(), 100);
QCOMPARE(overshootChangedSpy.count(), 2);
// release and let it return to bounds
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p1);
QTRY_COMPARE(dragHandler->active(), false);
QTRY_COMPARE(overshootChangedSpy.count(), 3);
- QCOMPARE(boundaryRule->currentOvershoot(), 0);
- QCOMPARE(boundaryRule->peakOvershoot(), 0);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
QCOMPARE(target->position().x(), 100);
}
diff --git a/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp b/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
index 9d832066af..ee43e5e06a 100644
--- a/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
+++ b/tests/auto/quick/qquickdrag/tst_qquickdrag.cpp
@@ -598,7 +598,7 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&rightTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&rightTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); 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(rightTarget.position.x(), qreal(5)); QCOMPARE(rightTarget.position.y(), qreal(15));
@@ -620,10 +620,10 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(&leftTarget));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(&leftTarget));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 1);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); QCOMPARE(outerTarget.moveEvents, 0);
QCOMPARE(leftTarget .enterEvents, 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(outerTarget.position.x(), qreal(60)); QCOMPARE(outerTarget.position.y(), qreal(50));
QCOMPARE(leftTarget.position.x(), qreal(25)); QCOMPARE(leftTarget.position.y(), qreal(5));
// Move out of all targets.
@@ -632,7 +632,7 @@ void tst_QQuickDrag::move()
QCoreApplication::processEvents();
QCOMPARE(evaluate<QObject *>(item, "Drag.target"), static_cast<QObject *>(nullptr));
QCOMPARE(evaluate<QObject *>(item, "dragTarget"), static_cast<QObject *>(nullptr));
- QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 1); QCOMPARE(outerTarget.moveEvents, 0);
+ QCOMPARE(outerTarget.enterEvents, 0); QCOMPARE(outerTarget.leaveEvents, 0); 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);
diff --git a/tests/auto/quick/qquickdroparea/data/nested1.qml b/tests/auto/quick/qquickdroparea/data/nested1.qml
new file mode 100644
index 0000000000..de6ac70d08
--- /dev/null
+++ b/tests/auto/quick/qquickdroparea/data/nested1.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+
+Item {
+ width: 200; height: 200
+ property int outerEnterEvents: 0
+ property int outerExitEvents: 0
+ property int innerEnterEvents: 0
+ property int innerExitEvents: 0
+
+ DropArea {
+ objectName: "outerDropArea"
+ x: 75; y: 75
+ width: 100; height: 100
+ Rectangle {
+ anchors.fill: parent
+ color: "green"
+ }
+ onEntered: ++outerEnterEvents
+ onExited: ++outerExitEvents
+
+ DropArea {
+ objectName: "innerDropArea"
+ width: 50; height: 50
+ Rectangle {
+ anchors.fill: parent
+ color: "blue"
+ }
+ onEntered: ++innerEnterEvents
+ onExited: ++innerExitEvents
+ }
+ }
+
+ Rectangle {
+ width: 20; height: 20
+ color: dragArea.pressed ? "red" : "brown"
+ Drag.active: dragArea.drag.active
+ MouseArea {
+ id: dragArea
+ objectName: "dragArea"
+ anchors.fill: parent
+ drag.target: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickdroparea/data/nested2.qml b/tests/auto/quick/qquickdroparea/data/nested2.qml
new file mode 100644
index 0000000000..93630c3779
--- /dev/null
+++ b/tests/auto/quick/qquickdroparea/data/nested2.qml
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+
+Item {
+ width: 200; height: 200
+ property int outerEnterEvents: 0
+ property int outerExitEvents: 0
+ property int innerEnterEvents: 0
+ property int innerExitEvents: 0
+
+ Rectangle {
+ x: 75; y: 75
+ width: 100; height: 100
+ color: "green"
+ DropArea {
+ objectName: "outerDropArea"
+ anchors.fill: parent
+ onEntered: ++outerEnterEvents
+ onExited: ++outerExitEvents
+ }
+
+ Rectangle {
+ width: 50; height: 50
+ color: "blue"
+ DropArea {
+ objectName: "innerDropArea"
+ anchors.fill: parent
+ onEntered: ++innerEnterEvents
+ onExited: ++innerExitEvents
+ }
+ }
+ }
+
+ Rectangle {
+ width: 20; height: 20
+ color: dragArea.pressed ? "red" : "brown"
+ Drag.active: dragArea.drag.active
+ MouseArea {
+ id: dragArea
+ objectName: "dragArea"
+ anchors.fill: parent
+ drag.target: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickdroparea/qquickdroparea.pro b/tests/auto/quick/qquickdroparea/qquickdroparea.pro
index a34d5ad009..7a8fdef7b9 100644
--- a/tests/auto/quick/qquickdroparea/qquickdroparea.pro
+++ b/tests/auto/quick/qquickdroparea/qquickdroparea.pro
@@ -4,4 +4,11 @@ macx:CONFIG -= app_bundle
SOURCES += tst_qquickdroparea.cpp
+OTHER_FILES += $$files(data/*.qml)
+
+include (../../shared/util.pri)
+include (../shared/util.pri)
+
+TESTDATA = data/*
+
QT += core-private gui-private qml-private quick-private network testlib
diff --git a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
index cf01cc927b..dcba4c872e 100644
--- a/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
+++ b/tests/auto/quick/qquickdroparea/tst_qquickdroparea.cpp
@@ -28,6 +28,7 @@
#include <QtTest/QtTest>
#include <QtTest/QSignalSpy>
+#include <QtGui/qstylehints.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include <QtQml/qqmlcontext.h>
@@ -36,6 +37,8 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qwindowsysteminterface.h>
+#include "../../shared/util.h"
+#include "../shared/viewtestutil.h"
template <typename T> static T evaluate(QObject *scope, const QString &expression)
{
@@ -54,13 +57,10 @@ template <> void evaluate<void>(QObject *scope, const QString &expression)
qWarning() << expr.error().toString();
}
-class tst_QQuickDropArea: public QObject
+class tst_QQuickDropArea: public QQmlDataTest
{
Q_OBJECT
private slots:
- void initTestCase();
- void cleanupTestCase();
-
void containsDrag_internal();
void containsDrag_external();
void keys_internal();
@@ -74,21 +74,13 @@ private slots:
void competingDrags();
void simultaneousDrags();
void dropStuff();
+ void nestedDropAreas_data();
+ void nestedDropAreas();
private:
QQmlEngine engine;
};
-void tst_QQuickDropArea::initTestCase()
-{
-
-}
-
-void tst_QQuickDropArea::cleanupTestCase()
-{
-
-}
-
void tst_QQuickDropArea::containsDrag_internal()
{
QQuickWindow window;
@@ -1224,6 +1216,74 @@ void tst_QQuickDropArea::dropStuff()
QCOMPARE(evaluate<QByteArray>(dropArea, "array"), QByteArray("red"));
}
+void tst_QQuickDropArea::nestedDropAreas_data()
+{
+ QTest::addColumn<QString>("qmlFile");
+
+ QTest::newRow("dropRectDropRect") << "nested1.qml";
+ QTest::newRow("rectDropRectDrop") << "nested2.qml";
+}
+
+void tst_QQuickDropArea::nestedDropAreas()
+{
+ QFETCH(QString, qmlFile);
+
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QQuickView window;
+ QByteArray errorMessage;
+ QVERIFY2(QQuickTest::initView(window, testFileUrl(qmlFile.toLatin1().data()), true, &errorMessage), errorMessage.constData());
+
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject() != nullptr);
+
+ QQuickItem *dragArea = window.rootObject()->findChild<QQuickItem*>("dragArea");
+ QVERIFY(dragArea);
+ QQuickItem *outerDropArea = window.rootObject()->findChild<QQuickItem*>("outerDropArea");
+ QVERIFY(outerDropArea);
+ QQuickItem *innerDropArea = window.rootObject()->findChild<QQuickItem*>("innerDropArea");
+ QVERIFY(innerDropArea);
+
+ QPoint p = QPoint(10,10);
+ QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p);
+
+ // move the minimum distance to activate drag
+ p += QPoint(dragThreshold + 1, dragThreshold + 1);
+ QTest::mouseMove(&window, p);
+
+ // drag the red rectangle into the inner DropArea
+ p += QPoint(100, 100);
+ QTest::mouseMove(&window, p);
+ QCOMPARE(window.rootObject()->property("outerEnterEvents"), 0);
+ QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
+ QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
+ QCOMPARE(window.rootObject()->property("innerExitEvents"), 0);
+
+ // drag the red rectangle into the outer DropArea
+ p += QPoint(0, 50);
+ QTest::mouseMove(&window, p);
+ QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
+ QCOMPARE(window.rootObject()->property("outerExitEvents"), 0);
+ QCOMPARE(window.rootObject()->property("innerEnterEvents"), 1);
+ QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
+
+ // drag the red rectangle into the inner DropArea
+ p -= QPoint(0, 50);
+ QTest::mouseMove(&window, p);
+ QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
+ QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
+ QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
+ QCOMPARE(window.rootObject()->property("innerExitEvents"), 1);
+
+ // drag the red rectangle back out of both
+ p -= QPoint(100, 100);
+ QTest::mouseMove(&window, p);
+ QCOMPARE(window.rootObject()->property("outerEnterEvents"), 1);
+ QCOMPARE(window.rootObject()->property("outerExitEvents"), 1);
+ QCOMPARE(window.rootObject()->property("innerEnterEvents"), 2);
+ QCOMPARE(window.rootObject()->property("innerExitEvents"), 2);
+}
+
QTEST_MAIN(tst_QQuickDropArea)
#include "tst_qquickdroparea.moc"
diff --git a/tests/auto/quick/qquickflickable/data/resize.qml b/tests/auto/quick/qquickflickable/data/resize.qml
index 2f7ae7b8bb..131691d012 100644
--- a/tests/auto/quick/qquickflickable/data/resize.qml
+++ b/tests/auto/quick/qquickflickable/data/resize.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Rectangle {
+ required property bool setRebound
function resizeContent() {
flick.resizeContent(600, 600, Qt.point(100, 100))
}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index c104eecbcd..5364530ca8 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -226,7 +226,7 @@ void tst_qquickflickable::create()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("flickable01.qml"));
- QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+ QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.createWithInitialProperties({{"setRebound", false}}));
QVERIFY(obj != nullptr);
QCOMPARE(obj->isAtXBeginning(), true);
@@ -782,9 +782,8 @@ void tst_qquickflickable::flickableDirection()
void tst_qquickflickable::resizeContent()
{
QQmlEngine engine;
- engine.rootContext()->setContextProperty("setRebound", QVariant::fromValue(false));
QQmlComponent c(&engine, testFileUrl("resize.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+ QQuickItem *root = qobject_cast<QQuickItem*>(c.createWithInitialProperties({{"setRebound", false}}));
QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
QVERIFY(obj != nullptr);
@@ -816,7 +815,7 @@ void tst_qquickflickable::returnToBounds()
QScopedPointer<QQuickView> window(new QQuickView);
- window->rootContext()->setContextProperty("setRebound", setRebound);
+ window->setInitialProperties({{"setRebound", setRebound}});
window->setSource(testFileUrl("resize.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowActive(window.data()));
diff --git a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml
index 6a1c0632ad..49838c4fd5 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_gridlayout.qml
@@ -60,8 +60,8 @@ Item {
id: testCase
name: "Tests_GridLayout"
when: windowShown
- width: 200
- height: 200
+ width: parent.width
+ height: parent.height
Component {
id: layout_flow_Component
@@ -84,7 +84,7 @@ Item {
function test_flow()
{
- var layout = layout_flow_Component.createObject(container);
+ var layout = createTemporaryObject(layout_flow_Component, container);
tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10])
tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10])
tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10])
@@ -102,8 +102,6 @@ Item {
tryCompare(layout.children[4], "itemRect", [10, 0, 10, 10])
tryCompare(layout.children[5], "itemRect", [10, 10, 10, 10])
-
- layout.destroy()
}
Component {
@@ -178,7 +176,7 @@ Item {
}
function test_flowLeftToRight() {
- var layout = layout_flowLeftToRight_Component.createObject(container);
+ var layout = createTemporaryObject(layout_flowLeftToRight_Component, container);
compare(layout.implicitWidth, 80);
compare(layout.children[0].x, 0);
compare(layout.children[0].y, 0);
@@ -208,8 +206,6 @@ Item {
compare(layout.children[11].y, 60);
compare(layout.children[12].x, 40);
compare(layout.children[12].y, 80);
-
- layout.destroy();
}
@@ -259,7 +255,7 @@ Item {
function test_flowLeftToRightDefaultPositions() {
ignoreWarning("QGridLayoutEngine::addItem: Cell (1, 0) already taken");
- var layout = layout_flowLeftToRightDefaultPositions_Component.createObject(container);
+ var layout = createTemporaryObject(layout_flowLeftToRightDefaultPositions_Component, container);
compare(layout.implicitWidth, 40);
compare(layout.children[0].x, 0);
compare(layout.children[0].y, 0);
@@ -267,7 +263,6 @@ Item {
compare(layout.children[1].y, 20);
compare(layout.children[2].x, 20);
compare(layout.children[2].y, 20);
- layout.destroy();
}
@@ -342,7 +337,7 @@ Item {
}
function test_flowTopToBottom() {
- var layout = layout_flowTopToBottom_Component.createObject(container);
+ var layout = createTemporaryObject(layout_flowTopToBottom_Component, container);
compare(layout.children[0].x, 0);
compare(layout.children[0].y, 0);
compare(layout.children[1].x, 20);
@@ -371,8 +366,6 @@ Item {
compare(layout.children[11].y, 60);
compare(layout.children[12].x, 80);
compare(layout.children[12].y, 0);
-
- layout.destroy();
}
Component {
@@ -432,7 +425,7 @@ Item {
}
function test_spanAcrossEmptyRows() {
- var layout = layout_spanAcrossEmptyRows_Component.createObject(container);
+ var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container);
compare(layout.children[0].x, 0);
compare(layout.children[0].y, 0);
compare(layout.children[1].x, 20);
@@ -442,8 +435,6 @@ Item {
compare(layout.implicitWidth, 60);
compare(layout.Layout.maximumWidth, 120);
-
- layout.destroy();
}
Component {
@@ -463,14 +454,13 @@ Item {
}
function test_spanIsMoreThanColumns() {
- var layout = layout_spanIsMoreThanColumns_Component.createObject(container);
+ var layout = createTemporaryObject(layout_spanIsMoreThanColumns_Component, container);
// item was not added, therefore implicit width is 0
compare(layout.implicitWidth, 0);
- layout.destroy();
}
function test_sizeHints() {
- var layout = layout_spanAcrossEmptyRows_Component.createObject(container);
+ var layout = createTemporaryObject(layout_spanAcrossEmptyRows_Component, container);
compare(layout.visible, true)
var minWidth = layout.Layout.minimumWidth
@@ -489,8 +479,6 @@ Item {
compare(prefHeight, layout.implicitHeight)
compare(maxWidth, layout.Layout.maximumWidth)
compare(maxHeight, layout.Layout.maximumHeight)
-
- layout.destroy();
}
Component {
@@ -567,7 +555,7 @@ Item {
function test_alignment()
{
- var layout = layout_alignment_Component.createObject(container);
+ var layout = createTemporaryObject(layout_alignment_Component, container);
layout.width = 60;
layout.height = 100;
@@ -596,8 +584,6 @@ Item {
layout.children[4].Layout.alignment = Qt.AlignLeft
tryCompare(layout.children[4], "x", 0);
tryCompare(layout.children[4], "y", 60);
-
- layout.destroy();
}
@@ -648,7 +634,7 @@ Item {
function test_rightToLeft()
{
- var layout = layout_rightToLeft_Component.createObject(container);
+ var layout = createTemporaryObject(layout_rightToLeft_Component, container);
layout.width = 180;
layout.height = 50;
@@ -674,8 +660,6 @@ Item {
layout.LayoutMirroring.enabled = true
verifyIsRightToLeft(layout)
-
- layout.destroy();
}
Component {
@@ -698,7 +682,7 @@ Item {
function test_columnsChanged()
{
- var layout = layout_columnsOrRowsChanged_Component.createObject(container);
+ var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container);
layout.width = 40;
layout.height = 20;
tryCompare(layout.children[0], "itemRect", [ 0, 5, 10, 10])
@@ -711,13 +695,11 @@ Item {
tryCompare(layout.children[1], "itemRect", [20, 0, 10, 10])
tryCompare(layout.children[2], "itemRect", [ 0, 10, 10, 10])
tryCompare(layout.children[3], "itemRect", [20, 10, 10, 10])
-
- layout.destroy()
}
function test_rowsChanged()
{
- var layout = layout_columnsOrRowsChanged_Component.createObject(container);
+ var layout = createTemporaryObject(layout_columnsOrRowsChanged_Component, container);
layout.flow = GridLayout.TopToBottom
layout.width = 20;
layout.height = 40;
@@ -731,8 +713,6 @@ Item {
tryCompare(layout.children[1], "itemRect", [ 0, 25, 10, 10])
tryCompare(layout.children[2], "itemRect", [10, 5, 10, 10])
tryCompare(layout.children[3], "itemRect", [10, 25, 10, 10])
-
- layout.destroy()
}
Component {
@@ -767,7 +747,7 @@ Item {
function test_columnOrRowChanged()
{
- var layout = layout_columnOrRowChanged_Component.createObject(container);
+ var layout = createTemporaryObject(layout_columnOrRowChanged_Component, container);
layout.width = layout.implicitWidth
layout.height = layout.implicitHeight
// c0-c1-c2
@@ -795,8 +775,6 @@ Item {
tryCompare(layout.children[0], "itemRect", [10, 10, 10, 10])
tryCompare(layout.children[1], "itemRect", [ 0, 0, 10, 10])
tryCompare(layout.children[2], "itemRect", [20, 0, 10, 10])
-
- layout.destroy()
}
Component {
@@ -819,7 +797,7 @@ Item {
}
function test_baselines()
{
- var layout = layout_baselines_Component.createObject(container);
+ var layout = createTemporaryObject(layout_baselines_Component, container);
tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10])
tryCompare(layout.children[1], "itemRect", [10, 0, 10, 10])
compare(layout.implicitWidth, 20)
@@ -832,8 +810,6 @@ Item {
tryCompare(layout.children[1], "itemRect", [10, 10, 10, 10])
compare(layout.implicitWidth, 20)
compare(layout.implicitHeight, 20)
-
- layout.destroy();
}
Component {
@@ -851,30 +827,42 @@ Item {
}
}
- function test_spacings()
+ function test_spacings_data()
+ {
+ let data = [
+ { spacing: Number.NaN },
+ { spacing: 0 },
+ { spacing: 10 },
+ { spacing: -5 },
+ { spacing: -19 }
+ ]
+ for (let i = 0; i < data.length; ++i) {
+ data[i].tag = data[i].spacing.toString()
+ }
+ return data
+ }
+
+ function test_spacings(data)
{
- var layout = layout_spacings_Component.createObject(container);
+ var layout = createTemporaryObject(layout_spacings_Component, container);
// breaks down below -19. This is acceptable, since it means that the implicit size of the layout is negative
var testSpacings = [Number.NaN, 0, 10, -5, -19]
layout.rowSpacing = 0
- for (var i = 0; i < testSpacings.length; ++i) {
- var sp = testSpacings[i]
- if (isNaN(sp)) {
- sp = 5 // Test defaults
- } else {
- layout.columnSpacing = sp
- }
- tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10])
- tryCompare(layout.children[1], "itemRect", [10 + sp, 0, 10, 10])
- compare(layout.implicitWidth, 20 + sp)
+ var spacing = data.spacing
+ if (isNaN(spacing)) {
+ spacing = 5 // Test defaults
+ } else {
+ layout.columnSpacing = spacing
}
+ tryCompare(layout.children[0], "itemRect", [ 0, 0, 10, 10])
+ tryCompare(layout.children[1], "itemRect", [10 + spacing, 0, 10, 10])
+ compare(layout.implicitWidth, 20 + spacing)
// do not crash
layout.columnSpacing = -100
waitForRendering(layout)
verify(isFinite(layout.implicitWidth))
- layout.destroy();
}
Component {
@@ -1026,11 +1014,10 @@ Item {
function test_invalidateWhileRearranging_QTBUG_44139()
{
- var layout = layout_invalidateWhileRearranging_Component.createObject(container)
+ var layout = createTemporaryObject(layout_invalidateWhileRearranging_Component, container)
waitForRendering(layout);
verify(layout.children[1].visible == false);
- layout.destroy()
}
}
}
diff --git a/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml b/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml
new file mode 100644
index 0000000000..f354517678
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.12
+import Qt.fruit 1.0
+
+Rectangle {
+ id: root
+ required property bool useCpp
+ width: 200; height: 200
+
+
+ ListModel {
+ id: fruitModel
+
+ ListElement {
+ name: "Apple"
+ cost: 2
+ }
+ ListElement {
+ name: "Orange"
+ cost: 3
+ }
+ ListElement {
+ name: "Banana"
+ cost: 1
+ }
+ }
+
+
+ Component {
+ id: fruitDelegate
+ Row {
+ id: row
+ spacing: 10
+ required property string name
+ required property int cost
+ Text { text: row.name }
+ Text { text: '$' + row.cost }
+ Component.onCompleted: () => { console.debug(row.name+row.cost) };
+ }
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: root.useCpp ? FruitModelCpp : fruitModel
+ delegate: fruitDelegate
+ }
+
+}
diff --git a/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml b/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml
new file mode 100644
index 0000000000..18ce406e3f
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml
@@ -0,0 +1,77 @@
+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"
+ property string section: ListView.section
+ property string nextSection: ListView.nextSection
+ property string prevSection: ListView.previousSection
+ 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
+ cacheBuffer: 60
+ model: testModel
+ delegate: myDelegate
+ section.property: sectionProperty
+ section.delegate: Rectangle {
+ id: myDelegate
+ required property string section
+ objectName: "sect_" + section
+ color: "#99bb99"
+ height: 20
+ width: list.width
+ Text { text: myDelegate.section + ", " + parent.y + ", " + parent.objectName }
+ }
+ section.labelPositioning: sectionPositioning
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 08149a1786..fb5ae168e8 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -127,6 +127,7 @@ private slots:
void qAbstractItemModel_package_sections();
void qAbstractItemModel_sections();
void sectionsPositioning();
+ void sectionsDelegate_data();
void sectionsDelegate();
void sectionsDragOutsideBounds_data();
void sectionsDragOutsideBounds();
@@ -280,6 +281,8 @@ private slots:
void touchCancel();
void resizeAfterComponentComplete();
+ void delegateWithRequiredProperties();
+
private:
template <class T> void items(const QUrl &source);
template <class T> void changed(const QUrl &source);
@@ -389,7 +392,7 @@ void tst_QQuickListView::init()
m_view = nullptr;
}
#endif
- qmlRegisterType<QAbstractItemModel>();
+ qmlRegisterAnonymousType<QAbstractItemModel>("Proxy", 1);
qmlRegisterType<ProxyTestInnerModel>("Proxy", 1, 0, "ProxyTestInnerModel");
qmlRegisterType<QSortFilterProxyModel>("Proxy", 1, 0, "QSortFilterProxyModel");
}
@@ -1943,6 +1946,31 @@ void tst_QQuickListView::enforceRange()
QTRY_COMPARE(listview->currentIndex(), 6);
+ // Test for [QTBUG-77418] {
+ // explicit set current index
+ listview->setCurrentIndex(5);
+ QTRY_COMPARE(listview->contentY(), 0);
+
+ // then check if contentY changes if the highlight range is changed
+ listview->setPreferredHighlightBegin(80);
+ listview->setPreferredHighlightEnd(80);
+ QTRY_COMPARE(listview->contentY(), 20);
+
+ // verify that current index does not change with no highlight
+ listview->setHighlightRangeMode(QQuickListView::NoHighlightRange);
+ listview->setContentY(100);
+ QTRY_COMPARE(listview->currentIndex(), 5);
+
+ // explicit set current index, contentY should not change now
+ listview->setCurrentIndex(6);
+ QTRY_COMPARE(listview->contentY(), 100);
+ QTest::qWait(50); // This was needed in order to reproduce a failure for the following test
+
+ // verify that contentY changes if we turn on highlight again
+ listview->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange);
+ QTRY_COMPARE(listview->contentY(), 40);
+ // } Test for [QTBUG-77418]
+
// change model
QaimModel model2;
for (int i = 0; i < 5; i++)
@@ -2158,8 +2186,17 @@ void tst_QQuickListView::sections(const QUrl &source)
QTRY_COMPARE(item->height(), 40.0);
}
+void tst_QQuickListView::sectionsDelegate_data()
+{
+ QTest::addColumn<QUrl>("path");
+ QTest::addRow("implicit") << testFileUrl("listview-sections_delegate.qml");
+ QTest::addRow("required") << testFileUrl("listview-sections_delegate_required.qml");
+}
+
void tst_QQuickListView::sectionsDelegate()
{
+ QFETCH(QUrl, path);
+
QScopedPointer<QQuickView> window(createView());
QaimModel model;
@@ -2169,7 +2206,7 @@ void tst_QQuickListView::sectionsDelegate()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- window->setSource(testFileUrl("listview-sections_delegate.qml"));
+ window->setSource(path);
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -9037,6 +9074,90 @@ void tst_QQuickListView::resizeAfterComponentComplete() // QTBUG-76487
QTRY_COMPARE(lastItem->property("y").toInt(), 9 * lastItem->property("height").toInt());
}
+class Animal
+{
+public:
+ Animal(const int cost, const QString &name) {m_name = name; m_cost = cost;}
+
+ int cost() const {return m_cost;}
+ QString name() const {return m_name;}
+
+ QString m_name;
+ int m_cost;
+};
+
+class FruitModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ enum AnimalRoles {
+ NameRole = Qt::UserRole + 1,
+ CostRole
+ };
+
+ FruitModel(QObject* = nullptr) {
+ m_animals.push_back(Animal {4, QLatin1String("Melon")});
+ m_animals.push_back(Animal {5, QLatin1String("Cherry")});
+ }
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override {return m_animals.count();}
+
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override {
+ if (!checkIndex(index))
+ return {};
+ const Animal &animal = m_animals[index.row()];
+ if (role == CostRole)
+ return animal.cost();
+ else if (role == NameRole)
+ return animal.name();
+ return QVariant();
+ }
+
+protected:
+ QHash<int, QByteArray> roleNames() const override {
+ QHash<int, QByteArray> roles;
+ roles[CostRole] = "cost";
+ roles[NameRole] = "name";
+ return roles;
+ }
+private:
+ QList<Animal> m_animals;
+};
+
+void tst_QQuickListView::delegateWithRequiredProperties()
+{
+ FruitModel myModel;
+ qmlRegisterSingletonInstance("Qt.fruit", 1, 0, "FruitModelCpp", &myModel);
+ {
+ // ListModel
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Apple2");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Orange3");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Banana1");
+ QScopedPointer<QQuickView> window(createView());
+ window->setInitialProperties({{QLatin1String("useCpp"), false}});
+ window->setSource(testFileUrl("delegatesWithRequiredProperties.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *listView = window->rootObject();
+ QVERIFY(listView);
+ }
+ {
+ // C++ model
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Melon4");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Cherry5");
+ QScopedPointer<QQuickView> window(createView());
+ window->setInitialProperties({{QLatin1String("useCpp"), true}});
+ window->setSource(testFileUrl("delegatesWithRequiredProperties.qml"));
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *listView = window->rootObject();
+ QVERIFY(listView);
+ }
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml b/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml
new file mode 100644
index 0000000000..7bb21e8b93
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Item {
+ id: behaviorCounter
+ required property int i
+ required property string s
+
+}
diff --git a/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml b/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml
new file mode 100644
index 0000000000..4728346ca1
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int i: 0
+ property string s: ""
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ onLoaded: {
+ root.i = loader.item.i; // should be 42
+ root.s = loader.item.s; // should be 11
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("RequiredPropertyValuesComponent.qml", {"i": 42});
+ }
+}
diff --git a/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml b/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml
new file mode 100644
index 0000000000..5d6e3171a0
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int i: 0
+ property string s: ""
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ onLoaded: {
+ root.i = loader.item.i; // should be 42
+ root.s = loader.item.s; // should be 11
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("RequiredPropertyValuesComponent.qml", {"i": 42, "s": "hello world"});
+ }
+}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index fbdd87905b..da923d4d41 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -681,6 +681,16 @@ void tst_QQuickLoader::initialPropertyValues_data()
<< QStringList()
<< (QStringList() << "initialValue")
<< (QVariantList() << 6);
+
+ QTest::newRow("ensure required properties are set correctly") << testFileUrl("initialPropertyValues.9.qml")
+ << QStringList()
+ << (QStringList() << "i" << "s")
+ << (QVariantList() << 42 << QLatin1String("hello world"));
+
+ QTest::newRow("required properties only partially set =") << testFileUrl("initialPropertyValues.10.qml")
+ << (QStringList() << QString(testFileUrl("RequiredPropertyValuesComponent.qml").toString() + QLatin1String(":6:5: Required property s was not initialized")))
+ << (QStringList() << "i" << "s")
+ << (QVariantList() << 0 << QLatin1String(""));
}
void tst_QQuickLoader::initialPropertyValues()
diff --git a/tests/auto/quick/qquickmousearea/BLACKLIST b/tests/auto/quick/qquickmousearea/BLACKLIST
new file mode 100644
index 0000000000..f2cb00225b
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/BLACKLIST
@@ -0,0 +1,4 @@
+# QTBUG-78153
+[nestedStopAtBounds]
+opensuse-leap
+
diff --git a/tests/auto/quick/qquickmousearea/data/dragreset.qml b/tests/auto/quick/qquickmousearea/data/dragreset.qml
index 10039f1fcb..bbe0160080 100644
--- a/tests/auto/quick/qquickmousearea/data/dragreset.qml
+++ b/tests/auto/quick/qquickmousearea/data/dragreset.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Rectangle {
id: whiteRect
+ required property bool haveTarget
width: 200
height: 200
color: "white"
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 5844720aa4..54a29dbc7f 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -307,7 +307,7 @@ void tst_QQuickMouseArea::resetDrag()
{
QQuickView window;
QByteArray errorMessage;
- window.rootContext()->setContextProperty("haveTarget", QVariant(true));
+ window.setInitialProperties({{"haveTarget", true}});
QVERIFY2(QQuickTest::initView(window, testFileUrl("dragreset.qml"), true, &errorMessage), errorMessage.constData());
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
@@ -326,7 +326,9 @@ void tst_QQuickMouseArea::resetDrag()
QVERIFY(rootItem != nullptr);
QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
QVERIFY(drag->target() != nullptr);
- window.rootContext()->setContextProperty("haveTarget", QVariant(false));
+ auto root = window.rootObject();
+ QQmlProperty haveTarget {root, "haveTarget"};
+ haveTarget.write(false);
QCOMPARE(targetSpy.count(),1);
QVERIFY(!drag->target());
}
@@ -1359,6 +1361,34 @@ void tst_QQuickMouseArea::hoverVisible()
QCOMPARE(enteredSpy.count(), 1);
QCOMPARE(QPointF(mouseTracker->mouseX(), mouseTracker->mouseY()), QPointF(11,33));
+
+ // QTBUG-77983
+ mouseTracker->setVisible(false);
+ mouseTracker->setEnabled(false);
+
+ QCOMPARE(mouseTracker->hovered(), false);
+ mouseTracker->setVisible(true);
+ // if the enabled property is false, the containsMouse property shouldn't become true
+ // when an invisible mousearea become visible
+ QCOMPARE(mouseTracker->hovered(), false);
+
+ mouseTracker->parentItem()->setEnabled(false);
+ mouseTracker->setVisible(false);
+ mouseTracker->setEnabled(true);
+
+ QCOMPARE(mouseTracker->hovered(), false);
+ mouseTracker->setVisible(true);
+ // if the parent item is not enabled, the containsMouse property will be false, even if
+ // the mousearea is enabled
+ QCOMPARE(mouseTracker->hovered(), false);
+
+ mouseTracker->parentItem()->setEnabled(true);
+ mouseTracker->setVisible(false);
+ mouseTracker->setEnabled(true);
+
+ QCOMPARE(mouseTracker->hovered(), false);
+ mouseTracker->setVisible(true);
+ QCOMPARE(mouseTracker->hovered(), true);
}
void tst_QQuickMouseArea::hoverAfterPress()
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index cd66fc4ede..e96b892b54 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -72,6 +72,7 @@ private slots:
void mouseGestureStarted_data();
void mouseGestureStarted();
void cancel();
+ void stationaryTouchWithChangingPressure();
private:
QQuickView *createAndShowView(const QString &file);
@@ -1305,6 +1306,42 @@ void tst_QQuickMultiPointTouchArea::cancel()
}
+void tst_QQuickMultiPointTouchArea::stationaryTouchWithChangingPressure() // QTBUG-77142
+{
+ QScopedPointer<QQuickView> window(createAndShowView("basic.qml"));
+ QVERIFY(window->rootObject() != nullptr);
+
+ QQuickTouchPoint *point1 = window->rootObject()->findChild<QQuickTouchPoint*>("point1");
+ QCOMPARE(point1->pressed(), false);
+
+ QPoint p1(20,100);
+ QTouchEvent::TouchPoint tp1(1);
+
+ tp1.setScreenPos(window->mapToGlobal(p1));
+ tp1.setState(Qt::TouchPointPressed);
+ tp1.setPressure(0.5);
+ qt_handleTouchEvent(window.data(), device, {tp1});
+ QQuickTouchUtils::flush(window.data());
+
+ QCOMPARE(point1->pressed(), true);
+ QCOMPARE(point1->pressure(), 0.5);
+
+ tp1.setState(Qt::TouchPointStationary);
+ tp1.setPressure(0.6);
+ qt_handleTouchEvent(window.data(), device, {tp1});
+ QQuickTouchUtils::flush(window.data());
+
+ QCOMPARE(point1->pressure(), 0.6);
+
+ tp1.setState(Qt::TouchPointReleased);
+ tp1.setPressure(0);
+ qt_handleTouchEvent(window.data(), device, {tp1});
+ QQuickTouchUtils::flush(window.data());
+
+ QCOMPARE(point1->pressed(), false);
+ QCOMPARE(point1->pressure(), 0);
+}
+
QTEST_MAIN(tst_QQuickMultiPointTouchArea)
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml
new file mode 100644
index 0000000000..ae8ca784bc
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml
@@ -0,0 +1,59 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ width: 800
+ height: 600
+ property bool working: false
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ height: 50
+ width: 50
+ required property string name
+ required property int index
+ onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = true}
+ Text {
+ text: myDelegate.name
+ font.pointSize: 10
+ anchors.fill: myDelegate
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 80; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+ Timer {
+ interval: 1
+ running: true
+ repeat: false
+ onTriggered: () => { myModel.setProperty(1, "name", "You-know-who"); }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml
new file mode 100644
index 0000000000..2996ba18fd
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml
@@ -0,0 +1,64 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ width: 800
+ height: 600
+ property bool working: false
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ height: 50
+ width: 50
+ required property string name
+ required property int index
+ onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = false}
+ Text {
+ text: myDelegate.name
+ font.pointSize: 10
+ anchors.fill: myDelegate
+ }
+ Component.onCompleted: () => {myDelegate.name = "break binding"}
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 80; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+ Timer {
+ interval: 1
+ running: true
+ repeat: false
+ onTriggered: () => {
+ myModel.setProperty(1, "name", "You-know-who")
+ myModel.setProperty(2, "name", "You-know-who")
+ root.working = true
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml
new file mode 100644
index 0000000000..5d721fd0c4
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml
@@ -0,0 +1,53 @@
+import QtQuick 2.14
+
+Item {
+ width: 400
+ height: 200
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ required property int index
+ required property string name
+ required property string place
+ height: 100
+ width: 100
+ Text {
+ text: myDelegate.name + " lives in " + myDelegate.place + myDelegate.index
+ font.pointSize: 16
+ anchors.fill: myDelegate
+
+ Component.onCompleted: () => {console.info(myDelegate.name+myDelegate.place+myDelegate.index)}
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 120; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml
new file mode 100644
index 0000000000..bf130a2d73
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml
@@ -0,0 +1,52 @@
+import QtQuick 2.14
+
+Item {
+ width: 400
+ height: 200
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ required property int set
+ set: 42
+ height: 100
+ width: 100
+ Text {
+ text: "Test"
+ font.pointSize: 16
+ anchors.fill: myDelegate
+
+ Component.onCompleted: () => { try {index; console.log(index); console.log(name)} catch(ex) {console.info(ex.name)} }
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 120; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml
new file mode 100644
index 0000000000..ff11002552
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/nestedmousearea2.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+PathView {
+ id: view
+ width: 400; height: 240
+ highlight: Rectangle { width: 80; height: 80; color: "lightsteelblue" }
+ preferredHighlightBegin: 0.5
+ preferredHighlightEnd: 0.5
+ model: ListModel {
+ id: appModel
+ ListElement { name: "Music" }
+ ListElement { name: "Movies" }
+ ListElement { name: "Camera" }
+ ListElement { name: "Calendar" }
+ ListElement { name: "Messaging" }
+ ListElement { name: "Todo List" }
+ ListElement { name: "Contacts" }
+ }
+ delegate: Rectangle {
+ width: 100; height: 100
+ scale: PathView.iconScale
+ border.color: "lightgrey"
+ color: "transparent"
+ Text {
+ anchors { horizontalCenter: parent.horizontalCenter }
+ text: name
+ smooth: true
+ color: ma.pressed ? "red" : "black"
+ }
+
+ MouseArea {
+ id: ma
+ anchors.fill: parent
+ onClicked: view.currentIndex = index
+ }
+ }
+ path: Path {
+ startX: 10
+ startY: 50
+ PathAttribute { name: "iconScale"; value: 0.5 }
+ PathQuad { x: 200; y: 150; controlX: 50; controlY: 200 }
+ PathAttribute { name: "iconScale"; value: 1.0 }
+ PathQuad { x: 390; y: 50; controlX: 350; controlY: 200 }
+ PathAttribute { name: "iconScale"; value: 0.5 }
+ }
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 20
+ text: view.currentIndex + " @ " + offset.toFixed(2)
+ }
+}
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index 8b963117ed..a8e847a5c7 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -120,6 +120,7 @@ private slots:
void undefinedPath();
void mouseDrag();
void nestedMouseAreaDrag();
+ void flickNClick();
void treeModel();
void changePreferredHighlight();
void missingPercent();
@@ -149,6 +150,8 @@ private slots:
void movementDirection();
void removePath();
void objectModelMove();
+ void requiredPropertiesInDelegate();
+ void requiredPropertiesInDelegatePreventUnrelated();
};
class TestObject : public QObject
@@ -1601,6 +1604,71 @@ void tst_QQuickPathView::nestedMouseAreaDrag()
QVERIFY(pathview->isMoving());
}
+void tst_QQuickPathView::flickNClick() // QTBUG-77173
+{
+ QScopedPointer<QQuickView> window(createView());
+ QQuickViewTestUtil::moveMouseAway(window.data());
+ window->setSource(testFileUrl("nestedmousearea2.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window.data()));
+ QCOMPARE(window.data(), qGuiApp->focusWindow());
+
+ QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject());
+ QVERIFY(pathview != nullptr);
+ QSignalSpy movingChangedSpy(pathview, SIGNAL(movingChanged()));
+ QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged()));
+ QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted()));
+ QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded()));
+ QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged()));
+ QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted()));
+ QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded()));
+ QSignalSpy flickingSpy(pathview, SIGNAL(flickingChanged()));
+ QSignalSpy flickStartedSpy(pathview, SIGNAL(flickStarted()));
+ QSignalSpy flickEndedSpy(pathview, SIGNAL(flickEnded()));
+
+ for (int duration = 100; duration > 0; duration -= 20) {
+ movingChangedSpy.clear();
+ draggingSpy.clear();
+ dragStartedSpy.clear();
+ dragEndedSpy.clear();
+ currentIndexSpy.clear();
+ moveStartedSpy.clear();
+ moveEndedSpy.clear();
+ flickingSpy.clear();
+ flickStartedSpy.clear();
+ flickEndedSpy.clear();
+ // Dragging the child mouse area should animate the PathView (MA has no drag target)
+ flick(window.data(), QPoint(200,200), QPoint(400,200), duration);
+ QVERIFY(pathview->isMoving());
+ QCOMPARE(movingChangedSpy.count(), 1);
+ QCOMPARE(draggingSpy.count(), 2);
+ QCOMPARE(dragStartedSpy.count(), 1);
+ QCOMPARE(dragEndedSpy.count(), 1);
+ QVERIFY(currentIndexSpy.count() > 0);
+ QCOMPARE(moveStartedSpy.count(), 1);
+ QCOMPARE(moveEndedSpy.count(), 0);
+ QCOMPARE(flickingSpy.count(), 1);
+ QCOMPARE(flickStartedSpy.count(), 1);
+ QCOMPARE(flickEndedSpy.count(), 0);
+
+ // Now while it's still moving, click it.
+ // The PathView should stop at a position such that offset is a whole number.
+ QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(200, 200));
+ QTRY_VERIFY(!pathview->isMoving());
+ QCOMPARE(movingChangedSpy.count(), 2); // QTBUG-78926
+ QCOMPARE(draggingSpy.count(), 2);
+ QCOMPARE(dragStartedSpy.count(), 1);
+ QCOMPARE(dragEndedSpy.count(), 1);
+ QCOMPARE(moveStartedSpy.count(), 1);
+ QCOMPARE(moveEndedSpy.count(), 1);
+ QCOMPARE(flickingSpy.count(), 2);
+ QCOMPARE(flickStartedSpy.count(), 1);
+ QCOMPARE(flickEndedSpy.count(), 1);
+ QVERIFY(qFuzzyIsNull(pathview->offset() - int(pathview->offset())));
+ }
+}
+
void tst_QQuickPathView::treeModel()
{
QScopedPointer<QQuickView> window(createView());
@@ -2658,6 +2726,41 @@ void tst_QQuickPathView::objectModelMove()
}
}
+void tst_QQuickPathView::requiredPropertiesInDelegate()
+{
+ {
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Bill JonesBerlin0");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Jane DoeOslo1");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "John SmithOulo2");
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegateWithRequiredProperties.qml"));
+ window->show();
+ }
+ {
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegateWithRequiredProperties.2.qml"));
+ window->show();
+ QTRY_VERIFY(window->rootObject()->property("working").toBool());
+ }
+ {
+ QScopedPointer<QQuickView> window(createView());
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("Writing to \"name\" broke the binding to the underlying model"));
+ window->setSource(testFileUrl("delegateWithRequiredProperties.3.qml"));
+ window->show();
+ QTRY_VERIFY(window->rootObject()->property("working").toBool());
+ }
+}
+
+void tst_QQuickPathView::requiredPropertiesInDelegatePreventUnrelated()
+{
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegatewithUnrelatedRequiredPreventsAccessToModel.qml"));
+ window->show();
+}
+
QTEST_MAIN(tst_QQuickPathView)
#include "tst_qquickpathview.moc"
diff --git a/tests/auto/quick/qquickpositioners/data/transitions-padding.qml b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
index e3175c480c..eda9ce628e 100644
--- a/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
+++ b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
@@ -5,6 +5,16 @@ Rectangle {
width: 500
height: 500
+ required property bool usePopulateTransition
+ required property bool enableAddTransition
+ required property bool dynamicallyPopulate
+ required property var testModel
+ required property var model_targetItems_transitionFrom
+ required property var model_displacedItems_transitionVia
+ required property point targetItems_transitionFrom
+ required property point displacedItems_transitionVia
+ required property string testedPositioner
+
property int duration: 50
property real incrementalSize: 5
diff --git a/tests/auto/quick/qquickpositioners/data/transitions.qml b/tests/auto/quick/qquickpositioners/data/transitions.qml
index a1f27bb06e..988a01e373 100644
--- a/tests/auto/quick/qquickpositioners/data/transitions.qml
+++ b/tests/auto/quick/qquickpositioners/data/transitions.qml
@@ -5,6 +5,16 @@ Rectangle {
width: 500
height: 500
+ required property bool usePopulateTransition
+ required property bool enableAddTransition
+ required property bool dynamicallyPopulate
+ required property var testModel
+ required property var model_targetItems_transitionFrom
+ required property var model_displacedItems_transitionVia
+ required property point targetItems_transitionFrom
+ required property point displacedItems_transitionVia
+ required property string testedPositioner
+
property int duration: 50
property real incrementalSize: 5
diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
index d3c0f345b9..e6bbd8c215 100644
--- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
+++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
@@ -1025,16 +1025,17 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", usePopulateTransition);
- ctxt->setContextProperty("enableAddTransition", true);
- ctxt->setContextProperty("dynamicallyPopulate", dynamicallyPopulate);
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", positionerObjectName);
+ window->setInitialProperties({
+ {"usePopulateTransition", usePopulateTransition},
+ {"enableAddTransition", true},
+ {"dynamicallyPopulate", dynamicallyPopulate},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", positionerObjectName}
+ });
window->setSource(testFileUrl(qmlFile));
QQuickItem *positioner = window->rootObject()->findChild<QQuickItem*>(positionerObjectName);
@@ -1111,16 +1112,17 @@ void tst_qquickpositioners::addTransitions(const QString &positionerObjectName)
QaimModel model_displacedItems_transitionVia;
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", QVariant(false));
- ctxt->setContextProperty("enableAddTransition", QVariant(true));
- ctxt->setContextProperty("dynamicallyPopulate", QVariant(false));
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", QString());
+ window->setInitialProperties({
+ {"usePopulateTransition", QVariant(false)},
+ {"enableAddTransition", QVariant(true)},
+ {"dynamicallyPopulate", QVariant(false)},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", QString()}
+ });
window->setSource(testFileUrl(qmlFile));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -1234,16 +1236,17 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName)
QaimModel model_displacedItems_transitionVia;
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", QVariant(false));
- ctxt->setContextProperty("enableAddTransition", QVariant(false));
- ctxt->setContextProperty("dynamicallyPopulate", QVariant(false));
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", QString());
+ window->setInitialProperties({
+ {"usePopulateTransition", QVariant(false)},
+ {"enableAddTransition", QVariant(false)},
+ {"dynamicallyPopulate", QVariant(false)},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", QString()}
+ });
window->setSource(testFileUrl(qmlFile));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
diff --git a/tests/auto/quick/qquickrepeater/data/objlist_required.qml b/tests/auto/quick/qquickrepeater/data/objlist_required.qml
new file mode 100644
index 0000000000..cc9dd9566c
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/objlist_required.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+ objectName: "container"
+ width: 240
+ height: 320
+ color: "white"
+ Repeater {
+ id: repeater
+ objectName: "repeater"
+ model: testData
+ property int errors: 0
+ property int instantiated: 0
+ Component {
+ Item{
+ required property int index
+ required property int idx
+ Component.onCompleted: {if (index != idx) repeater.errors += 1; repeater.instantiated++}
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/data/requiredProperty.qml b/tests/auto/quick/qquickrepeater/data/requiredProperty.qml
new file mode 100644
index 0000000000..80eb3c28ee
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/requiredProperty.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.14
+
+Item {
+ Column {
+ Repeater {
+ model: ["apples", "oranges", "pears"]
+ Text {
+ id: txt
+ required property string modelData
+ required property int index
+ text: modelData + index
+ Component.onCompleted: () => {console.info(txt.text)}
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 65e7d29595..ccfef63902 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -55,6 +55,7 @@ public:
private slots:
void numberModel();
+ void objectList_data();
void objectList();
void stringList();
void dataModel_adding();
@@ -79,6 +80,7 @@ private slots:
void QTBUG54859_asynchronousMove();
void package();
void ownership();
+ void requiredProperties();
};
class TestObject : public QObject
@@ -143,6 +145,14 @@ void tst_QQuickRepeater::numberModel()
delete window;
}
+void tst_QQuickRepeater::objectList_data()
+{
+ QTest::addColumn<QUrl>("filename");
+
+ QTest::newRow("normal") << testFileUrl("objlist.qml");
+ QTest::newRow("required") << testFileUrl("objlist_required.qml");
+}
+
class MyObject : public QObject
{
Q_OBJECT
@@ -157,6 +167,7 @@ public:
void tst_QQuickRepeater::objectList()
{
+ QFETCH(QUrl, filename);
QQuickView *window = createView();
QObjectList data;
for (int i=0; i<100; i++)
@@ -165,7 +176,7 @@ void tst_QQuickRepeater::objectList()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testData", QVariant::fromValue(data));
- window->setSource(testFileUrl("objlist.qml"));
+ window->setSource(filename);
qApp->processEvents();
QQuickRepeater *repeater = findItem<QQuickRepeater>(window->rootObject(), "repeater");
@@ -1108,6 +1119,18 @@ void tst_QQuickRepeater::ownership()
QVERIFY(!modelGuard);
}
+void tst_QQuickRepeater::requiredProperties()
+{
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "apples0");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "oranges1");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "pears2");
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("requiredProperty.qml"));
+ QScopedPointer<QObject> o {component.create()};
+ QVERIFY(o);
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml b/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml
new file mode 100644
index 0000000000..3d38fa4046
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml
@@ -0,0 +1,72 @@
+import QtQuick 2.10
+import QtQuick.Layouts 1.3
+
+Item {
+ id: root
+
+ visible: true
+
+ width: 400
+ height: 200
+ property bool switchToRight: false
+ property alias stayingRectX: stayingRect.x
+
+ RowLayout {
+ id: topLayout
+
+ anchors.fill: parent
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ id: leftRect
+
+ width: parent.width*(2/3)
+ height: width
+ anchors.centerIn: parent
+
+ color: "red"
+
+ Rectangle {
+ id: stayingRect
+
+ x: 70; y: 70
+ width: 50; height: 50
+
+ color: "yellow"
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ id: rightRect
+
+ width: parent.height*(2/3)
+ height: width
+ anchors.centerIn: parent
+
+ color: "green"
+ rotation: 45
+ }
+ }
+ }
+
+ states: State {
+ name: "switchToRight"
+
+ ParentChange {
+ target: stayingRect
+ parent: rightRect
+ width: 70
+ }
+
+ }
+
+ state: root.switchToRight ? "switchToRight" : ""
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index 1eb797f54f..d5fea3cb28 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -139,6 +139,7 @@ private slots:
void revertListMemoryLeak();
void duplicateStateName();
void trivialWhen();
+ void parentChangeCorrectReversal();
};
void tst_qquickstates::initTestCase()
@@ -1675,6 +1676,22 @@ void tst_qquickstates::trivialWhen()
QVERIFY(c.create());
}
+void tst_qquickstates::parentChangeCorrectReversal()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("parentChangeCorrectReversal.qml"));
+ QScopedPointer<QObject> root {c.create()};
+ QVERIFY(root);
+ QQmlProperty stayingRectX(root.get(), "stayingRectX");
+ qreal oldX = stayingRectX.read().toDouble();
+ QQmlProperty switchToRight(root.get(), "switchToRight");
+ switchToRight.write(true);
+ qreal newX = stayingRectX.read().toDouble();
+ QVERIFY(newX != oldX);
+ switchToRight.write(false);
+ QCOMPARE(oldX, stayingRectX.read().toDouble());
+}
+
QTEST_MAIN(tst_qquickstates)
diff --git a/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml b/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml
new file mode 100644
index 0000000000..bebfd86931
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ delegate: tableViewDelegate
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ id: rect
+ required property string position
+ required property bool hasModelChildren
+ required property QtObject model
+ Text {text: rect.position}
+ implicitWidth: 100
+ implicitHeight: 100
+ Component.onCompleted: () => {if (rect.position === "R1:C1" && rect.model.hasModelChildren == rect.hasModelChildren) console.info("success")}
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml b/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml
new file mode 100644
index 0000000000..0c685cd49e
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ delegate: tableViewDelegate
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ id: rect
+ required property string position
+ required property bool unset
+ required property bool hasModelChildren
+ required property QtObject model
+ Text {text: rect.position}
+ implicitWidth: 100
+ implicitHeight: 100
+ Component.onCompleted: () => {if (rect.position === "R1:C1" && rect.model.hasModelChildren == rect.hasModelChildren) console.info("success")}
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml b/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml
new file mode 100644
index 0000000000..ecc79a9368
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/tweakimplicitsize.qml
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+ property real delegateSize: 10
+ property int hideRow: -1
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ anchors.margins: 1
+ clip: true
+ delegate: tableViewDelegate
+ columnSpacing: 1
+ rowSpacing: 1
+ columnWidthProvider: function(column) {
+ return -1
+ }
+ rowHeightProvider: function(row) {
+ if (row === hideRow)
+ return 0
+ return -1
+ }
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ objectName: "tableViewDelegate"
+ implicitWidth: row === 0 ? 10 : delegateSize
+ implicitHeight: column === 0 ? 10 : delegateSize
+ color: "lightgray"
+ border.width: 1
+
+ Text {
+ id: textItem
+ anchors.centerIn: parent
+ text: model.display
+ renderType: Text.NativeRendering
+ }
+ }
+ }
+
+}
+
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 19967efcd9..230dcc9446 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -119,6 +119,7 @@ private slots:
void checkRowHeightProviderNegativeReturnValue();
void checkRowHeightProviderNotCallable();
void checkForceLayoutFunction();
+ void checkForceLayoutEndUpDoingALayout();
void checkContentWidthAndHeight();
void checkPageFlicking();
void checkExplicitContentWidthAndHeight();
@@ -172,6 +173,7 @@ private slots:
void checkSyncView_differentSizedModels();
void checkSyncView_connect_late_data();
void checkSyncView_connect_late();
+ void delegateWithRequiredProperties();
};
tst_QQuickTableView::tst_QQuickTableView()
@@ -560,6 +562,32 @@ void tst_QQuickTableView::checkForceLayoutFunction()
QCOMPARE(fxItem->item->width(), newColumnWidth);
}
+void tst_QQuickTableView::checkForceLayoutEndUpDoingALayout()
+{
+ // QTBUG-77074
+ // Check that we change the implicit size of the delegate after
+ // the initial loading, and at the same time hide some rows or
+ // columns, and then do a forceLayout(), we end up with a
+ // complete relayout that respects the new implicit size.
+ LOAD_TABLEVIEW("tweakimplicitsize.qml");
+
+ auto model = TestModelAsVariant(10, 10);
+
+ tableView->setModel(model);
+
+ WAIT_UNTIL_POLISHED;
+
+ const qreal newDelegateSize = 20;
+ view->rootObject()->setProperty("delegateSize", newDelegateSize);
+ // Hide a row, just to force the following relayout to
+ // do a complete reload (and not just a relayout)
+ view->rootObject()->setProperty("hideRow", 1);
+ tableView->forceLayout();
+
+ for (auto fxItem : tableViewPrivate->loadedItems)
+ QCOMPARE(fxItem->item->height(), newDelegateSize);
+}
+
void tst_QQuickTableView::checkContentWidthAndHeight()
{
// Check that contentWidth/Height reports the correct size of the
@@ -2592,6 +2620,50 @@ void tst_QQuickTableView::checkSyncView_connect_late()
}
+void tst_QQuickTableView::delegateWithRequiredProperties()
+{
+ constexpr static int PositionRole = Qt::UserRole+1;
+ struct MyTable : QAbstractTableModel {
+
+
+ using QAbstractTableModel::QAbstractTableModel;
+
+ int rowCount(const QModelIndex& = QModelIndex()) const override {
+ return 3;
+ }
+
+ int columnCount(const QModelIndex& = QModelIndex()) const override {
+ return 3;
+ }
+
+ QVariant data(const QModelIndex &index, int = Qt::DisplayRole) const override {
+ return QVariant::fromValue(QString::asprintf("R%d:C%d", index.row(), index.column()));
+ }
+
+ QHash<int, QByteArray> roleNames() const override {
+ return QHash<int, QByteArray> { {PositionRole, "position"} };
+ }
+ };
+
+ auto model = QVariant::fromValue(QSharedPointer<MyTable>(new MyTable));
+ {
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "success");
+ LOAD_TABLEVIEW("delegateWithRequired.qml")
+ QVERIFY(tableView);
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+ QVERIFY(view->errors().empty());
+ }
+ {
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(R"|(TableView: failed loading index: \d)|"));
+ LOAD_TABLEVIEW("delegatewithRequiredUnset.qml")
+ QVERIFY(tableView);
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+ QTRY_VERIFY(view->errors().empty());
+ }
+}
+
QTEST_MAIN(tst_QQuickTableView)
#include "tst_qquicktableview.moc"
diff --git a/tests/auto/quick/qquicktext/data/transparentBackground.qml b/tests/auto/quick/qquicktext/data/transparentBackground.qml
new file mode 100644
index 0000000000..a10a1779bb
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/transparentBackground.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 200
+ color: "white"
+ Text {
+ objectName: "text"
+ textFormat: Text.RichText
+ anchors.fill: parent
+ color: "black"
+ text: "<h1 style=\"background-color:rgba(255,255,255,0.00)\">foo</h1>"
+ verticalAlignment: Text.AlignTop
+ horizontalAlignment: Text.AlignLeft
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 97107694bd..e62db81d27 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -164,6 +164,8 @@ private slots:
void verticallyAlignedImageInTable();
+ void transparentBackground();
+
private:
QStringList standard;
QStringList richText;
@@ -4429,6 +4431,26 @@ void tst_qquicktext::verticallyAlignedImageInTable()
// Don't crash
}
+void tst_qquicktext::transparentBackground()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms");
+
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("transparentBackground.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+ QImage img = window->grabWindow();
+ QCOMPARE(img.isNull(), false);
+
+ QColor color = img.pixelColor(0, 0);
+ QCOMPARE(color.red(), 255);
+ QCOMPARE(color.blue(), 255);
+ QCOMPARE(color.green(), 255);
+}
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 33a6b829bc..facd63027e 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -2106,30 +2106,31 @@ void tst_qquicktextedit::mouseSelection()
textEditObject->setFocus(focus);
textEditObject->setFocusOnPress(focusOnPress);
+ // Avoid that the last click from the previous test data and the first click in the
+ // current test data happens so close in time that they are interpreted as a double click.
+ static const int moreThanDoubleClickInterval = QGuiApplication::styleHints()->mouseDoubleClickInterval() + 1;
+
// press-and-drag-and-release from x1 to x2
QPoint p1 = textEditObject->positionToRectangle(from).center().toPoint();
QPoint p2 = textEditObject->positionToRectangle(to).center().toPoint();
if (clicks == 2)
- QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1, moreThanDoubleClickInterval);
else if (clicks == 3)
- QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1, moreThanDoubleClickInterval);
+ // cancel the 500ms delta QTestLib adds in order to properly synthesize a triple click within the required interval
+ QTest::lastMouseTimestamp -= QTest::mouseDoubleClickInterval;
QTest::mousePress(&window, Qt::LeftButton, Qt::NoModifier, p1);
- if (clicks == 2) {
- // QTBUG-50022: Since qtbase commit beef975, QTestLib avoids generating
- // double click events by adding 500ms delta to release event timestamps.
- // Send a double click event by hand to ensure the correct sequence:
- // press, release, press, _dbl click_, move, release.
- QMouseEvent dblClickEvent(QEvent::MouseButtonDblClick, p1, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
- QGuiApplication::sendEvent(textEditObject, &dblClickEvent);
- }
QTest::mouseMove(&window, p2);
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p2);
QTRY_COMPARE(textEditObject->selectedText(), selectedText);
// Clicking and shift to clicking between the same points should select the same text.
textEditObject->setCursorPosition(0);
- if (clicks > 1)
+ if (clicks > 1) {
QTest::mouseDClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
+ // cancel the 500ms delta QTestLib adds in order to properly synthesize a triple click within the required interval
+ QTest::lastMouseTimestamp -= QTest::mouseDoubleClickInterval;
+ }
if (clicks != 2)
QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, p1);
QTest::mouseClick(&window, Qt::LeftButton, Qt::ShiftModifier, p2);
diff --git a/tests/auto/quick/qquicktextinput/BLACKLIST b/tests/auto/quick/qquicktextinput/BLACKLIST
new file mode 100644
index 0000000000..ada7c57c75
--- /dev/null
+++ b/tests/auto/quick/qquicktextinput/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-78162
+[mouseSelectionMode]
+opensuse-leap
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index 32008f675a..fe56cad018 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -432,6 +432,7 @@ private slots:
void asynchronousCancel();
void invalidContext();
void externalManagedModel();
+ void delegateModelChangeDelegate();
private:
template <int N> void groups_verify(
@@ -4302,6 +4303,45 @@ void tst_qquickvisualdatamodel::externalManagedModel()
QTRY_VERIFY(!object->property("running").toBool());
}
+void tst_qquickvisualdatamodel::delegateModelChangeDelegate()
+{
+ // Verify that QTBUG-63477 is fixed.
+ // Changing the delegate would not update existing items.
+ QQmlEngine engine;
+ QScopedPointer<QQmlContext> context(new QQmlContext(engine.rootContext()));
+
+ QQmlComponent c(&engine);
+ c.setData("import QtQml.Models 2.2\nDelegateModel {}\n", QUrl());
+ QCOMPARE(c.status(), QQmlComponent::Ready);
+
+ QQmlDelegateModel *visualModel = qobject_cast<QQmlDelegateModel*>(c.create(context.data()));
+ QVERIFY(visualModel);
+ visualModel->setModel(QVariant(3));
+
+ QQmlComponent first(&engine);
+ first.setData("import QtQuick 2.0\nItem { objectName: \"old\" }\n", QUrl());
+ QCOMPARE(first.status(), QQmlComponent::Ready);
+
+ // Without delegate, claim to have an item count of 0
+ QCOMPARE(visualModel->count(), 0);
+
+ visualModel->setDelegate(&first);
+ // The first delegate has been set, verify we get it
+ QObject* old = visualModel->object(0, QQmlIncubator::Synchronous);
+ QVERIFY(old);
+ QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("old"));
+ QCOMPARE(visualModel->count(), 3);
+
+ QQmlComponent second(&engine);
+ second.setData("import QtQuick 2.0\nItem { objectName: \"new\" }\n", QUrl());
+ QCOMPARE(second.status(), QQmlComponent::Ready);
+
+ visualModel->setDelegate(&second);
+ // After changing the delegate, expect the existing item to have the new delegate
+ QCOMPARE(visualModel->object(0, QQmlIncubator::Synchronous)->objectName(), QStringLiteral("new"));
+ QCOMPARE(visualModel->count(), 3);
+}
+
QTEST_MAIN(tst_qquickvisualdatamodel)
#include "tst_qquickvisualdatamodel.moc"
diff --git a/tests/auto/quick/qquickwindow/data/shortcut.qml b/tests/auto/quick/qquickwindow/data/shortcut.qml
new file mode 100644
index 0000000000..2632e27859
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/data/shortcut.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.9
+import QtQuick.Window 2.2
+
+Window {
+ id: root
+ visible: true
+ width: 200
+ height: 200
+ property bool received: false
+ Item {
+ focus: true
+ Shortcut {
+ sequence: "B"
+ onActivated: {
+ root.received = true
+ }
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index f08b9207d1..7faa621e86 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -482,6 +482,10 @@ private slots:
void testChildMouseEventFilter_data();
void cleanupGrabsOnRelease();
+#if QT_CONFIG(shortcut)
+ void testShortCut();
+#endif
+
private:
QTouchDevice *touchDevice;
QTouchDevice *touchDeviceWithVelocity;
@@ -3579,6 +3583,30 @@ void tst_qquickwindow::cleanupGrabsOnRelease()
QCOMPARE(parent->mouseUngrabEventCount, 1);
}
+#if QT_CONFIG(shortcut)
+void tst_qquickwindow::testShortCut()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("shortcut.qml"));
+
+ QObject *created = component.create();
+ QScopedPointer<QObject> cleanup(created);
+ QVERIFY(created);
+
+ QQuickWindow *window = qobject_cast<QQuickWindow *>(created);
+ QVERIFY(QTest::qWaitForWindowActive(window));
+
+ EventFilter eventFilter;
+ window->activeFocusItem()->installEventFilter(&eventFilter);
+ //Send non-spontaneous key press event
+ QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_B, Qt::NoModifier);
+ QCoreApplication::sendEvent(window, &keyEvent);
+ QVERIFY(eventFilter.events.contains(int(QEvent::ShortcutOverride)));
+ QVERIFY(window->property("received").value<bool>());
+}
+#endif
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/manual/nodetypes_ng/nodetypes_ng.cpp b/tests/manual/nodetypes_ng/nodetypes_ng.cpp
index 829002b538..8fe0e0dc98 100644
--- a/tests/manual/nodetypes_ng/nodetypes_ng.cpp
+++ b/tests/manual/nodetypes_ng/nodetypes_ng.cpp
@@ -301,6 +301,13 @@ int main(int argc, char **argv)
fmt.setProfile(QSurfaceFormat::CoreProfile);
view.setFormat(fmt);
}
+ if (app.arguments().contains(QLatin1String("--transparent"))) {
+ qDebug("Requesting alpha channel for the window and using Qt::transparent as background");
+ QSurfaceFormat fmt = view.format();
+ fmt.setAlphaBufferSize(8);
+ view.setFormat(fmt);
+ view.setColor(Qt::transparent);
+ }
view.engine()->rootContext()->setContextProperty(QLatin1String("helper"), &helper);
diff --git a/tests/manual/pointer/pointerDrag.qml b/tests/manual/pointer/pointerDrag.qml
index 79044eb0b4..2063d8fae2 100644
--- a/tests/manual/pointer/pointerDrag.qml
+++ b/tests/manual/pointer/pointerDrag.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -26,7 +26,7 @@
**
****************************************************************************/
-import QtQuick 2.12
+import QtQuick 2.15
import "content"
Rectangle {
@@ -74,7 +74,14 @@ Rectangle {
label: "DragHandler"
objectName: "dragSquircle1"
DragHandler {
-
+ dragThreshold: ckZeroDragThreshold1.checked ? 0 : undefined
+ }
+ CheckBox {
+ id: ckZeroDragThreshold1
+ label: " Zero threshold"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 20
+ checked: false
}
}
@@ -99,7 +106,16 @@ Rectangle {
id: tap2
gesturePolicy: root.globalGesturePolicy
}
- DragHandler { }
+ DragHandler {
+ dragThreshold: ckZeroDragThreshold2.checked ? 0 : undefined
+ }
+ CheckBox {
+ id: ckZeroDragThreshold2
+ label: " Zero threshold"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 32
+ checked: false
+ }
}
TextBox {
@@ -107,7 +123,16 @@ Rectangle {
width: 100; height: 100
label: "DragHandler\nTapHandler"
color: queryColor(tap3.pressed)
- DragHandler { }
+ DragHandler {
+ dragThreshold: ckZeroDragThreshold3.checked ? 0 : undefined
+ }
+ CheckBox {
+ id: ckZeroDragThreshold3
+ label: " Zero threshold"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 32
+ checked: false
+ }
TapHandler {
id: tap3
gesturePolicy: root.globalGesturePolicy
@@ -118,7 +143,16 @@ Rectangle {
x: 400; y: 0
width: 100; height: 100
label: "DragHandler"
- DragHandler { }
+ DragHandler {
+ dragThreshold: ckZeroDragThreshold4.checked ? 0 : undefined
+ }
+ CheckBox {
+ id: ckZeroDragThreshold4
+ label: " Zero threshold"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 20
+ checked: false
+ }
TextBox {
label: "TapHandler"
@@ -145,6 +179,13 @@ Rectangle {
label: " Greedy ↓"
checked: true
}
+ CheckBox {
+ id: ckZeroDragThreshold5
+ label: " Zero threshold"
+ x: 10
+ anchors.bottom: ckGreedyDrag.top
+ checked: false
+ }
TapHandler {
id: tap5
gesturePolicy: root.globalGesturePolicy
@@ -159,6 +200,7 @@ Rectangle {
DragHandler {
grabPermissions: ckGreedyDrag ? DragHandler.CanTakeOverFromAnything :
DragHandler.CanTakeOverFromItems | DragHandler.CanTakeOverFromHandlersOfDifferentType | DragHandler.ApprovesTakeOverByAnything
+ dragThreshold: ckZeroDragThreshold5.checked ? 0 : undefined
}
}
}
@@ -174,7 +216,16 @@ Rectangle {
label: "DragHandler"
x: (parent.width - width)/2
y: 60
- DragHandler { }
+ DragHandler {
+ dragThreshold: ckZeroDragThreshold6.checked ? 0 : undefined
+ }
+ }
+ CheckBox {
+ id: ckZeroDragThreshold6
+ label: " Zero threshold"
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: 20
+ checked: false
}
}
diff --git a/tests/manual/pointer/tapWithModifiers.qml b/tests/manual/pointer/tapWithModifiers.qml
index 8ca1c1bd63..da3c0cb30a 100644
--- a/tests/manual/pointer/tapWithModifiers.qml
+++ b/tests/manual/pointer/tapWithModifiers.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -40,6 +40,16 @@ Item {
onTapped: console.log("tapped with no modifiers")
}
TapHandler {
- onTapped: console.log("tapped with modifiers " + point.event.modifiers)
+ onTapped:
+ switch (point.modifiers) {
+ case Qt.ControlModifier | Qt.AltModifier:
+ console.log("CTRL+ALT");
+ break;
+ case Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier:
+ console.log("CTRL+META+ALT");
+ break;
+ default:
+ console.log("other modifiers", point.modifiers)
+ }
}
}
diff --git a/tests/manual/scenegraph_lancelot/hostinfo.sh b/tests/manual/scenegraph_lancelot/hostinfo.sh
deleted file mode 100644
index 6bad2ba467..0000000000
--- a/tests/manual/scenegraph_lancelot/hostinfo.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/bin/sh
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the QtQml module of the Qt Toolkit.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-# printProperty(): prints a key-value pair from given key and cmd list.
-# If running cmd fails, or does not produce any stdout, nothing is printed.
-# Arguments: $1: key, $2: cmd, $3: optional, field specification as to cut(1) -f
-printProperty ()
-{
- key=$1
- val=`{ eval $2 ; } 2>/dev/null`
- [ -n "$3" ] && val=`echo $val | tr -s '[:blank:]' '\t' | cut -f$3`
- [ -n "$val" ] && echo $key: $val
-}
-
-# printEnvVar(): prints a key-value pair from given environment variable name.
-# key is printed as "Env_<varname>".
-# If the variable is undefined, nothing is printed.
-# Arguments: $1: varname
-
-printEnvVar ()
-{
- key=Env_$1
- val=`eval 'echo $'$1`
- [ -n "$val" ] && echo $key: $val
-}
-
-
-# printOnOff(): prints a key-value pair from given environment variable name.
-# If variable is defined, value is printed as "<key>-On"; otherwise "<key>-Off".
-# Arguments: $1: key $2: varname
-
-printOnOff ()
-{
- key=$1
- val=`eval 'echo $'$2`
- if [ -z "$val" ] ; then
- val=Off
- else
- val=On
- fi
- echo $key: $key-$val
-}
-
-# ------------
-
-printProperty Uname "uname -a"
-
-printProperty WlanMAC "ifconfig wlan0 | grep HWaddr" 5
-
-printEnvVar QMLSCENE_DEVICE
diff --git a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
index 6da0799bbc..23c678380c 100644
--- a/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegrabber/main.cpp
@@ -36,6 +36,11 @@
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
+#ifdef Q_OS_WIN
+# include <fcntl.h>
+# include <io.h>
+#endif // Q_OS_WIN
+
// Timeout values:
// A valid screen grab requires the scene to not change
@@ -101,6 +106,10 @@ private slots:
#endif
if (ofile == "-") { // Write to stdout
QFile of;
+#ifdef Q_OS_WIN
+ // Make sure write to stdout doesn't do LF->CRLF
+ _setmode(_fileno(stdout), _O_BINARY);
+#endif // Q_OS_WIN
if (!of.open(1, QIODevice::WriteOnly) || !lastGrab.save(&of, "ppm")) {
qWarning() << "Error: failed to write grabbed image to stdout.";
QGuiApplication::exit(2);
diff --git a/tests/manual/scenegraph_lancelot/scenegraph/scenegraph.pro b/tests/manual/scenegraph_lancelot/scenegraph/scenegraph.pro
index 65819ab5bf..dd0ef268b1 100644
--- a/tests/manual/scenegraph_lancelot/scenegraph/scenegraph.pro
+++ b/tests/manual/scenegraph_lancelot/scenegraph/scenegraph.pro
@@ -9,3 +9,7 @@ SOURCES += tst_scenegraph.cpp
# Include Lancelot protocol code to communicate with baseline server.
# Assuming that we are in a normal Qt5 source code tree
include(../../../../../qtbase/tests/baselineserver/shared/qbaselinetest.pri)
+
+TEST_HELPER_INSTALLS += .././qmlscenegrabber
+
+TESTDATA += ../data
diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
index 3f28d90e7b..40b17ec2a2 100644
--- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
@@ -68,6 +68,7 @@ private:
bool renderAndGrab(const QString& qmlFile, const QStringList& extraArgs, QImage *screenshot, QString *errMsg);
quint16 checksumFileOrDir(const QString &path);
+ QString testSuitePath;
int consecutiveErrors; // Not test failures (image mismatches), but system failures (so no image at all)
bool aborted; // This run given up because of too many system failures
};
@@ -81,6 +82,18 @@ tst_Scenegraph::tst_Scenegraph()
void tst_Scenegraph::initTestCase()
{
+ QString dataDir = QFINDTESTDATA("../data/.");
+ if (dataDir.isEmpty())
+ dataDir = QStringLiteral("data");
+ QFileInfo fi(dataDir);
+ if (!fi.exists() || !fi.isDir() || !fi.isReadable())
+ QSKIP("Test suite data directory missing or unreadable: " + fi.canonicalFilePath().toLatin1());
+ testSuitePath = fi.canonicalFilePath();
+
+ const char *backendVarName = "QT_QUICK_BACKEND";
+ const QString backend = qEnvironmentVariable(backendVarName, QString::fromLatin1("default"));
+ QBaselineTest::addClientProperty(QString::fromLatin1(backendVarName), backend);
+
QByteArray msg;
if (!QBaselineTest::connectToBaselineServer(&msg))
QSKIP(msg);
@@ -91,7 +104,7 @@ void tst_Scenegraph::cleanup()
{
// Allow subsystems time to settle
if (!aborted)
- QTest::qWait(200);
+ QTest::qWait(20);
}
void tst_Scenegraph::testNoTextRendering_data()
@@ -127,13 +140,6 @@ void tst_Scenegraph::setupTestSuite(const QByteArray& filter)
QTest::addColumn<QString>("qmlFile");
int numItems = 0;
- QString testSuiteDir = QLatin1String("data");
- QString testSuiteLocation = QCoreApplication::applicationDirPath();
- QString testSuitePath = testSuiteLocation + QDir::separator() + testSuiteDir;
- QFileInfo fi(testSuitePath);
- if (!fi.exists() || !fi.isDir() || !fi.isReadable())
- QSKIP("Test suite data directory missing or unreadable: " + testSuitePath.toLatin1());
-
QStringList ignoreItems;
QFile ignoreFile(testSuitePath + "/Ignore");
if (ignoreFile.open(QIODevice::ReadOnly)) {
@@ -233,7 +239,7 @@ quint16 tst_Scenegraph::checksumFileOrDir(const QString &path)
QFile f(path);
f.open(QIODevice::ReadOnly);
QByteArray contents = f.readAll();
- return qChecksum(contents.constData(), contents.size());
+ return qChecksum(contents.constData(), uint(contents.size()));
}
if (fi.isDir()) {
static const QStringList nameFilters = QStringList() << "*.qml" << "*.cpp" << "*.png" << "*.jpg";