aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qml')
-rw-r--r--tests/auto/qml/debugger/debugger.pro1
-rw-r--r--tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp5
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml4
-rw-r--r--tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp12
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml41
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro12
-rw-r--r--tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp80
-rw-r--r--tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp10
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp2
-rw-r--r--tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp4
-rw-r--r--tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp2
-rw-r--r--tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp3
-rw-r--r--tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp32
-rw-r--r--tests/auto/qml/debugger/shared/debugutil.cpp2
-rw-r--r--tests/auto/qml/debugger/shared/debugutil_p.h5
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations32
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp61
-rw-r--r--tests/auto/qml/qjsvalue/tst_qjsvalue.cpp16
-rw-r--r--tests/auto/qml/qml.pro5
-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/qmlcachegen.pro2
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp22
-rw-r--r--tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp4
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml106
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.formatted.qml106
-rw-r--r--tests/auto/qml/qmlformat/data/Annotations.qml76
-rw-r--r--tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml152
-rw-r--r--tests/auto/qml/qmlformat/data/Example1.formatted.qml152
-rw-r--r--tests/auto/qml/qmlformat/data/Example1.qml105
-rw-r--r--tests/auto/qml/qmlformat/data/FrontInline.formatted.qml3
-rw-r--r--tests/auto/qml/qmlformat/data/FrontInline.qml2
-rw-r--r--tests/auto/qml/qmlformat/data/IfBlocks.formatted.qml63
-rw-r--r--tests/auto/qml/qmlformat/data/IfBlocks.qml66
-rw-r--r--tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml29
-rw-r--r--tests/auto/qml/qmlformat/data/readOnlyProps.qml15
-rw-r--r--tests/auto/qml/qmlformat/qmlformat.pro12
-rw-r--r--tests/auto/qml/qmlformat/tst_qmlformat.cpp300
-rw-r--r--tests/auto/qml/qmllint/data/AttachedProps.qml6
-rw-r--r--tests/auto/qml/qmllint/data/AutomatchedSignalHandler.qml15
-rw-r--r--tests/auto/qml/qmllint/data/ButtonLoader.qml10
-rw-r--r--tests/auto/qml/qmllint/data/Cycle1.qml2
-rw-r--r--tests/auto/qml/qmllint/data/Cycle2.qml2
-rw-r--r--tests/auto/qml/qmllint/data/Cycle3.qml2
-rw-r--r--tests/auto/qml/qmllint/data/Dialog.qml10
-rw-r--r--tests/auto/qml/qmllint/data/Drawer.qml5
-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/Methods.js3
-rw-r--r--tests/auto/qml/qmllint/data/Text.qml6
-rw-r--r--tests/auto/qml/qmllint/data/Things/SomethingElse.qml2
-rw-r--r--tests/auto/qml/qmllint/data/Things/plugins.qmltypes17
-rw-r--r--tests/auto/qml/qmllint/data/Things/qmldir3
-rw-r--r--tests/auto/qml/qmllint/data/badAlias.qml5
-rw-r--r--tests/auto/qml/qmllint/data/badAliasProperty.qml6
-rw-r--r--tests/auto/qml/qmllint/data/badParent.qml7
-rw-r--r--tests/auto/qml/qmllint/data/badTypeAssertion.qml6
-rw-r--r--tests/auto/qml/qmllint/data/esmodule.mjs2
-rw-r--r--tests/auto/qml/qmllint/data/forLoop.qml9
-rw-r--r--tests/auto/qml/qmllint/data/goodAlias.qml12
-rw-r--r--tests/auto/qml/qmllint/data/goodParent.qml8
-rw-r--r--tests/auto/qml/qmllint/data/goodTypeAssertion.qml6
-rw-r--r--tests/auto/qml/qmllint/data/incompleteQmltypes.qml6
-rw-r--r--tests/auto/qml/qmllint/data/javascriptMethods.qml6
-rw-r--r--tests/auto/qml/qmllint/data/memberNotFound.qml7
-rw-r--r--tests/auto/qml/qmllint/data/parentIsComponent.qml13
-rw-r--r--tests/auto/qml/qmllint/data/qmldirAndQmltypes.qml6
-rw-r--r--tests/auto/qml/qmllint/data/unknownElement.qml (renamed from tests/auto/qml/qmllint/data/spuriousParentWarning.qml)0
-rw-r--r--tests/auto/qml/qmllint/data/unknownJavascriptMethod.qml6
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp207
-rw-r--r--tests/auto/qml/qmlmin/tst_qmlmin.cpp1
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp43
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.h59
-rw-r--r--tests/auto/qml/qmltyperegistrar/foreign/foreign.pro10
-rw-r--r--tests/auto/qml/qmltyperegistrar/hppheader.hpp64
-rw-r--r--tests/auto/qml/qmltyperegistrar/noextheader64
-rw-r--r--tests/auto/qml/qmltyperegistrar/qmltyperegistrar.pro4
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp78
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h96
-rw-r--r--tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.pro20
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.qmbin0 -> 101 bytes
-rw-r--r--tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.ts11
-rw-r--r--tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp23
-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/RequiredDefault.qml5
-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/requiredDefault.1.qml5
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml3
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml6
-rw-r--r--tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml4
-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.cpp117
-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/qqmldelegatemodel/data/abstractItemModel.qml37
-rw-r--r--tests/auto/qml/qqmldelegatemodel/data/integerModel.qml35
-rw-r--r--tests/auto/qml/qqmldelegatemodel/data/listModel.qml45
-rw-r--r--tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro13
-rw-r--r--tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp139
-rw-r--r--tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp8
-rw-r--r--tests/auto/qml/qqmlecmascript/testtypes.h1
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp35
-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/data/uiLanguage.qml9
-rw-r--r--tests/auto/qml/qqmlengine/tst_qqmlengine.cpp65
-rw-r--r--tests/auto/qml/qqmlenginecleanup/data/MyItem.qml2
-rw-r--r--tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp13
-rw-r--r--tests/auto/qml/qqmlimport/tst_qqmlimport.cpp21
-rw-r--r--tests/auto/qml/qqmlincubator/data/requiredProperty.qml5
-rw-r--r--tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp105
-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/Action.qml21
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentBase.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentChild.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentProvider.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentProvider2.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentProvider3.qml11
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentProviderChild.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/InlineComponentReexporter.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/RequiredBase.qml3
-rw-r--r--tests/auto/qml/qqmllanguage/data/SelfInstantiation.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/SelfInstantiation.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/SelfReference.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/SimpleItem.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.14.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.18.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/alias.18.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/arrayToContainer.qml2
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/foreignExtended.qml20
-rw-r--r--tests/auto/qml/qqmllanguage/data/icCycleViaProperty.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/icSimpleCycle.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentDuplicateName.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentFoundBeforeOtherImports.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentOrder.qml20
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentUser1.qml13
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentUser2.qml10
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentUser3.qml16
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentUser4.qml12
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentUser5.qml11
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml17
-rw-r--r--tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml14
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidRoot.4.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/invalidTypeName.4.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/listContainingDeleted.qml36
-rw-r--r--tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/nestedIC.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/nonExistingICUser1.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/nonExistingICUser2.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/nonExistingICUser3.qml3
-rw-r--r--tests/auto/qml/qqmllanguage/data/nonExistingICUser4.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/nonExistingICUser5.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.errors.txt1
-rw-r--r--tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml8
-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.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml1
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml3
-rw-r--r--tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml5
-rw-r--r--tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/TestSingleton.qml7
-rw-r--r--tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/SingletonTypeWithIC.qml16
-rw-r--r--tests/auto/qml/qqmllanguage/data/singleton/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/data/singletonICTest.qml6
-rw-r--r--tests/auto/qml/qqmllanguage/data/unsupportedProperty.errors.txt2
-rw-r--r--tests/auto/qml/qqmllanguage/data/unsupportedProperty.qml2
-rw-r--r--tests/auto/qml/qqmllanguage/qqmllanguage.pro5
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.cpp12
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h114
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp546
-rw-r--r--tests/auto/qml/qqmllistmodel/qqmllistmodel.pro2
-rw-r--r--tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp2
-rw-r--r--tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp213
-rw-r--r--tests/auto/qml/qqmllocale/tst_qqmllocale.cpp32
-rw-r--r--tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp4
-rw-r--r--tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp42
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml7
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/protectedModule/plugin.cpp4
-rw-r--r--tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp4
-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/qqmlparser/data/annotations/View1.qml76
-rw-r--r--tests/auto/qml/qqmlparser/data/noannotations/View1.qml76
-rw-r--r--tests/auto/qml/qqmlparser/qqmlparser.pro1
-rw-r--r--tests/auto/qml/qqmlparser/tst_qqmlparser.cpp147
-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/data/interfaceBinding2.qml27
-rw-r--r--tests/auto/qml/qqmlproperty/interfaces.h161
-rw-r--r--tests/auto/qml/qqmlproperty/qqmlproperty.pro8
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp158
-rw-r--r--tests/auto/qml/qqmlqt/data/formatting.qml5
-rw-r--r--tests/auto/qml/qqmlqt/data/formattingLocale.qml12
-rw-r--r--tests/auto/qml/qqmlqt/data/timeRoundtrip.qml2
-rw-r--r--tests/auto/qml/qqmlqt/tst_qqmlqt.cpp71
-rw-r--r--tests/auto/qml/qqmltablemodel/qqmltablemodel.pro2
-rw-r--r--tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp32
-rw-r--r--tests/auto/qml/qqmltypeloader/data/declarativeCppType.qml6
-rw-r--r--tests/auto/qml/qqmltypeloader/declarativetesttype.h44
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp50
-rw-r--r--tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro9
-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/qmlproperty_read.qml9
-rw-r--r--tests/auto/qml/qqmlvaluetypes/testtypes.h8
-rw-r--r--tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp15
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/file_request.qml32
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp346
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp17
-rw-r--r--tests/auto/qml/qquickworkerscript/data/BaseWorker.qml5
-rw-r--r--tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp18
279 files changed, 5584 insertions, 555 deletions
diff --git a/tests/auto/qml/debugger/debugger.pro b/tests/auto/qml/debugger/debugger.pro
index 5c328fbfcc..890e722aa3 100644
--- a/tests/auto/qml/debugger/debugger.pro
+++ b/tests/auto/qml/debugger/debugger.pro
@@ -4,6 +4,7 @@ SUBDIRS += qqmldebugjsserver
PUBLICTESTS += \
qdebugmessageservice \
+ qqmldebugtranslationservice \
qqmlenginedebugservice \
qqmldebugjs \
qqmlinspector \
diff --git a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
index d2cfd3897a..ec7ee15d34 100644
--- a/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
+++ b/tests/auto/qml/debugger/qdebugmessageservice/tst_qdebugmessageservice.cpp
@@ -88,8 +88,7 @@ public:
QList<LogEntry> logBuffer;
protected:
- //inherited from QQmlDebugClient
- void messageReceived(const QByteArray &data);
+ void messageReceived(const QByteArray &data) override;
signals:
void debugOutput();
@@ -136,7 +135,7 @@ QList<QQmlDebugClient *> tst_QDebugMessageService::createClients()
void tst_QDebugMessageService::retrieveDebugOutput()
{
- QCOMPARE(QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ QCOMPARE(QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
QString(), testFile(QMLFILE), true), ConnectSuccess);
QTRY_VERIFY(m_client->logBuffer.size() >= 2);
diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
index deba24cf91..a7231df48b 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
+++ b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml
@@ -36,5 +36,9 @@ Item {
}
id: root
property int a: 10
+
+ Item {
+ property int b: 11
+ }
}
diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
index 5b6c43bc0c..91470e0651 100644
--- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
+++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp
@@ -180,7 +180,7 @@ QQmlDebugTest::ConnectResult tst_QQmlDebugJS::init(bool qmlscene, const QString
const QString executable = qmlscene
? QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene"
: debugJsServerPath("qqmldebugjs");
- return QQmlDebugTest::connect(
+ return QQmlDebugTest::connectTo(
executable, restrictServices ? QStringLiteral("V8Debugger") : QString(),
testFile(qmlFile), blockMode);
}
@@ -896,6 +896,16 @@ void tst_QQmlDebugJS::evaluateInContext()
QVERIFY(waitForClientSignal(SIGNAL(result())));
QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20);
+
+ auto childObjects = object.children;
+ QVERIFY(childObjects.count() > 0); // QQmlComponentAttached is also in there
+ QCOMPARE(childObjects[0].className, QString::fromLatin1("Item"));
+
+ // "b" accessible in context of surrounding (child) object
+ m_client->evaluate(QLatin1String("b"), -1, childObjects[0].debugId);
+ QVERIFY(waitForClientSignal(SIGNAL(result())));
+
+ QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 11);
}
void tst_QQmlDebugJS::getScripts()
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml
new file mode 100644
index 0000000000..234496577a
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/data/test.qml
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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.0
+import QtQuick.Controls 2.12
+
+Item {
+ width: 360
+ height: 360
+
+ Text {
+ text: qsTr("hello")
+ width: parent.width / 10
+ elide: Text.ElideRight
+ }
+}
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro
new file mode 100644
index 0000000000..32e60e306d
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/qqmldebugtranslationservice.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qdebugtranslationservice
+QT += network testlib gui-private core-private qmldebug-private
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qqmldebugtranslationservice.cpp
+
+include(../shared/debugutil.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/test.qml
diff --git a/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp
new file mode 100644
index 0000000000..01ee805dee
--- /dev/null
+++ b/tests/auto/qml/debugger/qqmldebugtranslationservice/tst_qqmldebugtranslationservice.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+//QQmlDebugTest
+#include <debugutil_p.h>
+#include <qqmldebugprocess_p.h>
+
+#include <private/qqmldebugclient_p.h>
+#include <private/qqmldebugtranslationclient_p.h>
+#include <private/qqmldebugconnection_p.h>
+#include <private/qpacket_p.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qlibraryinfo.h>
+#include <QtTest/qtest.h>
+
+const char *QMLFILE = "test.qml";
+
+class tst_QQmlDebugTranslationService : public QQmlDebugTest
+{
+ Q_OBJECT
+
+private slots:
+ void pluginConnection();
+
+private:
+ QList<QQmlDebugClient *> createClients() override;
+ QPointer<QQmlDebugTranslationClient> m_client;
+};
+
+QList<QQmlDebugClient *> tst_QQmlDebugTranslationService::createClients()
+{
+ m_client = new QQmlDebugTranslationClient(m_connection);
+
+ QObject::connect(m_client, &QQmlDebugClient::stateChanged, m_client, [this](QQmlDebugClient::State newState) {
+ QCOMPARE(newState, m_client->state());
+ });
+
+ return {m_client};
+}
+
+void tst_QQmlDebugTranslationService::pluginConnection()
+{
+ auto executable = QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml";
+ auto services = "DebugTranslation";
+ auto extraArgs = testFile(QMLFILE);
+ auto block = true;
+
+ auto result = QQmlDebugTest::connectTo(executable, services, extraArgs, block);
+ QCOMPARE(result, ConnectSuccess);
+}
+
+QTEST_MAIN(tst_QQmlDebugTranslationService)
+
+#include "tst_qqmldebugtranslationservice.moc"
diff --git a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
index a8c43b1c75..c8915fb840 100644
--- a/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
+++ b/tests/auto/qml/debugger/qqmlenginecontrol/tst_qqmlenginecontrol.cpp
@@ -66,7 +66,7 @@ class tst_QQmlEngineControl : public QQmlDebugTest
Q_OBJECT
private:
- ConnectResult connect(const QString &testFile, bool restrictServices);
+ ConnectResult connectTo(const QString &testFile, bool restrictServices);
QList<QQmlDebugClient *> createClients() override;
void engine_data();
@@ -79,10 +79,10 @@ private slots:
void stopEngine();
};
-QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connect(const QString &file,
+QQmlDebugTest::ConnectResult tst_QQmlEngineControl::connectTo(const QString &file,
bool restrictServices)
{
- return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
+ return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene",
restrictServices ? QStringLiteral("EngineControl") : QString(),
testFile(file), true);
}
@@ -109,7 +109,7 @@ void tst_QQmlEngineControl::startEngine_data()
void tst_QQmlEngineControl::startEngine()
{
QFETCH(bool, restrictMode);
- QCOMPARE(connect("test.qml", restrictMode), ConnectSuccess);
+ QCOMPARE(connectTo("test.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
@@ -130,7 +130,7 @@ void tst_QQmlEngineControl::stopEngine()
{
QFETCH(bool, restrictMode);
- QCOMPARE(connect("exit.qml", restrictMode), ConnectSuccess);
+ QCOMPARE(connectTo("exit.qml", restrictMode), ConnectSuccess);
QTRY_VERIFY(!m_client->blockedEngines().empty());
m_client->releaseEngine(m_client->blockedEngines().last());
diff --git a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
index 980e2be1f1..9830f1a9bd 100644
--- a/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebuginspectorintegrationtest/tst_qqmlenginedebuginspectorintegration.cpp
@@ -87,7 +87,7 @@ QQmlEngineDebugObjectReference tst_QQmlEngineDebugInspectorIntegration::findRoot
QQmlDebugTest::ConnectResult tst_QQmlEngineDebugInspectorIntegration::init(bool restrictServices)
{
- return QQmlDebugTest::connect(
+ return QQmlDebugTest::connectTo(
QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
restrictServices ? QStringLiteral("QmlDebugger,QmlInspector") : QString(),
testFile("qtquick2.qml"), true);
diff --git a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
index 0ebf43eb6f..12befeb1ec 100644
--- a/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
+++ b/tests/auto/qml/debugger/qqmlenginedebugservice/tst_qqmlenginedebugservice.cpp
@@ -280,11 +280,11 @@ void tst_QQmlEngineDebugService::recursiveObjectTest(
} else {
QCOMPARE(ref.name, QString("<unknown value>"));
}
- } else if (pmeta.type() < QVariant::UserType && pmeta.userType() != QMetaType::QVariant) {
+ } else if (pmeta.userType() < QMetaType::User && pmeta.userType() != QMetaType::QVariant) {
const QVariant expected = pmeta.read(o);
QVERIFY2(p.value == expected, QString::fromLatin1("%1 != %2. Details: %3/%4/%5/%6")
.arg(QTest::toString(p.value)).arg(QTest::toString(expected)).arg(p.name)
- .arg(p.valueTypeName).arg(pmeta.type()).arg(pmeta.userType()).toUtf8());
+ .arg(p.valueTypeName).arg(pmeta.userType()).arg(pmeta.userType()).toUtf8());
}
if (p.name == "parent")
diff --git a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
index 6685558bb5..b5f45f1eeb 100644
--- a/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
+++ b/tests/auto/qml/debugger/qqmlinspector/tst_qqmlinspector.cpp
@@ -64,7 +64,7 @@ private slots:
QQmlDebugTest::ConnectResult tst_QQmlInspector::startQmlProcess(const QString &qmlFile,
bool restrictServices)
{
- return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
restrictServices ? QStringLiteral("QmlInspector") : QString(),
testFile(qmlFile), true);
}
diff --git a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp
index f08f3c1da7..bfec776614 100644
--- a/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp
+++ b/tests/auto/qml/debugger/qqmlpreview/tst_qqmlpreview.cpp
@@ -74,7 +74,7 @@ private slots:
QQmlDebugTest::ConnectResult tst_QQmlPreview::startQmlProcess(const QString &qmlFile)
{
- return QQmlDebugTest::connect(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
+ return QQmlDebugTest::connectTo(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qml",
QStringLiteral("QmlPreview"), testFile(qmlFile), true);
}
@@ -122,7 +122,6 @@ void checkFiles(const QStringList &files)
{
QVERIFY(!files.contains("/etc/localtime"));
QVERIFY(!files.contains("/etc/timezome"));
- QVERIFY(!files.contains(":/qgradient/webgradients.binaryjson"));
}
void tst_QQmlPreview::cleanup()
diff --git a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
index 085eb7b87a..c2a774b42d 100644
--- a/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
+++ b/tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp
@@ -201,7 +201,7 @@ private:
CheckType = CheckMessageType | CheckDetailType | CheckLine | CheckColumn | CheckFileEndsWith
};
- ConnectResult connect(bool block, const QString &file, bool recordFromStart = true,
+ ConnectResult connectTo(bool block, const QString &file, bool recordFromStart = true,
uint flushInterval = 0, bool restrictServices = true,
const QString &executable
= QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene");
@@ -246,7 +246,7 @@ private:
#define VERIFY(type, position, expected, checks, numbers) \
QVERIFY(verify(type, position, expected, checks, numbers))
-QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
+QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connectTo(
bool block, const QString &file, bool recordFromStart, uint flushInterval,
bool restrictServices, const QString &executable)
{
@@ -255,7 +255,7 @@ QQmlDebugTest::ConnectResult tst_QQmlProfilerService::connect(
m_isComplete = false;
// ### Still using qmlscene due to QTBUG-33377
- return QQmlDebugTest::connect(
+ return QQmlDebugTest::connectTo(
executable,
restrictServices ? "CanvasFrameRate,EngineControl,DebugMessages" : QString(),
testFile(file), block);
@@ -542,7 +542,7 @@ void tst_QQmlProfilerService::connect()
QFETCH(bool, restrictMode);
QFETCH(bool, traceEnabled);
- QCOMPARE(connect(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
+ QCOMPARE(connectTo(blockMode, "test.qml", traceEnabled, 0, restrictMode), ConnectSuccess);
if (!traceEnabled)
m_client->client->setRecording(true);
@@ -556,7 +556,7 @@ void tst_QQmlProfilerService::connect()
void tst_QQmlProfilerService::pixmapCacheData()
{
- QCOMPARE(connect(true, "pixmapCacheTest.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "pixmapCacheTest.qml"), ConnectSuccess);
// Don't wait for readyReadStandardOutput before the loop. It may have already arrived.
while (m_process->output().indexOf(QLatin1String("image loaded")) == -1 &&
@@ -594,7 +594,7 @@ void tst_QQmlProfilerService::pixmapCacheData()
void tst_QQmlProfilerService::scenegraphData()
{
- QCOMPARE(connect(true, "scenegraphTest.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "scenegraphTest.qml"), ConnectSuccess);
while (!m_process->output().contains(QLatin1String("tick")))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
@@ -654,7 +654,7 @@ void tst_QQmlProfilerService::scenegraphData()
void tst_QQmlProfilerService::profileOnExit()
{
- QCOMPARE(connect(true, "exit.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "exit.qml"), ConnectSuccess);
checkProcessTerminated();
checkTraceReceived();
@@ -663,7 +663,7 @@ void tst_QQmlProfilerService::profileOnExit()
void tst_QQmlProfilerService::controlFromJS()
{
- QCOMPARE(connect(true, "controlFromJS.qml", false), ConnectSuccess);
+ QCOMPARE(connectTo(true, "controlFromJS.qml", false), ConnectSuccess);
QTRY_VERIFY(m_client->numLoadedEventTypes() > 0);
m_client->client->setRecording(false);
@@ -673,7 +673,7 @@ void tst_QQmlProfilerService::controlFromJS()
void tst_QQmlProfilerService::signalSourceLocation()
{
- QCOMPARE(connect(true, "signalSourceLocation.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "signalSourceLocation.qml"), ConnectSuccess);
while (!(m_process->output().contains(QLatin1String("500"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
@@ -694,7 +694,7 @@ void tst_QQmlProfilerService::signalSourceLocation()
void tst_QQmlProfilerService::javascript()
{
- QCOMPARE(connect(true, "javascript.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "javascript.qml"), ConnectSuccess);
while (!(m_process->output().contains(QLatin1String("done"))))
QVERIFY(QQmlDebugTest::waitForSignal(m_process, SIGNAL(readyReadStandardOutput())));
@@ -722,7 +722,7 @@ void tst_QQmlProfilerService::javascript()
void tst_QQmlProfilerService::flushInterval()
{
- QCOMPARE(connect(true, "timer.qml", true, 1), ConnectSuccess);
+ QCOMPARE(connectTo(true, "timer.qml", true, 1), ConnectSuccess);
// Make sure we get multiple messages
QTRY_VERIFY(m_client->qmlMessages.length() > 0);
@@ -736,7 +736,7 @@ void tst_QQmlProfilerService::flushInterval()
void tst_QQmlProfilerService::translationBinding()
{
- QCOMPARE(connect(true, "qstr.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "qstr.qml"), ConnectSuccess);
checkProcessTerminated();
checkTraceReceived();
@@ -752,7 +752,7 @@ void tst_QQmlProfilerService::translationBinding()
void tst_QQmlProfilerService::memory()
{
- QCOMPARE(connect(true, "memory.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "memory.qml"), ConnectSuccess);
checkProcessTerminated();
checkTraceReceived();
@@ -781,7 +781,7 @@ static bool hasCompileEvents(const QVector<QQmlProfilerEventType> &types)
void tst_QQmlProfilerService::compile()
{
// Flush interval so that we actually get the events before we stop recording.
- connect(true, "test.qml", true, 100);
+ connectTo(true, "test.qml", true, 100);
QVERIFY(m_client);
@@ -820,7 +820,7 @@ void tst_QQmlProfilerService::compile()
void tst_QQmlProfilerService::multiEngine()
{
- QCOMPARE(connect(true, "quit.qml", true, 0, false, debugJsServerPath("qqmlprofilerservice")),
+ QCOMPARE(connectTo(true, "quit.qml", true, 0, false, debugJsServerPath("qqmlprofilerservice")),
ConnectSuccess);
QSignalSpy spy(m_client->client, SIGNAL(complete(qint64)));
@@ -837,7 +837,7 @@ void tst_QQmlProfilerService::multiEngine()
void tst_QQmlProfilerService::batchOverflow()
{
// The trace client checks that the events are received in order.
- QCOMPARE(connect(true, "batchOverflow.qml"), ConnectSuccess);
+ QCOMPARE(connectTo(true, "batchOverflow.qml"), ConnectSuccess);
checkProcessTerminated();
checkTraceReceived();
checkJsHeap();
diff --git a/tests/auto/qml/debugger/shared/debugutil.cpp b/tests/auto/qml/debugger/shared/debugutil.cpp
index 68446b53a4..3787f34bc2 100644
--- a/tests/auto/qml/debugger/shared/debugutil.cpp
+++ b/tests/auto/qml/debugger/shared/debugutil.cpp
@@ -120,7 +120,7 @@ void QQmlDebugTestClient::messageReceived(const QByteArray &ba)
emit serverMessage(ba);
}
-QQmlDebugTest::ConnectResult QQmlDebugTest::connect(
+QQmlDebugTest::ConnectResult QQmlDebugTest::connectTo(
const QString &executable, const QString &services, const QString &extraArgs,
bool block)
{
diff --git a/tests/auto/qml/debugger/shared/debugutil_p.h b/tests/auto/qml/debugger/shared/debugutil_p.h
index 1c32590305..190909dc44 100644
--- a/tests/auto/qml/debugger/shared/debugutil_p.h
+++ b/tests/auto/qml/debugger/shared/debugutil_p.h
@@ -53,7 +53,6 @@ public:
static QString clientStateString(const QQmlDebugClient *client);
static QString connectionStateString(const QQmlDebugConnection *connection);
-protected:
enum ConnectResult {
ConnectSuccess,
ProcessFailed,
@@ -64,7 +63,9 @@ protected:
RestrictFailed
};
- ConnectResult connect(const QString &executable, const QString &services,
+ Q_ENUM(ConnectResult)
+protected:
+ ConnectResult connectTo(const QString &executable, const QString &services,
const QString &extraArgs, bool block);
virtual QQmlDebugProcess *createProcess(const QString &executable);
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 4c04afe886..6b743ba433 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -249,15 +249,6 @@ built-ins/String/prototype/toLocaleLowerCase/Final_Sigma_U180E.js fails
built-ins/String/prototype/toLocaleLowerCase/special_casing_conditional.js fails
built-ins/String/prototype/toLowerCase/Final_Sigma_U180E.js fails
built-ins/String/prototype/toLowerCase/special_casing_conditional.js fails
-built-ins/TypedArray/from/arylk-get-length-error.js fails
-built-ins/TypedArray/from/arylk-to-length-error.js fails
-built-ins/TypedArray/from/iter-access-error.js fails
-built-ins/TypedArray/from/iter-invoke-error.js fails
-built-ins/TypedArray/from/iter-next-error.js fails
-built-ins/TypedArray/from/iter-next-value-error.js fails
-built-ins/TypedArray/from/length.js fails
-built-ins/TypedArray/from/name.js fails
-built-ins/TypedArray/from/prop-desc.js fails
built-ins/TypedArray/prototype/constructor.js fails
built-ins/TypedArray/prototype/fill/fill-values-conversion-operations-consistent-nan.js fails
built-ins/TypedArray/prototype/slice/bit-precision.js fails
@@ -293,29 +284,6 @@ built-ins/TypedArrays/ctors/typedarray-arg/same-ctor-buffer-ctor-species-not-cto
built-ins/TypedArrays/ctors/typedarray-arg/same-ctor-buffer-ctor-species-prototype-throws.js fails
built-ins/TypedArrays/ctors/typedarray-arg/same-ctor-buffer-ctor-species-throws.js fails
built-ins/TypedArrays/ctors/typedarray-arg/same-ctor-buffer-ctor-value-not-obj-throws.js fails
-built-ins/TypedArrays/from/arylk-get-length-error.js fails
-built-ins/TypedArrays/from/arylk-to-length-error.js fails
-built-ins/TypedArrays/from/custom-ctor-returns-other-instance.js fails
-built-ins/TypedArrays/from/custom-ctor.js fails
-built-ins/TypedArrays/from/iter-access-error.js fails
-built-ins/TypedArrays/from/iter-invoke-error.js fails
-built-ins/TypedArrays/from/iter-next-error.js fails
-built-ins/TypedArrays/from/iter-next-value-error.js fails
-built-ins/TypedArrays/from/mapfn-abrupt-completion.js fails
-built-ins/TypedArrays/from/mapfn-arguments.js fails
-built-ins/TypedArrays/from/mapfn-this-with-thisarg.js fails
-built-ins/TypedArrays/from/mapfn-this-without-thisarg-non-strict.js sloppyFails
-built-ins/TypedArrays/from/mapfn-this-without-thisarg-strict.js strictFails
-built-ins/TypedArrays/from/nan-conversion.js fails
-built-ins/TypedArrays/from/new-instance-empty.js fails
-built-ins/TypedArrays/from/new-instance-from-ordinary-object.js fails
-built-ins/TypedArrays/from/new-instance-from-sparse-array.js fails
-built-ins/TypedArrays/from/new-instance-from-zero.js fails
-built-ins/TypedArrays/from/new-instance-using-custom-ctor.js fails
-built-ins/TypedArrays/from/new-instance-with-mapfn.js fails
-built-ins/TypedArrays/from/new-instance-without-mapfn.js fails
-built-ins/TypedArrays/from/property-abrupt-completion.js fails
-built-ins/TypedArrays/from/set-value-abrupt-completion.js fails
built-ins/TypedArrays/internals/Get/key-is-not-integer.js fails
built-ins/TypedArrays/internals/Get/key-is-not-minus-zero.js fails
built-ins/TypedArrays/internals/Get/key-is-out-of-bounds.js fails
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 66a526fda8..26737e79c4 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -263,6 +263,9 @@ private slots:
void arrayIncludesWithLargeArray();
void printCircularArray();
void typedArraySet();
+ void dataViewCtor();
+
+ void uiLanguage();
public:
Q_INVOKABLE QJSValue throwingCppMethod1();
@@ -1543,7 +1546,7 @@ void tst_QJSEngine::valueConversion_QVariant()
{
QVariant tmp1;
QVariant tmp2(QMetaType::QVariant, &tmp1);
- QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant);
+ QCOMPARE(QMetaType::Type(tmp2.userType()), QMetaType::QVariant);
QJSValue val1 = eng.toScriptValue(tmp1);
QJSValue val2 = eng.toScriptValue(tmp2);
@@ -1558,9 +1561,9 @@ void tst_QJSEngine::valueConversion_QVariant()
QVariant tmp1(123);
QVariant tmp2(QMetaType::QVariant, &tmp1);
QVariant tmp3(QMetaType::QVariant, &tmp2);
- QCOMPARE(QMetaType::Type(tmp1.type()), QMetaType::Int);
- QCOMPARE(QMetaType::Type(tmp2.type()), QMetaType::QVariant);
- QCOMPARE(QMetaType::Type(tmp3.type()), QMetaType::QVariant);
+ QCOMPARE(QMetaType::Type(tmp1.userType()), QMetaType::Int);
+ QCOMPARE(QMetaType::Type(tmp2.userType()), QMetaType::QVariant);
+ QCOMPARE(QMetaType::Type(tmp3.userType()), QMetaType::QVariant);
QJSValue val1 = eng.toScriptValue(tmp2);
QJSValue val2 = eng.toScriptValue(tmp3);
@@ -3340,7 +3343,7 @@ void tst_QJSEngine::dateRoundtripJSQtJS()
#ifdef Q_OS_WIN
QSKIP("This test fails on Windows due to a bug in QDateTime.");
#endif
- qint64 secs = QDateTime(QDate(2009, 1, 1)).toUTC().toSecsSinceEpoch();
+ qint64 secs = QDate(2009, 1, 1).startOfDay(Qt::UTC).toSecsSinceEpoch();
QJSEngine eng;
for (int i = 0; i < 8000; ++i) {
QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0));
@@ -3357,7 +3360,7 @@ void tst_QJSEngine::dateRoundtripQtJSQt()
#ifdef Q_OS_WIN
QSKIP("This test fails on Windows due to a bug in QDateTime.");
#endif
- QDateTime qtDate = QDateTime(QDate(2009, 1, 1));
+ QDateTime qtDate = QDate(2009, 1, 1).startOfDay();
QJSEngine eng;
for (int i = 0; i < 8000; ++i) {
QJSValue jsDate = eng.toScriptValue(qtDate);
@@ -3373,7 +3376,7 @@ void tst_QJSEngine::dateConversionJSQt()
#ifdef Q_OS_WIN
QSKIP("This test fails on Windows due to a bug in QDateTime.");
#endif
- qint64 secs = QDateTime(QDate(2009, 1, 1)).toUTC().toSecsSinceEpoch();
+ qint64 secs = QDate(2009, 1, 1).startOfDay(Qt::UTC).toSecsSinceEpoch();
QJSEngine eng;
for (int i = 0; i < 8000; ++i) {
QJSValue jsDate = eng.evaluate(QString::fromLatin1("new Date(%0)").arg(secs * 1000.0));
@@ -3389,7 +3392,7 @@ void tst_QJSEngine::dateConversionJSQt()
void tst_QJSEngine::dateConversionQtJS()
{
- QDateTime qtDate = QDateTime(QDate(2009, 1, 1));
+ QDateTime qtDate = QDate(2009, 1, 1).startOfDay();
QJSEngine eng;
for (int i = 0; i < 8000; ++i) {
QJSValue jsDate = eng.toScriptValue(qtDate);
@@ -5143,6 +5146,48 @@ void tst_QJSEngine::typedArraySet()
}
}
+void tst_QJSEngine::dataViewCtor()
+{
+ QJSEngine engine;
+ const auto error = engine.evaluate(R"(
+ (function() { try {
+ var buf = new ArrayBuffer(0x200);
+ var vuln = new DataView(buf, 8, 0xfffffff8);
+ } catch (e) {
+ return e;
+ }})()
+ )");
+ QVERIFY(error.isError());
+ QCOMPARE(error.toString(), "RangeError: DataView: constructor arguments out of range");
+}
+
+void tst_QJSEngine::uiLanguage()
+{
+ {
+ QJSEngine engine;
+
+ QVERIFY(!engine.globalObject().hasProperty("Qt"));
+
+ engine.installExtensions(QJSEngine::TranslationExtension);
+ QVERIFY(engine.globalObject().hasProperty("Qt"));
+ QVERIFY(engine.globalObject().property("Qt").hasProperty("uiLanguage"));
+
+ engine.setUiLanguage("Blah");
+ QCOMPARE(engine.globalObject().property("Qt").property("uiLanguage").toString(), "Blah");
+
+ engine.evaluate("Qt.uiLanguage = \"another\"");
+ QCOMPARE(engine.globalObject().property("Qt").property("uiLanguage").toString(), "another");
+ }
+
+ {
+ QQmlEngine qmlEngine;
+ QVERIFY(qmlEngine.globalObject().hasProperty("Qt"));
+ QVERIFY(qmlEngine.globalObject().property("Qt").hasProperty("uiLanguage"));
+ qmlEngine.setUiLanguage("Blah");
+ QCOMPARE(qmlEngine.globalObject().property("Qt").property("uiLanguage").toString(), "Blah");
+ }
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
index cab4686c37..0d0bd2ae7e 100644
--- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
+++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp
@@ -1067,7 +1067,7 @@ void tst_QJSValue::toVariant()
}
{
- QDateTime dateTime = QDateTime(QDate(1980, 10, 4));
+ QDateTime dateTime = QDate(1980, 10, 4).startOfDay();
QJSValue dateObject = eng.toScriptValue(dateTime);
QVariant var = dateObject.toVariant();
QCOMPARE(var, QVariant(dateTime));
@@ -1081,7 +1081,7 @@ void tst_QJSValue::toVariant()
// We can't roundtrip a QRegExp this way, as toVariant() has no information on whether we
// want QRegExp or QRegularExpression. It will always create a QRegularExpression.
- QCOMPARE(var.type(), QMetaType::QRegularExpression);
+ QCOMPARE(var.userType(), QMetaType::QRegularExpression);
QRegularExpression result = var.toRegularExpression();
QCOMPARE(result.pattern(), rx.pattern());
QCOMPARE(result.patternOptions() & QRegularExpression::CaseInsensitiveOption, 0);
@@ -1138,7 +1138,7 @@ void tst_QJSValue::toVariant()
QVERIFY(array.isArray());
QCOMPARE(array.property("length").toInt(), 2);
QVariant ret = array.toVariant();
- QCOMPARE(ret.type(), QVariant::List);
+ QCOMPARE(ret.userType(), QVariant::List);
QVariantList listOut = ret.toList();
QCOMPARE(listOut.size(), listIn.size());
for (int i = 0; i < listIn.size(); ++i)
@@ -1222,7 +1222,7 @@ void tst_QJSValue::toDateTime()
QDateTime dt = eng.evaluate("new Date(0)").toDateTime();
QVERIFY(dt.isValid());
QCOMPARE(dt.timeSpec(), Qt::LocalTime);
- QCOMPARE(dt.toUTC(), QDateTime(QDate(1970, 1, 1), QTime(0, 0, 0), Qt::UTC));
+ QCOMPARE(dt.toUTC(), QDate(1970, 1, 1).startOfDay(Qt::UTC));
QVERIFY(!eng.evaluate("[]").toDateTime().isValid());
QVERIFY(!eng.evaluate("{}").toDateTime().isValid());
@@ -2145,8 +2145,8 @@ void tst_QJSValue::equals()
QCOMPARE(str2.equals(QJSValue(321)), false);
QCOMPARE(str2.equals(QJSValue()), false);
- QJSValue date1 = eng.toScriptValue(QDateTime(QDate(2000, 1, 1)));
- QJSValue date2 = eng.toScriptValue(QDateTime(QDate(1999, 1, 1)));
+ QJSValue date1 = eng.toScriptValue(QDate(2000, 1, 1).startOfDay());
+ QJSValue date2 = eng.toScriptValue(QDate(1999, 1, 1).startOfDay());
QCOMPARE(date1.equals(date2), false);
QCOMPARE(date1.equals(date1), true);
QCOMPARE(date2.equals(date2), true);
@@ -2278,8 +2278,8 @@ void tst_QJSValue::strictlyEquals()
QCOMPARE(str2.strictlyEquals(QJSValue(321)), false);
QVERIFY(!str2.strictlyEquals(QJSValue()));
- QJSValue date1 = eng.toScriptValue(QDateTime(QDate(2000, 1, 1)));
- QJSValue date2 = eng.toScriptValue(QDateTime(QDate(1999, 1, 1)));
+ QJSValue date1 = eng.toScriptValue(QDate(2000, 1, 1).startOfDay());
+ QJSValue date2 = eng.toScriptValue(QDate(1999, 1, 1).startOfDay());
QCOMPARE(date1.strictlyEquals(date2), false);
QCOMPARE(date1.strictlyEquals(date1), true);
QCOMPARE(date2.strictlyEquals(date2), true);
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index db9bb52010..621e8bb437 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -91,7 +91,7 @@ SUBDIRS += $$METATYPETESTS
qtConfig(process) {
qtConfig(qml-debug): SUBDIRS += debugger
!boot2qt {
- SUBDIRS += qmllint qmlplugindump
+ SUBDIRS += qmlformat qmllint qmlplugindump
}
}
@@ -105,3 +105,6 @@ qtConfig(private_tests): \
qtNomakeTools( \
qmlplugindump \
)
+
+!cross_compile: \
+ SUBDIRS += qmltyperegistrar
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/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
index 4daf1d35c3..452bd7d04a 100644
--- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro
+++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro
@@ -28,7 +28,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 4a1f5378a6..f940f9c476 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -363,7 +363,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;
@@ -390,12 +390,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);
@@ -417,7 +413,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"));
@@ -506,7 +502,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());
@@ -587,7 +583,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);
@@ -610,7 +606,6 @@ void tst_qmlcachegen::moduleScriptImport()
void tst_qmlcachegen::esModulesViaQJSEngine()
{
- QCOMPARE(QFileInfo(":/data/module.mjs").size(), 0);
QJSEngine engine;
QJSValue module = engine.importModule(":/data/module.mjs");
QJSValue result = module.property("entry").call();
@@ -629,7 +624,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(
@@ -644,8 +639,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/qmldiskcache/tst_qmldiskcache.cpp b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
index 1f0115b926..d0c8390a74 100644
--- a/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
+++ b/tests/auto/qml/qmldiskcache/tst_qmldiskcache.cpp
@@ -87,7 +87,9 @@ public:
void waitForLoad()
{
- QTRY_VERIFY(status() == QQmlComponent::Ready || status() == QQmlComponent::Error);
+ QTRY_VERIFY_WITH_TIMEOUT(
+ status() == QQmlComponent::Ready || status() == QQmlComponent::Error,
+ 32768);
}
};
diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml
new file mode 100644
index 0000000000..a05c2125dc
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.nosort.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+@Pippo {
+ atg1: 3
+}
+@Annotation2 {
+}
+Item {
+ //![1]
+
+ @AnnotateMore {
+ property int x: 5
+ }
+ @AnnotateALot {
+ }
+
+ property variant othersSlice: 0
+ @Annotate {
+ }
+
+ anchors.fill: parent
+ @SuperComplete {
+ binding: late
+ }
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+ ChartView {
+ id: chart
+
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+ @ExtraAnnotation {
+ signal pippo()
+ }
+ PieSeries {
+ id: pieSeries
+
+ PieSlice {
+ label: "Volkswagen"
+ value: 13.5
+ }
+
+ PieSlice {
+ label: "Toyota"
+ value: 10.9
+ }
+
+ PieSlice {
+ label: "Ford"
+ value: 8.6
+ }
+
+ PieSlice {
+ label: "Skoda"
+ value: 8.2
+ }
+
+ PieSlice {
+ label: "Volvo"
+ value: 6.8
+ }
+
+ }
+
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Annotations.formatted.qml b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml
new file mode 100644
index 0000000000..a142d4cb74
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.formatted.qml
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtCharts 2.0
+//![2]
+import QtQuick 2.0
+
+@Pippo {
+ atg1: 3
+}
+@Annotation2 {
+}
+Item {
+ //![1]
+
+ @AnnotateMore {
+ property int x: 5
+ }
+ @AnnotateALot {
+ }
+
+ property variant othersSlice: 0
+ @Annotate {
+ }
+
+ anchors.fill: parent
+ @SuperComplete {
+ binding: late
+ }
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+ ChartView {
+ id: chart
+
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+ @ExtraAnnotation {
+ signal pippo()
+ }
+ PieSeries {
+ id: pieSeries
+
+ PieSlice {
+ label: "Volkswagen"
+ value: 13.5
+ }
+
+ PieSlice {
+ label: "Toyota"
+ value: 10.9
+ }
+
+ PieSlice {
+ label: "Ford"
+ value: 8.6
+ }
+
+ PieSlice {
+ label: "Skoda"
+ value: 8.2
+ }
+
+ PieSlice {
+ label: "Volvo"
+ value: 6.8
+ }
+
+ }
+
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Annotations.qml b/tests/auto/qml/qmlformat/data/Annotations.qml
new file mode 100644
index 0000000000..2d3d7d2cfd
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Annotations.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+@Pippo{ atg1:3 }
+@Annotation2{}
+Item {
+ @Annotate{}
+ anchors.fill: parent
+ @AnnotateMore{
+ property int x: 5
+ }
+ @AnnotateALot{}
+ property variant othersSlice: 0
+
+ //![1]
+ ChartView {
+ id: chart
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+@ExtraAnnotation{
+ signal pippo
+}
+ PieSeries {
+ id: pieSeries
+ PieSlice { label: "Volkswagen"; value: 13.5 }
+ PieSlice { label: "Toyota"; value: 10.9 }
+ PieSlice { label: "Ford"; value: 8.6 }
+ PieSlice { label: "Skoda"; value: 8.2 }
+ PieSlice { label: "Volvo"; value: 6.8 }
+ }
+ }
+
+@SuperComplete{
+binding: late
+}
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52.0);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+}
diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml
new file mode 100644
index 0000000000..34d58cf571
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Example1.formatted.nosort.qml
@@ -0,0 +1,152 @@
+/* This file is licensed under the not a license license
+ 1. You may not comply
+ 2. Goodbye
+*/
+
+// Importing this is very important
+import QtQuick 5.15
+// Muddling the waters!
+import QtQuick.Models 3.14 as muddle
+// Importing that is important too
+import Z
+import That
+import This // THIS IS VERY IMPORTANT!
+import Y
+import X.Z
+import X.Y
+import A.LLOHA
+import A.B.B.A
+
+// This comment is related to Item
+Item {
+ // Orphan comment
+ // Another orphan
+ // More orphans
+
+ // This to id
+ // Also id. (line 2)
+ // This is the third id
+ // fourth id comment
+ id: foo
+
+ // This to enum
+ enum Foo {
+ A = 3, // This is A
+ B, // This is B
+ C = 4, // This is C
+ D // This is D
+ }
+
+ property bool some_bool: false
+ property variant some_array_literal: [30, 20, Math["PI"], [4, 3, 2], "foo", 0.3]
+ property bool something_computed: function(x) {
+ // This is an orphan inside something_computed
+ // Are these getting duplicated?
+ // Another orphan inside something_computed
+
+ const PI = 3, DAYS_PER_YEAR = 365.25;
+ var x = 3 + 2;
+ x["bla"] = 50;
+ // This one to var few!
+ var few = new WhatEver();
+ x += Math.sin(3);
+ x--;
+ --x;
+ x++;
+ ++x;
+ for (var x = 0; x < 100; x++) {
+ x++;
+ console.log("Foo");
+ }
+ for (var x in [3, 2, 1]) {
+ y++;
+ console.log("Bar");
+ }
+ while (true)
+ console.log("Wee");
+
+ with (foo) {
+ bar;
+ x += 5;
+ } // This is related to with!
+ x3:
+ do {
+ console.log("Hello");
+ } while (3 == 0);
+ try {
+ dangerous();
+ } catch (e) {
+ console.log(e);
+ } finally {
+ dangerous();
+ }
+ switch (x) {
+ case 0:
+ x = 1;
+ break;
+ case 1:
+ x = 5;
+ break;
+ case 4:
+ x = 100;
+ break;
+ }
+ if (x == 50)
+ console.log("true");
+ else if (x == 50)
+ console.log("other thing");
+ else
+ console.log("false");
+
+ if (x == 50) {
+ console.log("true");
+ } else if (x == 50) {
+ console.log("other thing");
+ x--;
+ } else {
+ console.log("false");
+ }
+ return "foobar";
+ }()
+ default property bool some_default_bool: 500 % 5 !== 0 // some_default_bool
+ // some_read_only_bool
+ readonly property bool some_read_only_bool: Math.sin(3) && (aFunc()[30] + 5) | 2 != 0
+
+ signal say(string name, bool caps)
+
+ // This one to aFunc()
+ function aFunc() {
+ var x = 3;
+ return x;
+ }
+
+ x: 3 // Very cool
+ Component.onCompleted: console.log("Foo!")
+ myFavouriteThings: [
+ // This is an orphan
+
+ // This is a cool text
+ Text {
+ },
+ // This is a cool rectangle
+ Rectangle {
+ }
+ ]
+
+ Text {
+ required property string batman
+
+ signal boo(int count, int times, real duration)
+
+ text: "Bla"
+ }
+
+ // This comment is related to the property animation
+ PropertyAnimation on x {
+ id: foo
+
+ x: 3
+ y: x + 3
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Example1.formatted.qml b/tests/auto/qml/qmlformat/data/Example1.formatted.qml
new file mode 100644
index 0000000000..b06734eb0b
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Example1.formatted.qml
@@ -0,0 +1,152 @@
+/* This file is licensed under the not a license license
+ 1. You may not comply
+ 2. Goodbye
+*/
+
+import A.B.B.A
+import A.LLOHA
+// Importing this is very important
+import QtQuick 5.15
+// Muddling the waters!
+import QtQuick.Models 3.14 as muddle
+import That
+import This // THIS IS VERY IMPORTANT!
+import X.Y
+import X.Z
+import Y
+// Importing that is important too
+import Z
+
+// This comment is related to Item
+Item {
+ // Orphan comment
+ // Another orphan
+ // More orphans
+
+ // This to id
+ // Also id. (line 2)
+ // This is the third id
+ // fourth id comment
+ id: foo
+
+ // This to enum
+ enum Foo {
+ A = 3, // This is A
+ B, // This is B
+ C = 4, // This is C
+ D // This is D
+ }
+
+ property bool some_bool: false
+ property variant some_array_literal: [30, 20, Math["PI"], [4, 3, 2], "foo", 0.3]
+ property bool something_computed: function(x) {
+ // This is an orphan inside something_computed
+ // Are these getting duplicated?
+ // Another orphan inside something_computed
+
+ const PI = 3, DAYS_PER_YEAR = 365.25;
+ var x = 3 + 2;
+ x["bla"] = 50;
+ // This one to var few!
+ var few = new WhatEver();
+ x += Math.sin(3);
+ x--;
+ --x;
+ x++;
+ ++x;
+ for (var x = 0; x < 100; x++) {
+ x++;
+ console.log("Foo");
+ }
+ for (var x in [3, 2, 1]) {
+ y++;
+ console.log("Bar");
+ }
+ while (true)
+ console.log("Wee");
+
+ with (foo) {
+ bar;
+ x += 5;
+ } // This is related to with!
+ x3:
+ do {
+ console.log("Hello");
+ } while (3 == 0);
+ try {
+ dangerous();
+ } catch (e) {
+ console.log(e);
+ } finally {
+ dangerous();
+ }
+ switch (x) {
+ case 0:
+ x = 1;
+ break;
+ case 1:
+ x = 5;
+ break;
+ case 4:
+ x = 100;
+ break;
+ }
+ if (x == 50)
+ console.log("true");
+ else if (x == 50)
+ console.log("other thing");
+ else
+ console.log("false");
+
+ if (x == 50) {
+ console.log("true");
+ } else if (x == 50) {
+ console.log("other thing");
+ x--;
+ } else {
+ console.log("false");
+ }
+ return "foobar";
+ }()
+ default property bool some_default_bool: 500 % 5 !== 0 // some_default_bool
+ // some_read_only_bool
+ readonly property bool some_read_only_bool: Math.sin(3) && (aFunc()[30] + 5) | 2 != 0
+
+ signal say(string name, bool caps)
+
+ // This one to aFunc()
+ function aFunc() {
+ var x = 3;
+ return x;
+ }
+
+ x: 3 // Very cool
+ Component.onCompleted: console.log("Foo!")
+ myFavouriteThings: [
+ // This is an orphan
+
+ // This is a cool text
+ Text {
+ },
+ // This is a cool rectangle
+ Rectangle {
+ }
+ ]
+
+ Text {
+ required property string batman
+
+ signal boo(int count, int times, real duration)
+
+ text: "Bla"
+ }
+
+ // This comment is related to the property animation
+ PropertyAnimation on x {
+ id: foo
+
+ x: 3
+ y: x + 3
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/Example1.qml b/tests/auto/qml/qmlformat/data/Example1.qml
new file mode 100644
index 0000000000..0fb9053e3a
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/Example1.qml
@@ -0,0 +1,105 @@
+
+
+/* This file is licensed under the not a license license
+ 1. You may not comply
+ 2. Goodbye
+*/
+
+// Importing this is very important
+import QtQuick 5.15
+// Muddling the waters!
+import QtQuick.Models 3.14 as muddle
+// Importing that is important too
+import Z
+import That
+import This // THIS IS VERY IMPORTANT!
+import Y
+import X.Z
+import X.Y
+import A.LLOHA
+import A.B.B.A
+
+// This comment is related to Item
+Item {
+ x: 3 // Very cool
+
+ // This to enum
+ enum Foo {
+ A = 3, // This is A
+ B, // This is B
+ C = 4, // This is C
+ D // This is D
+ }
+
+ // This one to aFunc()
+ function aFunc() {
+ var x = 3;
+ return x;
+ }
+
+ property bool some_bool : false
+ // This comment is related to the property animation
+ PropertyAnimation on x {
+ id: foo; x: 3; y: x + 3
+ }
+
+ // Orphan comment
+
+ // Another orphan
+
+ // More orphans
+
+
+ property variant some_array_literal: [30,20,Math["PI"],[4,3,2],"foo",0.3]
+ property bool something_computed: function(x) {
+ const PI = 3, DAYS_PER_YEAR=365.25; var x = 3 + 2; x["bla"] = 50;
+
+ // This is an orphan inside something_computed
+
+ // Are these getting duplicated?
+
+
+ // This one to var few!
+ var few = new WhatEver();
+ x += Math.sin(3); x--; --x; x++; ++x;
+ for (var x = 0; x < 100; x++) { x++; console.log("Foo"); }
+ for (var x in [3,2,1]) { y++; console.log("Bar"); }
+ while (true) { console.log("Wee"); }
+ with (foo) { bar; x+=5; } // This is related to with!
+ x3:
+ do { console.log("Hello"); } while (3 == 0)
+ try { dangerous(); } catch(e) { console.log(e); } finally { console.log("What else?"); }
+ switch (x) { case 0: x = 1; break; case 1: x = 5; break; case 4: x = 100; break; }
+ if (x == 50) { console.log("true"); } else if (x == 50) { console.log("other thing"); } else { console.log("false"); }
+ if (x == 50) { console.log("true"); } else if (x == 50) { console.log("other thing"); x--; } else { console.log("false"); }
+
+ // Another orphan inside something_computed
+
+ return "foobar"; }();
+
+ default property bool some_default_bool : 500 % 5 !== 0 // some_default_bool
+
+ myFavouriteThings: [
+ // This is an orphan
+
+ // This is a cool text
+ Text {},
+ // This is a cool rectangle
+ Rectangle {}]
+
+ // some_read_only_bool
+ readonly property bool some_read_only_bool : Math.sin(3) && (aFunc()[30] + 5) | 2 != 0
+
+ signal say(string name, bool caps);
+
+ Text { text: "Bla"; signal boo(int count, int times, real duration); required property string batman; }
+
+ Component.onCompleted: console.log("Foo!");
+
+ // This to id
+ // Also id. (line 2)
+ // This is the third id
+ // fourth id comment
+ id: foo
+
+}
diff --git a/tests/auto/qml/qmlformat/data/FrontInline.formatted.qml b/tests/auto/qml/qmlformat/data/FrontInline.formatted.qml
new file mode 100644
index 0000000000..620fbf4120
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/FrontInline.formatted.qml
@@ -0,0 +1,3 @@
+// This comment should be directly above Item after formatting
+Item {
+}
diff --git a/tests/auto/qml/qmlformat/data/FrontInline.qml b/tests/auto/qml/qmlformat/data/FrontInline.qml
new file mode 100644
index 0000000000..c63265481c
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/FrontInline.qml
@@ -0,0 +1,2 @@
+Item { // This comment should be directly above Item after formatting
+}
diff --git a/tests/auto/qml/qmlformat/data/IfBlocks.formatted.qml b/tests/auto/qml/qmlformat/data/IfBlocks.formatted.qml
new file mode 100644
index 0000000000..b8e77ec23a
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/IfBlocks.formatted.qml
@@ -0,0 +1,63 @@
+Item {
+
+ function test() {
+ //// The following if blocks should NOT HAVE braces
+ // Single branch, no braces
+ if (true)
+ console.log("foo");
+
+ // Single branch, no braces
+ if (true)
+ console.log("foo");
+
+ // Multiple branches, No braces
+ if (true)
+ console.log("foo");
+ else if (false)
+ console.log("bar");
+ else
+ console.log("baz");
+ // Multiple branches, all braces
+ if (true)
+ console.log("foo");
+ else if (false)
+ console.log("bar");
+ else
+ console.log("baz");
+
+ //// The following if blocks should HAVE braces
+ // Single branch, braces
+ if (true) {
+ console.log("foo");
+ console.log("bar");
+ }
+ // Multiple branches, some braces
+ if (true) {
+ console.log("foo");
+ console.log("foo2");
+ } else if (false) {
+ console.log("bar");
+ } else {
+ console.log("baz");
+ }
+ // Multiple branches, some braces
+ if (true) {
+ console.log("foo");
+ } else if (false) {
+ console.log("bar");
+ console.log("bar2");
+ } else {
+ console.log("baz");
+ }
+ // Multiple branches, some braces
+ if (true) {
+ console.log("foo");
+ } else if (false) {
+ console.log("bar");
+ } else {
+ console.log("baz");
+ console.log("baz2");
+ }
+ }
+
+}
diff --git a/tests/auto/qml/qmlformat/data/IfBlocks.qml b/tests/auto/qml/qmlformat/data/IfBlocks.qml
new file mode 100644
index 0000000000..505988b238
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/IfBlocks.qml
@@ -0,0 +1,66 @@
+Item {
+ function test() {
+ //// The following if blocks should NOT HAVE braces
+ // Single branch, no braces
+ if (true)
+ console.log("foo");
+
+ // Single branch, no braces
+ if (true) {
+ console.log("foo");
+ }
+
+
+ // Multiple branches, No braces
+ if (true)
+ console.log("foo");
+ else if (false)
+ console.log("bar");
+ else
+ console.log("baz");
+
+ // Multiple branches, all braces
+ if (true) {
+ console.log("foo");
+ } else if (false) {
+ console.log("bar");
+ } else {
+ console.log("baz");
+ }
+
+ //// The following if blocks should HAVE braces
+ // Single branch, braces
+ if (true) {
+ console.log("foo");
+ console.log("bar");
+ }
+
+ // Multiple branches, some braces
+ if (true) {
+ console.log("foo");
+ console.log("foo2");
+ } else if (false)
+ console.log("bar");
+ else
+ console.log("baz");
+
+ // Multiple branches, some braces
+ if (true)
+ console.log("foo");
+ else if (false) {
+ console.log("bar");
+ console.log("bar2");
+ } else
+ console.log("baz");
+
+ // Multiple branches, some braces
+ if (true)
+ console.log("foo");
+ else if (false)
+ console.log("bar");
+ else {
+ console.log("baz");
+ console.log("baz2");
+ }
+ }
+}
diff --git a/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml
new file mode 100644
index 0000000000..6e7cc31dcf
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/readOnlyProps.formatted.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+QtObject {
+ // Testing UiObjectBinding
+ readonly property Item
+ item: Item {
+ id: test
+
+ signal foo()
+ }
+ // End comment
+
+ // Testing UiArrayBinding
+ readonly property list<Item> array: [
+ Item {
+ id: test1
+
+ signal foo()
+ },
+ Item {
+ id: test2
+
+ signal bar()
+ }
+ ]
+ // Testing UiScriptBinding
+ readonly property int script: Math.sin(Math.PI)
+ property bool normalProperty: true
+}
diff --git a/tests/auto/qml/qmlformat/data/readOnlyProps.qml b/tests/auto/qml/qmlformat/data/readOnlyProps.qml
new file mode 100644
index 0000000000..8a32dd131e
--- /dev/null
+++ b/tests/auto/qml/qmlformat/data/readOnlyProps.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+QtObject {
+ // Testing UiObjectBinding
+ readonly property Item item: Item { id: test; signal foo() }
+ // End comment
+
+ // Testing UiArrayBinding
+ readonly property list<Item> array: [ Item { id: test1; signal foo() }, Item { id: test2; signal bar() } ]
+
+ // Testing UiScriptBinding
+ readonly property int script: Math.sin(Math.PI)
+
+ property bool normalProperty: true
+}
diff --git a/tests/auto/qml/qmlformat/qmlformat.pro b/tests/auto/qml/qmlformat/qmlformat.pro
new file mode 100644
index 0000000000..a6ae391711
--- /dev/null
+++ b/tests/auto/qml/qmlformat/qmlformat.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qmlformat
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qmlformat.cpp
+DEFINES += SRCDIR=\\\"$$PWD\\\"
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+QT += testlib
diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
new file mode 100644
index 0000000000..5a8974b907
--- /dev/null
+++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** 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 <QtTest/QtTest>
+#include <QDir>
+#include <QFile>
+#include <QProcess>
+#include <QString>
+#include <QTemporaryDir>
+
+#include <util.h>
+
+class TestQmlformat: public QQmlDataTest
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initTestCase() override;
+
+ void testFormat();
+ void testFormatNoSort();
+ void testAnnotations();
+ void testAnnotationsNoSort();
+ void testLineEndings();
+ void testFrontInline();
+ void testIfBlocks();
+
+ void testReadOnlyProps();
+
+#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
+ void testExample();
+ void testExample_data();
+#endif
+
+private:
+ QString readTestFile(const QString &path);
+ QString runQmlformat(const QString &fileToFormat, bool sortImports, bool shouldSucceed, const QString &newlineFormat = "native");
+
+ QString m_qmlformatPath;
+ QStringList m_excludedDirs;
+ QStringList m_invalidFiles;
+
+ QStringList findFiles(const QDir &);
+ bool isInvalidFile(const QFileInfo &fileName) const;
+};
+
+void TestQmlformat::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+ m_qmlformatPath = QLibraryInfo::location(QLibraryInfo::BinariesPath) + QLatin1String("/qmlformat");
+#ifdef Q_OS_WIN
+ m_qmlformatPath += QLatin1String(".exe");
+#endif
+ if (!QFileInfo(m_qmlformatPath).exists()) {
+ QString message = QStringLiteral("qmlformat executable not found (looked for %0)").arg(m_qmlformatPath);
+ QFAIL(qPrintable(message));
+ }
+
+ // Add directories you want excluded here
+
+ // These snippets are not expected to run on their own.
+ m_excludedDirs << "doc/src/snippets/qml/visualdatamodel_rootindex";
+ m_excludedDirs << "doc/src/snippets/qml/qtbinding";
+ m_excludedDirs << "doc/src/snippets/qml/imports";
+ m_excludedDirs << "doc/src/snippets/qtquick1/visualdatamodel_rootindex";
+ m_excludedDirs << "doc/src/snippets/qtquick1/qtbinding";
+ m_excludedDirs << "doc/src/snippets/qtquick1/imports";
+ m_excludedDirs << "tests/manual/v4";
+ m_excludedDirs << "tests/auto/qml/ecmascripttests";
+ m_excludedDirs << "tests/auto/qml/qmllint";
+
+ // Add invalid files (i.e. files with syntax errors)
+ m_invalidFiles << "tests/auto/quick/qquickloader/data/InvalidSourceComponent.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.3.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/signal.5.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/property.4.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/empty.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/missingObject.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/insertedSemicolon.1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nonexistantProperty.5.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidRoot.1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/invalidQmlEnumValue.2.qml";
+ m_invalidFiles << "tests/auto/qml/qquickfolderlistmodel/data/dummy.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.3.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.4.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.5.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/stringParsing_error.6.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/numberParsing_error.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml";
+ m_invalidFiles << "tests/auto/qml/debugger/qqmlpreview/data/broken.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml";
+ m_invalidFiles << "tests/auto/qml/qqmllanguage/data/typeAnnotations.2.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlparser/data/disallowedtypeannotations/qmlnestedfunction.qml";
+
+ // These files rely on exact formatting
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon_error1.qml";
+ m_invalidFiles << "tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon2.qml";
+}
+
+QStringList TestQmlformat::findFiles(const QDir &d)
+{
+ for (int ii = 0; ii < m_excludedDirs.count(); ++ii) {
+ QString s = m_excludedDirs.at(ii);
+ if (d.absolutePath().endsWith(s))
+ return QStringList();
+ }
+
+ QStringList rv;
+
+ QStringList files = d.entryList(QStringList() << QLatin1String("*.qml"),
+ QDir::Files);
+ foreach (const QString &file, files) {
+ rv << d.absoluteFilePath(file);
+ }
+
+ QStringList dirs = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot |
+ QDir::NoSymLinks);
+ foreach (const QString &dir, dirs) {
+ QDir sub = d;
+ sub.cd(dir);
+ rv << findFiles(sub);
+ }
+
+ return rv;
+}
+
+bool TestQmlformat::isInvalidFile(const QFileInfo &fileName) const
+{
+ for (const QString &invalidFile : m_invalidFiles) {
+ if (fileName.absoluteFilePath().endsWith(invalidFile))
+ return true;
+ }
+ return false;
+}
+
+QString TestQmlformat::readTestFile(const QString &path)
+{
+ QFile file(testFile(path));
+
+ if (!file.open(QIODevice::ReadOnly))
+ return "";
+
+ return QString::fromUtf8(file.readAll());
+}
+
+void TestQmlformat::testFormat()
+{
+ QCOMPARE(runQmlformat(testFile("Example1.qml"), true, true), readTestFile("Example1.formatted.qml"));
+}
+
+void TestQmlformat::testFormatNoSort()
+{
+ QCOMPARE(runQmlformat(testFile("Example1.qml"), false, true), readTestFile("Example1.formatted.nosort.qml"));
+}
+
+void TestQmlformat::testAnnotations()
+{
+ QCOMPARE(runQmlformat(testFile("Annotations.qml"), true, true), readTestFile("Annotations.formatted.qml"));
+}
+
+void TestQmlformat::testAnnotationsNoSort()
+{
+ QCOMPARE(runQmlformat(testFile("Annotations.qml"), false, true), readTestFile("Annotations.formatted.nosort.qml"));
+}
+
+void TestQmlformat::testFrontInline()
+{
+ QCOMPARE(runQmlformat(testFile("FrontInline.qml"), false, true), readTestFile("FrontInline.formatted.qml"));
+}
+
+void TestQmlformat::testIfBlocks()
+{
+ QCOMPARE(runQmlformat(testFile("IfBlocks.qml"), false, true), readTestFile("IfBlocks.formatted.qml"));
+}
+
+void TestQmlformat::testReadOnlyProps()
+{
+ QCOMPARE(runQmlformat(testFile("readOnlyProps.qml"), false, true), readTestFile("readOnlyProps.formatted.qml"));
+}
+
+void TestQmlformat::testLineEndings()
+{
+ // macos
+ const QString macosContents = runQmlformat(testFile("Example1.formatted.qml"), false, true, "macos");
+ QVERIFY(!macosContents.contains("\n"));
+ QVERIFY(macosContents.contains("\r"));
+
+ // windows
+ const QString windowsContents = runQmlformat(testFile("Example1.formatted.qml"), false, true, "windows");
+ QVERIFY(windowsContents.contains("\r\n"));
+
+ // unix
+ const QString unixContents = runQmlformat(testFile("Example1.formatted.qml"), false, true, "unix");
+ QVERIFY(unixContents.contains("\n"));
+ QVERIFY(!unixContents.contains("\r"));
+}
+
+#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
+void TestQmlformat::testExample_data()
+{
+ QTest::addColumn<QString>("file");
+
+ QString examples = QLatin1String(SRCDIR) + "/../../../../examples/";
+ QString tests = QLatin1String(SRCDIR) + "/../../../../tests/";
+
+ QStringList files;
+ files << findFiles(QDir(examples));
+ files << findFiles(QDir(tests));
+
+ for (const QString &file : files)
+ QTest::newRow(qPrintable(file)) << file;
+}
+#endif
+
+#if !defined(QTEST_CROSS_COMPILED) // sources not available when cross compiled
+void TestQmlformat::testExample()
+{
+ QFETCH(QString, file);
+ QString output = runQmlformat(file, true, !isInvalidFile(file));
+
+ if (!isInvalidFile(file))
+ QVERIFY(!output.isEmpty());
+}
+#endif
+
+QString TestQmlformat::runQmlformat(const QString &fileToFormat, bool sortImports, bool shouldSucceed, const QString &newlineFormat)
+{
+ // Copy test file to temporary location
+ QTemporaryDir tempDir;
+ const QString tempFile = tempDir.path() + QDir::separator() + "to_format.qml";
+ QFile::copy(fileToFormat, tempFile);
+
+ QStringList args;
+ args << "-i";
+ args << tempFile;
+
+ if (!sortImports)
+ args << "-n";
+
+ args << "-l" << newlineFormat;
+
+ auto verify = [&]() {
+ QProcess process;
+ process.start(m_qmlformatPath, args);
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+ if (shouldSucceed)
+ QCOMPARE(process.exitCode(), 0);
+ };
+ verify();
+
+ QFile temp(tempFile);
+
+ temp.open(QIODevice::ReadOnly);
+ QString formatted = QString::fromUtf8(temp.readAll());
+
+ return formatted;
+}
+
+QTEST_MAIN(TestQmlformat)
+#include "tst_qmlformat.moc"
diff --git a/tests/auto/qml/qmllint/data/AttachedProps.qml b/tests/auto/qml/qmllint/data/AttachedProps.qml
new file mode 100644
index 0000000000..01be66f866
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/AttachedProps.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+
+QtObject {
+ id: self
+ property var foo: self.Component.completed
+}
diff --git a/tests/auto/qml/qmllint/data/AutomatchedSignalHandler.qml b/tests/auto/qml/qmllint/data/AutomatchedSignalHandler.qml
new file mode 100644
index 0000000000..064444e182
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/AutomatchedSignalHandler.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/ButtonLoader.qml b/tests/auto/qml/qmllint/data/ButtonLoader.qml
new file mode 100644
index 0000000000..2721614735
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/ButtonLoader.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.12
+
+Item {
+ Text {
+ id: roundButton
+ Text {
+ font.pixelSize: roundButton.font.pixelSize * 0.5
+ }
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/Cycle1.qml b/tests/auto/qml/qmllint/data/Cycle1.qml
new file mode 100644
index 0000000000..8095e9f732
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Cycle1.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+Cycle2 {}
diff --git a/tests/auto/qml/qmllint/data/Cycle2.qml b/tests/auto/qml/qmllint/data/Cycle2.qml
new file mode 100644
index 0000000000..90c376fcda
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Cycle2.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+Cycle3 {}
diff --git a/tests/auto/qml/qmllint/data/Cycle3.qml b/tests/auto/qml/qmllint/data/Cycle3.qml
new file mode 100644
index 0000000000..f4cba68653
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Cycle3.qml
@@ -0,0 +1,2 @@
+import QtQml 2.0
+Cycle1 {}
diff --git a/tests/auto/qml/qmllint/data/Dialog.qml b/tests/auto/qml/qmllint/data/Dialog.qml
new file mode 100644
index 0000000000..bde8eae18b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Dialog.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.12
+
+Item {
+ id: control
+ property Text header
+ header: Text {
+ font.bold: true
+ padding: 12
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/Drawer.qml b/tests/auto/qml/qmllint/data/Drawer.qml
new file mode 100644
index 0000000000..db1d785c6c
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Drawer.qml
@@ -0,0 +1,5 @@
+import QtQml 2.12 as T
+
+T.QtObject {
+ objectName: T.Component.objectName
+}
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/Methods.js b/tests/auto/qml/qmllint/data/Methods.js
new file mode 100644
index 0000000000..52ab857e38
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Methods.js
@@ -0,0 +1,3 @@
+function foo() {
+ return "ttt"
+}
diff --git a/tests/auto/qml/qmllint/data/Text.qml b/tests/auto/qml/qmllint/data/Text.qml
new file mode 100644
index 0000000000..130578d1e3
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Text.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.12 as T
+
+T.Text {
+ id: control
+ text: "'ello"
+}
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..9d81c21070
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/Things/plugins.qmltypes
@@ -0,0 +1,17 @@
+import QtQuick.tooling 1.2
+Module {
+ dependencies: []
+ Component {
+ name: "SomethingEntirelyStrange"
+ prototype: "QObject"
+ Enum {
+ name: "AnEnum"
+ values: {
+ "AAA": 0,
+ "BBB": 1,
+ "CCC": 2
+ }
+ }
+ Property { name: "palette"; type: "QPalette" }
+ }
+}
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/badAlias.qml b/tests/auto/qml/qmllint/data/badAlias.qml
new file mode 100644
index 0000000000..2dd7d1a7e0
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/badAlias.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+
+QtObject {
+ property alias wrong: nowhere
+}
diff --git a/tests/auto/qml/qmllint/data/badAliasProperty.qml b/tests/auto/qml/qmllint/data/badAliasProperty.qml
new file mode 100644
index 0000000000..9483c52cd0
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/badAliasProperty.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+
+QtObject {
+ id: self
+ property alias wrong: self.nowhere
+}
diff --git a/tests/auto/qml/qmllint/data/badParent.qml b/tests/auto/qml/qmllint/data/badParent.qml
new file mode 100644
index 0000000000..f381f059cc
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/badParent.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.0
+
+Item {
+ Item {
+ property int yyy: parent.rrr
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/badTypeAssertion.qml b/tests/auto/qml/qmllint/data/badTypeAssertion.qml
new file mode 100644
index 0000000000..717fc1b1bb
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/badTypeAssertion.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+Item {
+ property QtObject foo: Item { x: 4 }
+ property real foox: (foo as Item).rrr
+}
diff --git a/tests/auto/qml/qmllint/data/esmodule.mjs b/tests/auto/qml/qmllint/data/esmodule.mjs
new file mode 100644
index 0000000000..50a53be2b1
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/esmodule.mjs
@@ -0,0 +1,2 @@
+
+export function test() { console.log("hello world"); }
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/goodAlias.qml b/tests/auto/qml/qmllint/data/goodAlias.qml
new file mode 100644
index 0000000000..d2fa4485ec
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/goodAlias.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.0
+
+Item {
+ id: self
+
+ QtObject {
+ id: inner
+ }
+
+ property alias innerObj: inner
+ property alias name: self.objectName
+}
diff --git a/tests/auto/qml/qmllint/data/goodParent.qml b/tests/auto/qml/qmllint/data/goodParent.qml
new file mode 100644
index 0000000000..413337713a
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/goodParent.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Item {
+ property int rrr: 5
+ Item {
+ property int yyy: parent.rrr
+ }
+}
diff --git a/tests/auto/qml/qmllint/data/goodTypeAssertion.qml b/tests/auto/qml/qmllint/data/goodTypeAssertion.qml
new file mode 100644
index 0000000000..6f5f52eb6b
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/goodTypeAssertion.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+Item {
+ property QtObject foo: Item { x: 4 }
+ property real foox: (foo as Item).x
+}
diff --git a/tests/auto/qml/qmllint/data/incompleteQmltypes.qml b/tests/auto/qml/qmllint/data/incompleteQmltypes.qml
new file mode 100644
index 0000000000..ab06bbd8b0
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/incompleteQmltypes.qml
@@ -0,0 +1,6 @@
+import Things 1.0
+
+SomethingEntirelyStrange {
+ id: self
+ property var a: self.palette.weDontKnowIt
+}
diff --git a/tests/auto/qml/qmllint/data/javascriptMethods.qml b/tests/auto/qml/qmllint/data/javascriptMethods.qml
new file mode 100644
index 0000000000..62ddcfda60
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/javascriptMethods.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+import "Methods.js" as Methods
+
+QtObject {
+ objectName: Methods.foo()
+}
diff --git a/tests/auto/qml/qmllint/data/memberNotFound.qml b/tests/auto/qml/qmllint/data/memberNotFound.qml
new file mode 100644
index 0000000000..da2e353227
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/memberNotFound.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+
+QtObject {
+ id: self
+ property string n: self.objectName
+ property string not: self.foo
+}
diff --git a/tests/auto/qml/qmllint/data/parentIsComponent.qml b/tests/auto/qml/qmllint/data/parentIsComponent.qml
new file mode 100644
index 0000000000..a74bf9e4e8
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/parentIsComponent.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Item {
+ Component {
+ id: foo
+ Item {
+ property real yyy: parent.progress
+ Component.onCompleted: console.log(yyy)
+ }
+ }
+
+ property var stuff: foo.createObject()
+}
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/data/spuriousParentWarning.qml b/tests/auto/qml/qmllint/data/unknownElement.qml
index 1323593031..1323593031 100644
--- a/tests/auto/qml/qmllint/data/spuriousParentWarning.qml
+++ b/tests/auto/qml/qmllint/data/unknownElement.qml
diff --git a/tests/auto/qml/qmllint/data/unknownJavascriptMethod.qml b/tests/auto/qml/qmllint/data/unknownJavascriptMethod.qml
new file mode 100644
index 0000000000..2718e07c60
--- /dev/null
+++ b/tests/auto/qml/qmllint/data/unknownJavascriptMethod.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+import "Methods.js" as Methods
+
+QtObject {
+ objectName: Methods.foo2()
+}
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 582f146dca..8697495a6f 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 testUnqualifiedNoSpuriousParentWarning();
- void catchIdentifierNoFalsePositive();
+
+ void cleanQmlCode_data();
+ void cleanQmlCode();
+
+ void dirtyQmlCode_data();
+ void dirtyQmlCode();
+
+ void testUnknownCausesFail();
+
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,142 @@ 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()
+void TestQmllint::testUnknownCausesFail()
{
- 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("unknownElement.qml", false);
+ 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("AutomatchedSignalHandler")
+ << QStringLiteral("AutomatchedSignalHandler.qml")
+ << QString("Warning: unqualified access at 12:36")
+ << QStringLiteral("no matching signal found");
+ QTest::newRow("MemberNotFound")
+ << QStringLiteral("memberNotFound.qml")
+ << QString("Warning: Property \"foo\" not found on type \"QtObject\" at 6:31")
+ << QString();
+ QTest::newRow("UnknownJavascriptMethd")
+ << QStringLiteral("unknownJavascriptMethod.qml")
+ << QString("Warning: Property \"foo2\" not found on type \"Methods\" at 5:25")
+ << QString();
+ QTest::newRow("badAlias")
+ << QStringLiteral("badAlias.qml")
+ << QString("Warning: unqualified access at 4:27")
+ << QString();
+ QTest::newRow("badAliasProperty")
+ << QStringLiteral("badAliasProperty.qml")
+ << QString("Warning: Property \"nowhere\" not found on type \"QtObject\" at 5:32")
+ << QString();
+ QTest::newRow("badParent")
+ << QStringLiteral("badParent.qml")
+ << QString("Warning: Property \"rrr\" not found on type \"Item\" at 5:34")
+ << QString();
+ QTest::newRow("parentIsComponent")
+ << QStringLiteral("parentIsComponent.qml")
+ << QString("Warning: Property \"progress\" not found on type \"QQuickItem\" at 7:39")
+ << QString();
+ QTest::newRow("badTypeAssertion")
+ << QStringLiteral("badTypeAssertion.qml")
+ << QString("Warning: Property \"rrr\" not found on type \"Item\" at 5:39")
+ << QString();
+ QTest::newRow("incompleteQmltypes")
+ << QStringLiteral("incompleteQmltypes.qml")
+ << QString("Warning: Type \"QPalette\" of member \"palette\" not found at 5:26")
+ << QString();
+ QTest::newRow("inheritanceCylce")
+ << QStringLiteral("Cycle1.qml")
+ << QString("Warning: Cycle2 is part of an inheritance cycle: Cycle2 -> Cycle3 -> Cycle1 -> Cycle2")
+ << QString();
}
-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");
+ QTest::newRow("esmodule") << QStringLiteral("esmodule.mjs");
+ QTest::newRow("methodsInJavascript") << QStringLiteral("javascriptMethods.qml");
+ QTest::newRow("goodAlias") << QStringLiteral("goodAlias.qml");
+ QTest::newRow("goodParent") << QStringLiteral("goodParent.qml");
+ QTest::newRow("goodTypeAssertion") << QStringLiteral("goodTypeAssertion.qml");
+ QTest::newRow("AttachedProps") << QStringLiteral("AttachedProps.qml");
+ QTest::newRow("unknownBuiltinFont") << QStringLiteral("ButtonLoader.qml");
+ QTest::newRow("confusingImport") << QStringLiteral("Dialog.qml");
+ QTest::newRow("qualifiedAttached") << QStringLiteral("Drawer.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 e244369581..0501a8112a 100644
--- a/tests/auto/qml/qmlmin/tst_qmlmin.cpp
+++ b/tests/auto/qml/qmlmin/tst_qmlmin.cpp
@@ -131,6 +131,7 @@ void tst_qmlmin::initTestCase()
invalidFiles << "tests/auto/qml/debugger/qqmlpreview/data/broken.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.2.qml";
invalidFiles << "tests/auto/qml/qqmllanguage/data/fuzzed.3.qml";
+ invalidFiles << "tests/auto/qml/qqmllanguage/data/requiredProperties.2.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/qmltyperegistrar/foreign/foreign.cpp b/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
new file mode 100644
index 0000000000..db080a5cad
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "foreign.h"
+
+int Foreign::things() const
+{
+ return m_things;
+}
+
+void Foreign::setThings(int things)
+{
+ if (m_things == things)
+ return;
+
+ m_things = things;
+ emit thingsChanged(m_things);
+}
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign.h b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
new file mode 100644
index 0000000000..dc9fbc84a8
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+#ifndef FOREIGN_H
+#define FOREIGN_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qsize.h>
+
+class Foreign : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int things READ things WRITE setThings NOTIFY thingsChanged)
+
+public:
+ int things() const;
+
+public slots:
+ void setThings(int things);
+
+signals:
+ void thingsChanged(int things);
+
+private:
+ int m_things = 0;
+};
+
+class SizeGadget : public QSize
+{
+ Q_GADGET
+ Q_PROPERTY(int height READ height WRITE setHeight FINAL)
+};
+
+#endif // FOREIGN_H
diff --git a/tests/auto/qml/qmltyperegistrar/foreign/foreign.pro b/tests/auto/qml/qmltyperegistrar/foreign/foreign.pro
new file mode 100644
index 0000000000..87521eac43
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/foreign/foreign.pro
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+QT = core
+
+macos:CONFIG -= app_bundle
+CONFIG -= debug_and_release_target
+
+SOURCES = foreign.cpp
+HEADERS = foreign.h
+
+CONFIG += metatypes static
diff --git a/tests/auto/qml/qmltyperegistrar/hppheader.hpp b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
new file mode 100644
index 0000000000..f5fc881b77
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/hppheader.hpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+#ifndef HPPHEADER_HPP
+#define HPPHEADER_HPP
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+
+class HppClass : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(int eieiei READ eieiei WRITE setEieiei NOTIFY eieieiChanged)
+
+public:
+ int eieiei() const
+ {
+ return m_eieiei;
+ }
+
+public slots:
+ void setEieiei(int eieiei)
+ {
+ if (m_eieiei == eieiei)
+ return;
+
+ m_eieiei = eieiei;
+ emit eieieiChanged(m_eieiei);
+ }
+
+signals:
+ void eieieiChanged(int eieiei);
+
+private:
+ int m_eieiei;
+};
+
+#endif // HPPHEADER_HPP
diff --git a/tests/auto/qml/qmltyperegistrar/noextheader b/tests/auto/qml/qmltyperegistrar/noextheader
new file mode 100644
index 0000000000..3b6cb6d72c
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/noextheader
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+#ifndef NOEXTHEADER
+#define NOEXTHEADER
+
+#include <QtCore/qobject.h>
+#include <QtQml/qqml.h>
+
+class Noext : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(int gagaga READ gagaga WRITE setGagaga NOTIFY gagagaChanged)
+
+public:
+ int gagaga() const
+ {
+ return m_gagaga;
+ }
+
+public slots:
+ void setGagaga(int gagaga)
+ {
+ if (m_gagaga == gagaga)
+ return;
+
+ m_gagaga = gagaga;
+ emit gagagaChanged(m_gagaga);
+ }
+
+signals:
+ void gagagaChanged(int gagaga);
+
+private:
+ int m_gagaga;
+};
+
+#endif // NOEXTHEADER
diff --git a/tests/auto/qml/qmltyperegistrar/qmltyperegistrar.pro b/tests/auto/qml/qmltyperegistrar/qmltyperegistrar.pro
new file mode 100644
index 0000000000..738d099123
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/qmltyperegistrar.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = foreign tst_qmltyperegistrar.pro
+
+tst_qmltyperegistrar_pro.depends = foreign
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
new file mode 100644
index 0000000000..1cfcd689c6
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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 "tst_qmltyperegistrar.h"
+#include <QtTest/qtest.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qfile.h>
+
+void tst_qmltyperegistrar::initTestCase()
+{
+ QFile file(QCoreApplication::applicationDirPath() + "/tst_qmltyperegistrar.qmltypes");
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ qmltypesData = file.readAll();
+ QVERIFY(file.atEnd());
+ QCOMPARE(file.error(), QFile::NoError);
+}
+
+void tst_qmltyperegistrar::qmltypesHasForeign()
+{
+ QVERIFY(qmltypesData.contains("things"));
+}
+
+void tst_qmltyperegistrar::qmltypesHasHppClassAndNoext()
+{
+ QVERIFY(qmltypesData.contains("HppClass"));
+ QVERIFY(qmltypesData.contains("Noext"));
+}
+
+void tst_qmltyperegistrar::qmltypesHasFileNames()
+{
+ QVERIFY(qmltypesData.contains("file: \"hppheader.hpp\""));
+ QVERIFY(qmltypesData.contains("file: \"noextheader\""));
+ QVERIFY(qmltypesData.contains("file: \"tst_qmltyperegistrar.h\""));
+}
+
+void tst_qmltyperegistrar::qmltypesHasFlags()
+{
+ QVERIFY(qmltypesData.contains("name: \"Flags\""));
+ QVERIFY(qmltypesData.contains("alias: \"Flag\""));
+ QVERIFY(qmltypesData.contains("isFlag: true"));
+}
+
+void tst_qmltyperegistrar::superAndForeignTypes()
+{
+ QVERIFY(qmltypesData.contains("values: [\"Pixel\", \"Centimeter\", \"Inch\", \"Point\"]"));
+ QVERIFY(qmltypesData.contains("name: \"SizeGadget\""));
+ QVERIFY(qmltypesData.contains("prototype: \"SizeEnums\""));
+ QVERIFY(qmltypesData.contains("Property { name: \"height\"; type: \"int\" }"));
+ QVERIFY(qmltypesData.contains("Property { name: \"width\"; type: \"int\" }"));
+ QVERIFY(qmltypesData.contains("Method { name: \"sizeToString\"; type: \"string\" }"));
+}
+
+QTEST_MAIN(tst_qmltyperegistrar)
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
new file mode 100644
index 0000000000..09485ab0b6
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+#ifndef TST_QMLTYPEREGISTRAR_H
+#define TST_QMLTYPEREGISTRAR_H
+
+#include "foreign.h"
+
+#include <QtQml/qqml.h>
+
+class SizeEnums
+{
+ Q_GADGET
+ QML_NAMED_ELEMENT(SizeEnums)
+ QML_UNCREATABLE("Element is not creatable.")
+
+public:
+ enum Unit { Pixel, Centimeter, Inch, Point };
+ Q_ENUM(Unit)
+};
+
+class SizeValueType : public SizeEnums
+{
+ QSize v;
+ Q_GADGET
+ Q_PROPERTY(int width READ width WRITE setWidth FINAL)
+ QML_NAMED_ELEMENT(MySize)
+ QML_FOREIGN(SizeGadget)
+
+public:
+ Q_INVOKABLE QString sizeToString() const
+ {
+ return QString::fromLatin1("%1x%2").arg(v.width()).arg(v.height());
+ }
+
+ int width() const { return v.width(); }
+ void setWidth(int width) { v.setWidth(width); }
+};
+
+class Local : public Foreign
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ enum Flag {
+ Flag1 = 0x1,
+ Flag2 = 0x2,
+ Flag3 = 0x4,
+ Flag4 = 0x8
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+ Q_FLAG(Flags)
+};
+
+class tst_qmltyperegistrar : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void qmltypesHasForeign();
+ void qmltypesHasHppClassAndNoext();
+ void qmltypesHasFileNames();
+ void qmltypesHasFlags();
+ void superAndForeignTypes();
+
+private:
+ QByteArray qmltypesData;
+};
+
+#endif // TST_QMLTYPEREGISTRAR_H
diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.pro b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.pro
new file mode 100644
index 0000000000..fe21b122c2
--- /dev/null
+++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+
+QT = core qml testlib
+CONFIG += testcase qmltypes
+CONFIG -= debug_and_release_target
+macos:CONFIG -= app_bundle
+
+SOURCES += tst_qmltyperegistrar.cpp
+HEADERS += \
+ hppheader.hpp \
+ noextheader \
+ tst_qmltyperegistrar.h
+
+QMLTYPES_FILENAME = tst_qmltyperegistrar.qmltypes
+QML_FOREIGN_METATYPES += foreign/foreign_metatypes.json
+QML_IMPORT_NAME = QmlTypeRegistrarTest
+QML_IMPORT_VERSION = 1.0
+
+INCLUDEPATH += foreign
+LIBS += -Lforeign -lforeign
diff --git a/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.qm b/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.qm
new file mode 100644
index 0000000000..926d74f905
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.qm
Binary files differ
diff --git a/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.ts b/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.ts
new file mode 100644
index 0000000000..2105cfb2cf
--- /dev/null
+++ b/tests/auto/qml/qqmlapplicationengine/data/i18n/qml_de_CH.ts
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="de_CH" sourcelanguage="en">
+<context>
+ <name>loadTranslation</name>
+ <message>
+ <source>translate it</source>
+ <translation>Grüezi</translation>
+ </message>
+</context>
+</TS>
diff --git a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
index 2bee283826..f636e527c3 100644
--- a/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
+++ b/tests/auto/qml/qqmlapplicationengine/tst_qqmlapplicationengine.cpp
@@ -53,6 +53,7 @@ private slots:
void removeObjectsWhenDestroyed();
void loadTranslation_data();
void loadTranslation();
+ void translationChange();
void setInitialProperties();
void failureToLoadTriggersWarningSignal();
@@ -278,6 +279,28 @@ void tst_qqmlapplicationengine::loadTranslation()
QCOMPARE(rootObject->property("translation").toString(), translation);
}
+void tst_qqmlapplicationengine::translationChange()
+{
+ if (QLocale().language() == QLocale::SwissGerman) {
+ QSKIP("Skipping this when running under the Swiss locale as we would always load translation.");
+ }
+
+ QQmlApplicationEngine engine(testFileUrl("loadTranslation.qml"));
+
+ QCOMPARE(engine.uiLanguage(), QLocale().bcp47Name());
+
+ QObject *rootObject = engine.rootObjects().first();
+ QVERIFY(rootObject);
+
+ QCOMPARE(rootObject->property("translation").toString(), "translated");
+
+ engine.setUiLanguage("de_CH");
+ QCOMPARE(rootObject->property("translation").toString(), QString::fromUtf8("Gr\u00FCezi"));
+
+ engine.setUiLanguage(QString());
+ QCOMPARE(rootObject->property("translation").toString(), "translate it");
+}
+
void tst_qqmlapplicationengine::setInitialProperties()
{
QQmlApplicationEngine test {};
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/RequiredDefault.qml b/tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml
new file mode 100644
index 0000000000..7e8f225a52
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/RequiredDefault.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ required default property Text requiredDefault
+}
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/requiredDefault.1.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml
new file mode 100644
index 0000000000..68dff22f33
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.1.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+RequiredDefault {
+ Text {text: "Hello, world!"}
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml
new file mode 100644
index 0000000000..a6c4e8ea3f
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.2.qml
@@ -0,0 +1,3 @@
+import QtQuick 2.15
+
+RequiredDefault { }
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml
new file mode 100644
index 0000000000..19b3271858
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.3.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.15
+import qt.test 1.0
+
+RequiredDefaultCpp {
+ Text {text: "Hello, world!"}
+}
diff --git a/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml b/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml
new file mode 100644
index 0000000000..acd56db328
--- /dev/null
+++ b/tests/auto/qml/qqmlcomponent/data/requiredDefault.4.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import qt.test 1.0
+
+RequiredDefaultCpp { }
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 1d2fa42b75..43cbd93396 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:
@@ -668,35 +671,96 @@ void tst_qqmlcomponent::setDataNoEngineNoSegfault()
QVERIFY(!c);
}
-void tst_qqmlcomponent::testSetInitialProperties()
+class RequiredDefaultCpp : public QObject
+{
+ Q_OBJECT
+public:
+ Q_PROPERTY(QQuickItem *defaultProperty MEMBER m_defaultProperty NOTIFY defaultPropertyChanged REQUIRED)
+ Q_SIGNAL void defaultPropertyChanged();
+ Q_CLASSINFO("DefaultProperty", "defaultProperty")
+private:
+ QQuickItem *m_defaultProperty = nullptr;
+};
+
+void tst_qqmlcomponent::testRequiredProperties_data()
+{
+ qmlRegisterType<RequiredDefaultCpp>("qt.test", 1, 0, "RequiredDefaultCpp");
+ 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";
+ QTest::addRow("required default set") << testFileUrl("requiredDefault.1.qml") << true << "";
+ QTest::addRow("required default not set") << testFileUrl("requiredDefault.2.qml") << false << "Required property requiredDefault was not initialized";
+ QTest::addRow("required default set (C++)") << testFileUrl("requiredDefault.3.qml") << true << "";
+ QTest::addRow("required default not set (C++)") << testFileUrl("requiredDefault.4.qml") << false << "Required property defaultProperty was not initialized";
+}
+
+
+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 +792,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 +813,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/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/qqmldelegatemodel/data/abstractItemModel.qml b/tests/auto/qml/qqmldelegatemodel/data/abstractItemModel.qml
new file mode 100644
index 0000000000..01ebfd8e1e
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/data/abstractItemModel.qml
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** 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 QtQml.Models 2.15
+import QtQuick 2.15
+
+import Test 1.0
+
+DelegateModel {
+ model: AbstractItemModel {}
+ delegate: Item {}
+}
diff --git a/tests/auto/qml/qqmldelegatemodel/data/integerModel.qml b/tests/auto/qml/qqmldelegatemodel/data/integerModel.qml
new file mode 100644
index 0000000000..f6cd886e09
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/data/integerModel.qml
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** 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 QtQml.Models 2.15
+import QtQuick 2.15
+
+DelegateModel {
+ model: 100
+ delegate: Item {}
+}
diff --git a/tests/auto/qml/qqmldelegatemodel/data/listModel.qml b/tests/auto/qml/qqmldelegatemodel/data/listModel.qml
new file mode 100644
index 0000000000..1ee8bcac72
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/data/listModel.qml
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** 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 QtQml.Models 2.15
+import QtQuick 2.15
+
+DelegateModel {
+ model: ListModel {
+ ListElement {
+ name: "Item 0"
+ }
+ ListElement {
+ name: "Item 1"
+ }
+ ListElement {
+ name: "Item 2"
+ }
+ }
+ delegate: Item {}
+}
diff --git a/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro b/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro
new file mode 100644
index 0000000000..7fdd3ab5f1
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/qqmldelegatemodel.pro
@@ -0,0 +1,13 @@
+CONFIG += testcase
+TARGET = tst_qqmldelegatemodel
+macos:CONFIG -= app_bundle
+
+QT += qml testlib core-private qml-private qmlmodels-private
+
+SOURCES += tst_qqmldelegatemodel.cpp
+
+include (../../shared/util.pri)
+
+TESTDATA = data/*
+
+OTHER_FILES += data/*
diff --git a/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
new file mode 100644
index 0000000000..87f42c0c8a
--- /dev/null
+++ b/tests/auto/qml/qqmldelegatemodel/tst_qqmldelegatemodel.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** 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 <QtTest/qtest.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQmlModels/private/qqmldelegatemodel_p.h>
+
+#include "../../shared/util.h"
+
+class tst_QQmlDelegateModel : public QQmlDataTest
+{
+ Q_OBJECT
+
+public:
+ tst_QQmlDelegateModel();
+
+private slots:
+ void valueWithoutCallingObjectFirst_data();
+ void valueWithoutCallingObjectFirst();
+};
+
+class AbstractItemModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ AbstractItemModel()
+ {
+ for (int i = 0; i < 3; ++i)
+ mValues.append(QString::fromLatin1("Item %1").arg(i));
+ }
+
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (parent.isValid())
+ return QModelIndex();
+
+ return createIndex(row, column);
+ }
+
+ QModelIndex parent(const QModelIndex &) const override
+ {
+ return QModelIndex();
+ }
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override
+ {
+ if (parent.isValid())
+ return 0;
+
+ return mValues.count();
+ }
+
+ int columnCount(const QModelIndex &parent) const override
+ {
+ if (parent.isValid())
+ return 0;
+
+ return 1;
+ }
+
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
+ {
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ return mValues.at(index.row());
+ }
+
+private:
+ QVector<QString> mValues;
+};
+
+tst_QQmlDelegateModel::tst_QQmlDelegateModel()
+{
+ qmlRegisterType<AbstractItemModel>("Test", 1, 0, "AbstractItemModel");
+}
+
+void tst_QQmlDelegateModel::valueWithoutCallingObjectFirst_data()
+{
+ QTest::addColumn<QUrl>("qmlFileUrl");
+ QTest::addColumn<int>("index");
+ QTest::addColumn<QString>("role");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ QTest::addRow("integer") << testFileUrl("integerModel.qml")
+ << 50 << QString::fromLatin1("modelData") << QVariant(50);
+ QTest::addRow("ListModel") << testFileUrl("listModel.qml")
+ << 1 << QString::fromLatin1("name") << QVariant(QLatin1String("Item 1"));
+ QTest::addRow("QAbstractItemModel") << testFileUrl("abstractItemModel.qml")
+ << 1 << QString::fromLatin1("display") << QVariant(QLatin1String("Item 1"));
+}
+
+// Tests that it's possible to call variantValue() without creating
+// costly delegate items first via object().
+void tst_QQmlDelegateModel::valueWithoutCallingObjectFirst()
+{
+ QFETCH(const QUrl, qmlFileUrl);
+ QFETCH(const int, index);
+ QFETCH(const QString, role);
+ QFETCH(const QVariant, expectedValue);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(qmlFileUrl);
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY2(root, qPrintable(component.errorString()));
+ QQmlDelegateModel *model = qobject_cast<QQmlDelegateModel*>(root.data());
+ QVERIFY(model);
+ QCOMPARE(model->variantValue(index, role), expectedValue);
+}
+
+QTEST_MAIN(tst_QQmlDelegateModel)
+
+#include "tst_qqmldelegatemodel.moc"
diff --git a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
index bc4ba9437c..7e96205743 100644
--- a/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
+++ b/tests/auto/qml/qqmldirparser/tst_qqmldirparser.cpp
@@ -63,10 +63,10 @@ namespace {
for (const QQmlJS::DiagnosticMessage &e : errors) {
QString errorString = QLatin1String("qmldir");
- if (e.line > 0) {
- errorString += QLatin1Char(':') + QString::number(e.line);
- if (e.column > 0)
- errorString += QLatin1Char(':') + QString::number(e.column);
+ if (e.loc.startLine > 0) {
+ errorString += QLatin1Char(':') + QString::number(e.loc.startLine);
+ if (e.loc.startColumn > 0)
+ errorString += QLatin1Char(':') + QString::number(e.loc.startColumn);
}
errorString += QLatin1String(": ") + e.message;
diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
index 3233e7f105..03e3262e7b 100644
--- a/tests/auto/qml/qqmlecmascript/testtypes.h
+++ b/tests/auto/qml/qqmlecmascript/testtypes.h
@@ -36,7 +36,6 @@
#include <QtCore/qregularexpression.h>
#include <QtQml/qqmllist.h>
#include <QtCore/qrect.h>
-#include <QtGui/qmatrix.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
#include <QtGui/QFont>
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 26232ac1a3..4b0cbfa1aa 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -74,6 +74,7 @@ public:
private slots:
void initTestCase();
+ void arrayIncludesValueType();
void assignBasicTypes();
void assignDate_data();
void assignDate();
@@ -414,6 +415,36 @@ void tst_qqmlecmascript::initTestCase()
registerTypes();
}
+void tst_qqmlecmascript::arrayIncludesValueType()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ // It is vital that QtQuick is imported below else we get a warning about
+ // QQml_colorProvider and tst_qqmlecmascript::signalParameterTypes fails due
+ // to some static variable being initialized with the wrong value
+ component.setData(R"(
+ import QtQuick 2.15
+ import QtQml 2.15
+ QtObject {
+ id: root
+ property color r: Qt.rgba(1, 0, 0)
+ property color g: Qt.rgba(0, 1, 0)
+ property color b: Qt.rgba(0, 0, 1)
+ property var colors: [r, g, b]
+ property bool success: false
+
+ Component.onCompleted: {
+ root.success = root.colors.includes(root.g)
+ }
+ }
+ )", QUrl("testData"));
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o);
+ auto success = o->property("success");
+ QVERIFY(success.isValid());
+ QVERIFY(success.toBool());
+}
+
void tst_qqmlecmascript::assignBasicTypes()
{
QQmlEngine engine;
@@ -6439,6 +6470,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
@@ -7271,7 +7304,7 @@ void tst_qqmlecmascript::forInLoop()
QMetaObject::invokeMethod(object, "listProperty");
- QStringList r = object->property("listResult").toString().split("|", QString::SkipEmptyParts);
+ QStringList r = object->property("listResult").toString().split("|", Qt::SkipEmptyParts);
QCOMPARE(r.size(), 3);
QCOMPARE(r[0],QLatin1String("0=obj1"));
QCOMPARE(r[1],QLatin1String("1=obj2"));
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/data/uiLanguage.qml b/tests/auto/qml/qqmlengine/data/uiLanguage.qml
new file mode 100644
index 0000000000..bc20351245
--- /dev/null
+++ b/tests/auto/qml/qqmlengine/data/uiLanguage.qml
@@ -0,0 +1,9 @@
+import QtQml 2.15
+QtObject {
+ property string chosenLanguage: Qt.uiLanguage
+ property string textToTranslate: {
+ numberOfTranslationBindingEvaluations++;
+ return qsTr("Translate me maybe");
+ }
+ property int numberOfTranslationBindingEvaluations: 0
+}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index 613616ab71..cfbbd2a94c 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -84,6 +84,7 @@ private slots:
void aggressiveGc();
void cachedGetterLookup_qtbug_75335();
void createComponentOnSingletonDestruction();
+ void uiLanguage();
public slots:
QObject *createAQObjectForOwnershipTest ()
@@ -425,12 +426,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);
}
@@ -512,6 +514,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());
@@ -602,11 +605,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());
@@ -617,13 +619,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());
}
@@ -773,6 +775,7 @@ public:
};
Q_DECLARE_METATYPE(QList<QQmlAbstractUrlInterceptor::DataType>);
+
void tst_qqmlengine::urlInterceptor_data()
{
QTest::addColumn<QUrl>("testFile");
@@ -941,14 +944,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"
@@ -993,6 +997,11 @@ public:
SomeQObjectClass() : QObject(nullptr){}
};
+class Dayfly : public QObject
+{
+ Q_OBJECT
+};
+
void tst_qqmlengine::singletonInstance()
{
QQmlEngine engine;
@@ -1111,7 +1120,7 @@ void tst_qqmlengine::singletonInstance()
{
// deleted object
- auto dayfly = new QObject{};
+ auto dayfly = new Dayfly{};
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.");
@@ -1172,6 +1181,38 @@ void tst_qqmlengine::createComponentOnSingletonDestruction()
QVERIFY(obj);
}
+void tst_qqmlengine::uiLanguage()
+{
+ QQmlEngine engine;
+
+ QObject::connect(&engine, &QJSEngine::uiLanguageChanged, [&engine]() {
+ engine.retranslate();
+ });
+
+ QSignalSpy uiLanguageChangeSpy(&engine, SIGNAL(uiLanguageChanged()));
+
+ QQmlComponent component(&engine, testFileUrl("uiLanguage.qml"));
+
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, (component.url().toString() + ":2:1: QML QtObject: Binding loop detected for property \"textToTranslate\"").toLatin1());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+
+ QVERIFY(engine.uiLanguage().isEmpty());
+ QCOMPARE(object->property("numberOfTranslationBindingEvaluations").toInt(), 1);
+
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, (component.url().toString() + ":2:1: QML QtObject: Binding loop detected for property \"textToTranslate\"").toLatin1());
+ engine.setUiLanguage("TestLanguage");
+ QCOMPARE(object->property("numberOfTranslationBindingEvaluations").toInt(), 2);
+ QCOMPARE(object->property("chosenLanguage").toString(), "TestLanguage");
+
+
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, (component.url().toString() + ":2:1: QML QtObject: Binding loop detected for property \"textToTranslate\"").toLatin1());
+ engine.evaluate("Qt.uiLanguage = \"anotherLanguage\"");
+ QCOMPARE(engine.uiLanguage(), QString("anotherLanguage"));
+ QCOMPARE(object->property("numberOfTranslationBindingEvaluations").toInt(), 3);
+ QCOMPARE(object->property("chosenLanguage").toString(), "anotherLanguage");
+}
+
QTEST_MAIN(tst_qqmlengine)
#include "tst_qqmlengine.moc"
diff --git a/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml
new file mode 100644
index 0000000000..4bb8dfb486
--- /dev/null
+++ b/tests/auto/qml/qqmlenginecleanup/data/MyItem.qml
@@ -0,0 +1,2 @@
+import QtQuick 2.12
+Item {}
diff --git a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
index 690db30838..846ac842db 100644
--- a/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
+++ b/tests/auto/qml/qqmlenginecleanup/tst_qqmlenginecleanup.cpp
@@ -45,6 +45,7 @@ private slots:
void test_qmlClearTypeRegistrations();
void test_valueTypeProviderModule(); // QTBUG-43004
void test_customModuleCleanup();
+ void test_qmlListCleared();
};
// A wrapper around QQmlComponent to ensure the temporary reference counts
@@ -186,6 +187,18 @@ void tst_qqmlenginecleanup::test_customModuleCleanup()
}
}
+void tst_qqmlenginecleanup::test_qmlListCleared()
+{
+ {
+ QQmlEngine engine;
+ auto url = testFileUrl("MyItem.qml");
+ QQmlComponent comp(&engine, url);
+ QScopedPointer<QObject> item {comp.create()};
+ QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 1);
+ }
+ QCOMPARE(QQmlMetaType::qmlRegisteredListTypeCount(), 0);
+}
+
QTEST_MAIN(tst_qqmlenginecleanup)
#include "tst_qqmlenginecleanup.moc"
diff --git a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
index ca1e52ad2c..9c865b3f73 100644
--- a/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
+++ b/tests/auto/qml/qqmlimport/tst_qqmlimport.cpp
@@ -32,6 +32,7 @@
#include <QtQuick/qquickview.h>
#include <QtQuick/qquickitem.h>
#include <private/qqmlimport_p.h>
+#include <private/qqmlengine_p.h>
#include "../../shared/util.h"
class tst_QQmlImport : public QQmlDataTest
@@ -46,6 +47,7 @@ private slots:
void completeQmldirPaths();
void interceptQmldir();
void singletonVersionResolution();
+ void removeDynamicPlugin();
void cleanup();
};
@@ -260,6 +262,25 @@ void tst_QQmlImport::singletonVersionResolution()
}
}
+void tst_QQmlImport::removeDynamicPlugin()
+{
+ qmlClearTypeRegistrations();
+ QQmlEngine engine;
+ {
+ // Load something that adds a dynamic plugin
+ QQmlComponent component(&engine);
+ component.setData(QByteArray("import QtTest 1.0; TestResult{}"), QUrl());
+ QVERIFY(component.isReady());
+ }
+ QQmlImportDatabase *imports = &QQmlEnginePrivate::get(&engine)->importDatabase;
+ const QStringList &plugins = imports->dynamicPlugins();
+ QVERIFY(!plugins.isEmpty());
+ for (const QString &plugin : plugins)
+ QVERIFY(imports->removeDynamicPlugin(plugin));
+ QVERIFY(imports->dynamicPlugins().isEmpty());
+ qmlClearTypeRegistrations();
+}
+
QTEST_MAIN(tst_QQmlImport)
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..549aae8c2b 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;
@@ -148,7 +149,7 @@ void tst_qqmlincubator::objectDeleted()
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringOuterType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -156,14 +157,14 @@ void tst_qqmlincubator::objectDeleted()
QVERIFY(incubator.isLoading());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
delete SelfRegisteringType::me();
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -204,7 +205,7 @@ void tst_qqmlincubator::clear()
component.create(incubator);
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -223,7 +224,7 @@ void tst_qqmlincubator::clear()
component.create(incubator);
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -317,7 +318,7 @@ void tst_qqmlincubator::forceCompletion()
QVERIFY(incubator.isLoading());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -376,7 +377,7 @@ void tst_qqmlincubator::setInitialState()
MyIncubator incubator(QQmlIncubator::Asynchronous);
component.create(incubator);
QVERIFY(incubator.isLoading());
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
QVERIFY(incubator.isReady());
QVERIFY(incubator.object());
@@ -413,7 +414,7 @@ void tst_qqmlincubator::clearDuringCompletion()
QVERIFY(!CompletionRegisteringType::me());
while (CompletionRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -452,7 +453,7 @@ void tst_qqmlincubator::objectDeletionAfterInit()
component.create(incubator);
while (!incubator.obj && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -551,7 +552,7 @@ void tst_qqmlincubator::statusChanged()
QCOMPARE(incubator.statuses.at(0), int(QQmlIncubator::Loading));
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -573,7 +574,7 @@ void tst_qqmlincubator::statusChanged()
QCOMPARE(incubator.statuses.at(0), int(QQmlIncubator::Loading));
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -621,7 +622,7 @@ void tst_qqmlincubator::asynchronousIfNested()
QVERIFY(incubator.isLoading());
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -634,7 +635,7 @@ void tst_qqmlincubator::asynchronousIfNested()
while (nested.isLoading()) {
QVERIFY(incubator.isLoading());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -642,7 +643,7 @@ void tst_qqmlincubator::asynchronousIfNested()
QVERIFY(incubator.isLoading());
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -741,7 +742,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNested()
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -778,7 +779,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNested()
QVERIFY(incubator1.isLoading());
QVERIFY(incubator2.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -791,14 +792,14 @@ void tst_qqmlincubator::chainedAsynchronousIfNested()
QVERIFY(incubator1.isReady());
QVERIFY(incubator2.isLoading());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
QVERIFY(incubator1.isReady());
QVERIFY(incubator2.isReady());
if (incubator.isLoading()) {
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -855,7 +856,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -875,7 +876,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(incubator2.isNull());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -890,7 +891,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(incubator2.isNull());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -905,7 +906,7 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(incubator2.isLoading());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -920,12 +921,12 @@ void tst_qqmlincubator::chainedAsynchronousIfNestedOnCompleted()
QVERIFY(incubator2.isReady());
QVERIFY(incubator3.isLoading());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -983,7 +984,7 @@ void tst_qqmlincubator::chainedAsynchronousClear()
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringType::me() == nullptr && incubator.isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -1003,7 +1004,7 @@ void tst_qqmlincubator::chainedAsynchronousClear()
QVERIFY(incubator2.isNull());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -1018,7 +1019,7 @@ void tst_qqmlincubator::chainedAsynchronousClear()
QVERIFY(incubator2.isNull());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -1033,7 +1034,7 @@ void tst_qqmlincubator::chainedAsynchronousClear()
QVERIFY(incubator2.isLoading());
QVERIFY(incubator3.isNull());
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -1077,7 +1078,7 @@ void tst_qqmlincubator::selfDelete()
#define DELETE_TEST(status, mode) { \
bool done = false; \
component.create(*(new MyIncubator(&done, status, mode))); \
- bool True = true; \
+ std::atomic<bool> True{true}; \
controller.incubateWhile(&True); \
QVERIFY(done == true); \
}
@@ -1106,7 +1107,7 @@ void tst_qqmlincubator::selfDelete()
QVERIFY(!SelfRegisteringType::me());
while (SelfRegisteringType::me() == nullptr && incubator->isLoading()) {
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
@@ -1120,7 +1121,7 @@ void tst_qqmlincubator::selfDelete()
delete SelfRegisteringType::me();
{
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
}
@@ -1141,7 +1142,7 @@ void tst_qqmlincubator::contextDelete()
delete context;
{
- bool b = false;
+ std::atomic<bool> b{false};
controller.incubateWhile(&b);
}
}
@@ -1154,7 +1155,7 @@ void tst_qqmlincubator::garbageCollection()
engine.collectGarbage();
- bool b = true;
+ std::atomic<bool> b{true};
controller.incubateWhile(&b);
// verify incubation completed (the incubator was not prematurely collected)
@@ -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/Action.qml b/tests/auto/qml/qqmllanguage/data/Action.qml
new file mode 100644
index 0000000000..4db2bacf6e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/Action.qml
@@ -0,0 +1,21 @@
+import QtQuick 2.12
+
+QtObject {
+ id:root
+ property Item parent
+ property Item displayComponent: null
+
+ property list<QtObject> children
+
+ readonly property var visibleChildren: {
+ var visible = [];
+ var child;
+ for (var i in children) {
+ child = children[i];
+ if (!child.hasOwnProperty("visible") || child.visible) {
+ visible.push(child)
+ }
+ }
+ return visible;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentBase.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentBase.qml
new file mode 100644
index 0000000000..0b297a7779
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentBase.qml
@@ -0,0 +1,9 @@
+import QtQml 2.15
+
+QtObject {
+ property alias i: icInstance.i
+ component IC : QtObject {
+ property int i: 42
+ }
+ property QtObject ic: IC {id: icInstance}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentChild.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentChild.qml
new file mode 100644
index 0000000000..49a90ab7da
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentChild.qml
@@ -0,0 +1,7 @@
+import QtQml 2.15
+
+InlineComponentBase {
+ component IC : QtObject {
+ property int i: 13
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentProvider.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider.qml
new file mode 100644
index 0000000000..6058e32b2f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.15
+
+Item {
+ component StyledRectangle: Rectangle {
+ width: 24
+ height: 24
+ color: "red"
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentProvider2.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider2.qml
new file mode 100644
index 0000000000..b5a0efaccf
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider2.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.15
+
+Item {
+ property color myColor: "red"
+ component StyledRectangle: Rectangle {
+ width: 24
+ height: 24
+ color: myColor
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentProvider3.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider3.qml
new file mode 100644
index 0000000000..9a4f1fd272
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentProvider3.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.15
+
+Item {
+ Item {
+ component StyledRectangle: Rectangle {
+ width: 24
+ height: 24
+ color: "red"
+ }
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentProviderChild.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentProviderChild.qml
new file mode 100644
index 0000000000..ddb55e55e6
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentProviderChild.qml
@@ -0,0 +1 @@
+InlineComponentProvider {}
diff --git a/tests/auto/qml/qqmllanguage/data/InlineComponentReexporter.qml b/tests/auto/qml/qqmllanguage/data/InlineComponentReexporter.qml
new file mode 100644
index 0000000000..24bf6f771e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/InlineComponentReexporter.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.14
+
+QtObject {
+ component StyledRectangle: InlineComponentProvider.StyledRectangle {
+ color: "green"
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml b/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml
new file mode 100644
index 0000000000..60d45c2b1e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/NonRequiredBase.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ property int i
+}
diff --git a/tests/auto/qml/qqmllanguage/data/RequiredBase.qml b/tests/auto/qml/qqmllanguage/data/RequiredBase.qml
new file mode 100644
index 0000000000..4effdbf1c7
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/RequiredBase.qml
@@ -0,0 +1,3 @@
+NonRequiredBase {
+ required i
+}
diff --git a/tests/auto/qml/qqmllanguage/data/SelfInstantiation.errors.txt b/tests/auto/qml/qqmllanguage/data/SelfInstantiation.errors.txt
new file mode 100644
index 0000000000..dfd077941e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/SelfInstantiation.errors.txt
@@ -0,0 +1 @@
+3:29:SelfInstantiation is instantiated recursively
diff --git a/tests/auto/qml/qqmllanguage/data/SelfInstantiation.qml b/tests/auto/qml/qqmllanguage/data/SelfInstantiation.qml
new file mode 100644
index 0000000000..b2e4e453a0
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/SelfInstantiation.qml
@@ -0,0 +1,5 @@
+import QtQml 2.0
+QtObject {
+ property QtObject self: SelfInstantiation {
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/SelfReference.qml b/tests/auto/qml/qqmllanguage/data/SelfReference.qml
new file mode 100644
index 0000000000..129a171d77
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/SelfReference.qml
@@ -0,0 +1,8 @@
+import QtQml 2.0
+QtObject {
+ property SelfReference self
+ signal blah(selfParam: SelfReference)
+ function returnSelf() : SelfReference {
+ return this;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/SimpleItem.qml b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml
new file mode 100644
index 0000000000..c7bce2bc78
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/SimpleItem.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ property int i: 42
+}
diff --git a/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt b/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt
deleted file mode 100644
index 90a3ea4317..0000000000
--- a/tests/auto/qml/qqmllanguage/data/alias.14.errors.txt
+++ /dev/null
@@ -1 +0,0 @@
-10:34:References to other aliases within the same object are not supported at the moment
diff --git a/tests/auto/qml/qqmllanguage/data/alias.18.errors.txt b/tests/auto/qml/qqmllanguage/data/alias.18.errors.txt
new file mode 100644
index 0000000000..dda3e7a174
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.18.errors.txt
@@ -0,0 +1 @@
+7:24:Duplicate alias name
diff --git a/tests/auto/qml/qqmllanguage/data/alias.18.qml b/tests/auto/qml/qqmllanguage/data/alias.18.qml
new file mode 100644
index 0000000000..a9be937975
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/alias.18.qml
@@ -0,0 +1,9 @@
+import QtQml 2.14
+
+QtObject {
+ id: root
+ property QtObject o1: QtObject {
+ property alias a: root
+ property alias a: root
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml
index ee400eb41f..d8e278a7a1 100644
--- a/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml
+++ b/tests/auto/qml/qqmllanguage/data/arrayToContainer.qml
@@ -3,5 +3,7 @@ import qt.test 1.0
TestItem {
property var vector
+ property var myset
positions: vector
+ barrays: myset
}
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml
new file mode 100644
index 0000000000..76673f6409
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredProperty.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+MyClass {test: 42}
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml
new file mode 100644
index 0000000000..d4c059581c
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParent.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+Child2 {test: test2; test2: 18}
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml
new file mode 100644
index 0000000000..082e22dc3f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInChildAndParentNotSet.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+Child2 { test: 13 }
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml
new file mode 100644
index 0000000000..6602684542
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParent.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+Child {test: 42}
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml
new file mode 100644
index 0000000000..5971b0c263
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyInParentNotSet.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+Child {}
diff --git a/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml
new file mode 100644
index 0000000000..dab48a3d71
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppRequiredPropertyNotSet.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.15
+import example.org 1.0
+
+MyClass {}
diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml
new file mode 100644
index 0000000000..3b37c29b18
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.2.qml
@@ -0,0 +1,5 @@
+import StaticTest 1.0
+
+MyStaticSecondNamespacedType {
+ list: [ MyStaticNamespacedType {} ]
+}
diff --git a/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml
new file mode 100644
index 0000000000..2778baadb9
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/cppstaticnamespace.qml
@@ -0,0 +1,6 @@
+import StaticTest 1.0
+
+MyStaticNamespacedType {
+ myEnum: MyStaticNamespace.Key5
+ property int intProperty: MyStaticNamespace.MyOtherNSEnum.OtherKey2
+}
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/icCycleViaProperty.qml b/tests/auto/qml/qqmllanguage/data/icCycleViaProperty.qml
new file mode 100644
index 0000000000..c5aa4cfdf5
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/icCycleViaProperty.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.15
+
+Item {
+ component A : Item {
+ property var test: B {}
+ }
+ component B: A {}
+ A {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/icSimpleCycle.qml b/tests/auto/qml/qqmllanguage/data/icSimpleCycle.qml
new file mode 100644
index 0000000000..69e74f7c96
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/icSimpleCycle.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.15
+
+Item {
+ component A : B {}
+ component B: A {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentDuplicateName.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentDuplicateName.qml
new file mode 100644
index 0000000000..12cc79cf14
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentDuplicateName.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.12
+Item
+{
+ component IC: Item {}
+ component IC: Item {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentFoundBeforeOtherImports.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentFoundBeforeOtherImports.qml
new file mode 100644
index 0000000000..85903727fb
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentFoundBeforeOtherImports.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.12
+
+Item
+{
+ component Rectangle: Item {
+ Component.onCompleted: console.info("Created")
+ }
+ Rectangle {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentOrder.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentOrder.qml
new file mode 100644
index 0000000000..a96f68e56a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentOrder.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.15
+
+Item {
+ width: 600
+ height: 480
+ IC2 {
+ objectName: "icInstance"
+ anchors.centerIn: parent
+ }
+
+ component IC2: IC1 {}
+ component IC0: Rectangle {
+ height: 200
+ width: 200
+ color: "blue"
+ }
+ component IC1: IC0 {}
+
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentUser1.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentUser1.qml
new file mode 100644
index 0000000000..8968a20112
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentUser1.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.14
+
+Item {
+ width: 600
+ height: 480
+ property InlineComponentProvider.StyledRectangle myProp: InlineComponentProvider.StyledRectangle {}
+ InlineComponentProvider.StyledRectangle {
+ objectName: "icInstance"
+ anchors.centerIn: parent
+ color: "blue"
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentUser2.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentUser2.qml
new file mode 100644
index 0000000000..dc6e3850db
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentUser2.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.14
+
+Item {
+ width: 600
+ height: 480
+ property InlineComponentProvider.StyledRectangle myProp: InlineComponentReexporter.StyledRectangle {
+ objectName: "icInstance"
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentUser3.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentUser3.qml
new file mode 100644
index 0000000000..c57c4cad01
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentUser3.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.14
+
+Item {
+ width: 600
+ height: 480
+ component StyledRectangle: Rectangle {
+ width: 24
+ height: 24
+ color: "blue"
+ }
+ StyledRectangle {
+ objectName: "icInstance"
+ anchors.centerIn: parent
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentUser4.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentUser4.qml
new file mode 100644
index 0000000000..9f3903c8df
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentUser4.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.14
+
+Item {
+ width: 600
+ height: 480
+ property color myColor: "blue"
+ InlineComponentProvider2.StyledRectangle {
+ objectName: "icInstance"
+ anchors.centerIn: parent
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentUser5.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentUser5.qml
new file mode 100644
index 0000000000..150d0c2ded
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentUser5.qml
@@ -0,0 +1,11 @@
+import QtQuick 2.15
+
+Item {
+ width: 600
+ height: 480
+ property var test: InlineComponentProvider3.StyledRectangle {
+ objectName: "icInstance"
+ anchors.centerIn: parent
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml
new file mode 100644
index 0000000000..ab125e9323
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithAlias.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ component IC: SimpleItem {
+ width: i
+ Rectangle {
+ id: rect
+ color: "lime"
+ }
+ property alias color: rect.color
+ }
+ width: 200
+ IC {
+ objectName: "icInstance"
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml
new file mode 100644
index 0000000000..c4093bad2f
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/inlineComponentWithId.qml
@@ -0,0 +1,14 @@
+import QtQuick 2.15
+
+Item {
+ id: root
+ component IC: SimpleItem {
+ id: root
+ width: root.i
+ property color color: "red"
+ }
+ width: 200
+ IC {
+ objectName: "icInstance"
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/invalidRoot.4.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidRoot.4.errors.txt
index 3b90f573a2..41cb0eaac1 100644
--- a/tests/auto/qml/qqmllanguage/data/invalidRoot.4.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/invalidRoot.4.errors.txt
@@ -1 +1 @@
-3:1:Bar.Item - Bar is not a namespace
+3:1:Bar.Item - Bar is neither a type nor a namespace
diff --git a/tests/auto/qml/qqmllanguage/data/invalidTypeName.4.errors.txt b/tests/auto/qml/qqmllanguage/data/invalidTypeName.4.errors.txt
index 3b90f573a2..41cb0eaac1 100644
--- a/tests/auto/qml/qqmllanguage/data/invalidTypeName.4.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/invalidTypeName.4.errors.txt
@@ -1 +1 @@
-3:1:Bar.Item - Bar is not a namespace
+3:1:Bar.Item - Bar is neither a type nor a namespace
diff --git a/tests/auto/qml/qqmllanguage/data/listContainingDeleted.qml b/tests/auto/qml/qqmllanguage/data/listContainingDeleted.qml
new file mode 100644
index 0000000000..efd273ddc6
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/listContainingDeleted.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.12
+
+Item {
+ width: 1024
+ height: 800
+
+ property Component a: Component {
+ id: a
+ Item {
+ property list<QtObject> myList: [
+ QtObject {
+ property bool enabled: true
+ }
+ ]
+ }
+ }
+ Component {
+ id: b
+ Item {
+ property list<QtObject> myList
+
+ function test() {
+ for (var i = 0; i < myList.length; ++i)
+ console.log(i, "==", myList[i].enabled)
+ }
+ }
+ }
+ property Item instance
+ function doAssign(o) {
+ instance = b.createObject(null, {myList: o.myList})
+ }
+ function use() {
+ instance.test()
+ }
+
+}
diff --git a/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml b/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml
new file mode 100644
index 0000000000..b1635a9409
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/listPropertiesChild.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.12
+
+Action
+{
+ id: action
+ property color color
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nestedIC.qml b/tests/auto/qml/qqmllanguage/data/nestedIC.qml
new file mode 100644
index 0000000000..04cef64d54
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nestedIC.qml
@@ -0,0 +1,7 @@
+import QtQuick 2.15
+
+Item {
+ component Outer : Item {
+ component Inner : Item {}
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nonExistingICUser1.qml b/tests/auto/qml/qqmllanguage/data/nonExistingICUser1.qml
new file mode 100644
index 0000000000..a07a6a9838
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nonExistingICUser1.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ property InlineComponentProvider.NonExisting myProp
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nonExistingICUser2.qml b/tests/auto/qml/qqmllanguage/data/nonExistingICUser2.qml
new file mode 100644
index 0000000000..5c24962def
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nonExistingICUser2.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ InlineComponentProvider.NotExisting {}
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nonExistingICUser3.qml b/tests/auto/qml/qqmllanguage/data/nonExistingICUser3.qml
new file mode 100644
index 0000000000..34595707fc
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nonExistingICUser3.qml
@@ -0,0 +1,3 @@
+import QtQuick 2.15
+
+InlineComponentProvider.NotExisting {}
diff --git a/tests/auto/qml/qqmllanguage/data/nonExistingICUser4.qml b/tests/auto/qml/qqmllanguage/data/nonExistingICUser4.qml
new file mode 100644
index 0000000000..2be01ccd96
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nonExistingICUser4.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import "singleton" as MySingleton
+
+Item {
+ property MySingleton.SingletonTypeWithIC.NonExisting singletonIC
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nonExistingICUser5.qml b/tests/auto/qml/qqmllanguage/data/nonExistingICUser5.qml
new file mode 100644
index 0000000000..a2ca5db6de
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nonExistingICUser5.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ property InlineComponentProviderChild.StyledRectangle myProp
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.errors.txt b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.errors.txt
new file mode 100644
index 0000000000..d4f3eb3ecf
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.errors.txt
@@ -0,0 +1 @@
+6:29:Left-hand side may not contain || or &&
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml
new file mode 100644
index 0000000000..ce6aa9a532
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_And.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Component {
+ Component.onCompleted: {
+ // Should cause an error since having either || or && on any side of the coalescing operator is banned by the specification
+ var bad_lhs_and = 3 && 4 ?? 0;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.errors.txt b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.errors.txt
new file mode 100644
index 0000000000..f2f1719acd
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.errors.txt
@@ -0,0 +1 @@
+6:28:Left-hand side may not contain || or &&
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml
new file mode 100644
index 0000000000..8864524d0d
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_LHS_Or.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Component {
+ Component.onCompleted: {
+ // Should cause an error since having either || or && on any side of the coalescing operator is banned by the specification
+ var bad_lhs_or = 3 || 4 ?? 0;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.errors.txt b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.errors.txt
new file mode 100644
index 0000000000..0ff61be687
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.errors.txt
@@ -0,0 +1 @@
+6:34:Right-hand side may not contain || or &&
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml
new file mode 100644
index 0000000000..97898f055a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_And.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Component {
+ Component.onCompleted: {
+ // Should cause an error since having either || or && on any side of the coalescing operator is banned by the specification
+ var bad_rhs_and = 0 ?? 3 && 4;
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.errors.txt b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.errors.txt
new file mode 100644
index 0000000000..4b2784ac0a
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.errors.txt
@@ -0,0 +1 @@
+6:33:Right-hand side may not contain || or &&
diff --git a/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml
new file mode 100644
index 0000000000..f172755e91
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/nullishCoalescing_RHS_Or.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Component {
+ Component.onCompleted: {
+ // Should cause an error since having either || or && on any side of the coalescing operator is banned by the specification
+ var bad_rhs_or = 0 ?? 3 || 4;
+ }
+}
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..2585cf361e
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.3.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.15
+
+Item {
+ property int i;
+ required i;
+}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml
new file mode 100644
index 0000000000..1126f845c9
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.4.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ required objectName
+}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml
new file mode 100644
index 0000000000..c2d155b123
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.5.qml
@@ -0,0 +1 @@
+RequiredBase {}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml
new file mode 100644
index 0000000000..e8802aef20
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.6.qml
@@ -0,0 +1,3 @@
+RequiredBase {
+ i: 42
+}
diff --git a/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml b/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml
new file mode 100644
index 0000000000..40987f5c56
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/requiredProperties.7.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Item {
+ required blub
+}
diff --git a/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/TestSingleton.qml b/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/TestSingleton.qml
new file mode 100644
index 0000000000..f70a3b1fea
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/TestSingleton.qml
@@ -0,0 +1,7 @@
+import QtQml 2.0
+import selfreferencingsingletonmodule 1.0
+pragma Singleton
+QtObject {
+ property SelfReferencingSingleton self
+ property int dummy: 42
+}
diff --git a/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/qmldir b/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/qmldir
new file mode 100644
index 0000000000..617861b00b
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/selfreferencingsingletonmodule/qmldir
@@ -0,0 +1 @@
+singleton SelfReferencingSingleton 1.0 TestSingleton.qml
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/SingletonTypeWithIC.qml b/tests/auto/qml/qqmllanguage/data/singleton/SingletonTypeWithIC.qml
new file mode 100644
index 0000000000..bd724c4aeb
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singleton/SingletonTypeWithIC.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.0
+pragma Singleton
+
+Item {
+ id: singletonId
+ component IC1: Item {
+ property int iProp: 42
+ property string sProp: "Hello, world"
+ property Rectangle myRect: Rectangle {color: "green"}
+ }
+ component IC2: Item {
+ property int iProp: 13
+ property string sProp: "Goodbye, world"
+ property Rectangle myRect: Rectangle {color: "red"}
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/data/singleton/qmldir b/tests/auto/qml/qqmllanguage/data/singleton/qmldir
index 533fb6999a..727b09b4e8 100644
--- a/tests/auto/qml/qqmllanguage/data/singleton/qmldir
+++ b/tests/auto/qml/qqmllanguage/data/singleton/qmldir
@@ -1,3 +1,4 @@
singleton SingletonType SingletonType.qml
+singleton SingletonTypeWithIC SingletonTypeWithIC.qml
diff --git a/tests/auto/qml/qqmllanguage/data/singletonICTest.qml b/tests/auto/qml/qqmllanguage/data/singletonICTest.qml
new file mode 100644
index 0000000000..d0d3b079be
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/singletonICTest.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+import "singleton" as MySingleton
+
+Item {
+ property MySingleton.SingletonTypeWithIC.IC1 singleton1: MySingleton.SingletonTypeWithIC.IC1 {};
+}
diff --git a/tests/auto/qml/qqmllanguage/data/unsupportedProperty.errors.txt b/tests/auto/qml/qqmllanguage/data/unsupportedProperty.errors.txt
index 3cd626de86..b45c320c20 100644
--- a/tests/auto/qml/qqmllanguage/data/unsupportedProperty.errors.txt
+++ b/tests/auto/qml/qqmllanguage/data/unsupportedProperty.errors.txt
@@ -1 +1 @@
-3:13:Invalid property assignment: unsupported type "QMatrix"
+3:16:Invalid property assignment: unsupported type "QTransform"
diff --git a/tests/auto/qml/qqmllanguage/data/unsupportedProperty.qml b/tests/auto/qml/qqmllanguage/data/unsupportedProperty.qml
index 9f19680368..ec8171dd2c 100644
--- a/tests/auto/qml/qqmllanguage/data/unsupportedProperty.qml
+++ b/tests/auto/qml/qqmllanguage/data/unsupportedProperty.qml
@@ -1,4 +1,4 @@
import Test 1.0
MyQmlObject {
- matrix: "1,0,0,0,1,0,0,0,1"
+ transform: "1,0,0,0,1,0,0,0,1"
}
diff --git a/tests/auto/qml/qqmllanguage/qqmllanguage.pro b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
index 724a27320c..6c54525544 100644
--- a/tests/auto/qml/qqmllanguage/qqmllanguage.pro
+++ b/tests/auto/qml/qqmllanguage/qqmllanguage.pro
@@ -1,4 +1,7 @@
-CONFIG += testcase
+CONFIG += testcase qmltypes
+QML_IMPORT_NAME = StaticTest
+QML_IMPORT_VERSION = 1.0
+
TARGET = tst_qqmllanguage
macx:CONFIG -= app_bundle
diff --git a/tests/auto/qml/qqmllanguage/testtypes.cpp b/tests/auto/qml/qqmllanguage/testtypes.cpp
index 6956533196..31a4135d89 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,10 @@ void registerTypes()
qmlRegisterType<LazyDeferredSubObject>("Test", 1, 0, "LazyDeferredSubObject");
qmlRegisterType<DeferredProperties>("Test", 1, 0, "DeferredProperties");
+
+ qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>("Test", 1);
+ qmlRegisterTypesAndRevisions<BareSingleton>("Test", 1);
+ qmlRegisterTypesAndRevisions<UncreatableSingleton>("Test", 1);
}
QVariant myCustomVariantTypeConverter(const QString &data)
@@ -210,3 +214,9 @@ bool MyQmlObject::event(QEvent *event)
m_childAddedEventCount++;
return QObject::event(event);
}
+
+UncreatableSingleton *UncreatableSingleton::instance()
+{
+ static UncreatableSingleton instance;
+ return &instance;
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 1aab24841a..8852bf7af9 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -31,7 +31,7 @@
#include <QtCore/qobject.h>
#include <QtCore/qrect.h>
#include <QtCore/qdatetime.h>
-#include <QtGui/qmatrix.h>
+#include <QtGui/qtransform.h>
#include <QtGui/qcolor.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
@@ -104,7 +104,7 @@ class MyQmlObject : public QObject, public MyInterface
Q_PROPERTY(QString readOnlyString READ readOnlyString)
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled)
Q_PROPERTY(QRect rect READ rect WRITE setRect)
- Q_PROPERTY(QMatrix matrix READ matrix WRITE setMatrix) //assumed to be unsupported by QML
+ Q_PROPERTY(QTransform transform READ transform WRITE setTransform) //assumed to be unsupported by QML
Q_PROPERTY(MyInterface *interfaceProperty READ interface WRITE setInterface)
Q_PROPERTY(int onLiteralSignal READ onLiteralSignal WRITE setOnLiteralSignal)
Q_PROPERTY(MyCustomVariantType customType READ customType WRITE setCustomType)
@@ -129,8 +129,8 @@ public:
QRect rect() const { return QRect(); }
void setRect(const QRect&) {}
- QMatrix matrix() const { return QMatrix(); }
- void setMatrix(const QMatrix&) {}
+ QTransform transform() const { return QTransform(); }
+ void setTransform(const QTransform &) {}
MyInterface *interface() const { return m_interface; }
void setInterface(MyInterface *iface) { m_interface = iface; }
@@ -750,6 +750,47 @@ private:
bool m_ownRWObj;
};
+namespace MyStaticNamespace {
+ Q_NAMESPACE
+ QML_ELEMENT
+
+ enum MyNSEnum {
+ Key1 = 1,
+ Key2,
+ Key5 = 5
+ };
+ Q_ENUM_NS(MyNSEnum);
+
+ enum class MyOtherNSEnum {
+ OtherKey1 = 1,
+ OtherKey2
+ };
+ Q_ENUM_NS(MyOtherNSEnum);
+
+
+ class MyNamespacedType : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(MyStaticNamespace::MyNSEnum myEnum MEMBER m_myEnum)
+ QML_NAMED_ELEMENT(MyStaticNamespacedType)
+ MyStaticNamespace::MyNSEnum m_myEnum = MyNSEnum::Key1;
+ };
+
+ class MySecondNamespacedType : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<MyStaticNamespace::MyNamespacedType> list READ list)
+ QML_NAMED_ELEMENT(MyStaticSecondNamespacedType)
+ public:
+ QQmlListProperty<MyNamespacedType> list()
+ {
+ return QQmlListProperty<MyNamespacedType>(this, &m_list);
+ }
+
+ private:
+ QList<MyNamespacedType *> m_list;
+ };
+}
namespace MyNamespace {
Q_NAMESPACE
@@ -1420,6 +1461,71 @@ 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 Local : public QObject
+{
+ Q_OBJECT
+};
+
+class Foreign
+{
+ Q_GADGET
+ QML_FOREIGN(Local)
+ QML_NAMED_ELEMENT(Foreign)
+};
+
+class ForeignExtended
+{
+ Q_GADGET
+ QML_FOREIGN(Local)
+ QML_NAMED_ELEMENT(ForeignExtended)
+ QML_EXTENDED(Extension)
+};
+
+class BareSingleton : public QObject
+{
+ Q_OBJECT
+ QML_SINGLETON
+ QML_ELEMENT
+
+public:
+ BareSingleton(QObject *parent = nullptr) : QObject(parent)
+ {
+ setObjectName("statically registered");
+ }
+};
+
+class UncreatableSingleton : public QObject
+{
+ Q_OBJECT
+ QML_SINGLETON
+ QML_ELEMENT
+
+public:
+ static UncreatableSingleton *instance();
+
+private:
+ UncreatableSingleton() { setObjectName("uncreatable"); }
+};
void registerTypes();
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 4a8ce77f92..5665775258 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -123,6 +123,7 @@ private slots:
void dynamicProperties();
void dynamicPropertiesNested();
void listProperties();
+ void listPropertiesInheritanceNoCrash();
void badListItemType();
void dynamicObjectProperties();
void dynamicSignalsAndSlots();
@@ -132,6 +133,9 @@ private slots:
void autoComponentCreation();
void autoComponentCreationInGroupProperty();
void propertyValueSource();
+ void requiredProperty();
+ void requiredPropertyFromCpp_data();
+ void requiredPropertyFromCpp();
void attachedProperties();
void dynamicObjects();
void customVariantTypes();
@@ -303,7 +307,28 @@ private slots:
void typeWrapperToVariant();
+ void extendedForeignTypes();
+
+ void inlineComponent();
+ void inlineComponent_data();
+ void inlineComponentReferenceCycle_data();
+ void inlineComponentReferenceCycle();
+ void nestedInlineComponentNotAllowed();
+ void inlineComponentStaticTypeResolution();
+ void inlineComponentInSingleton();
+ void nonExistingInlineComponent_data();
+ void nonExistingInlineComponent();
+ void inlineComponentFoundBeforeOtherImports();
+ void inlineComponentDuplicateNameError();
+
+ void selfReference();
+ void selfReferencingSingleton();
+
+ void listContainingDeletedObject();
+ void overrideSingleton();
+
void arrayToContainer();
+ void qualifiedScopeInCustomParser();
private:
QQmlEngine engine;
@@ -473,6 +498,11 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
+ QTest::newRow("nullishCoalescing_LHS_Or") << "nullishCoalescing_LHS_Or.qml" << "nullishCoalescing_LHS_Or.errors.txt" << false;
+ QTest::newRow("nullishCoalescing_LHS_And") << "nullishCoalescing_LHS_And.qml" << "nullishCoalescing_LHS_And.errors.txt" << false;
+ QTest::newRow("nullishCoalescing_RHS_Or") << "nullishCoalescing_RHS_Or.qml" << "nullishCoalescing_RHS_Or.errors.txt" << false;
+ QTest::newRow("nullishCoalescing_RHS_And") << "nullishCoalescing_RHS_And.qml" << "nullishCoalescing_RHS_And.errors.txt" << false;
+
QTest::newRow("invalidGroupedProperty.1") << "invalidGroupedProperty.1.qml" << "invalidGroupedProperty.1.errors.txt" << false;
QTest::newRow("invalidGroupedProperty.2") << "invalidGroupedProperty.2.qml" << "invalidGroupedProperty.2.errors.txt" << false;
QTest::newRow("invalidGroupedProperty.3") << "invalidGroupedProperty.3.qml" << "invalidGroupedProperty.3.errors.txt" << false;
@@ -630,6 +660,8 @@ void tst_qqmllanguage::errors_data()
QTest::newRow("typeAnnotations.2") << "typeAnnotations.2.qml" << "typeAnnotations.2.errors.txt" << false;
QTest::newRow("propertyUnknownType") << "propertyUnknownType.qml" << "propertyUnknownType.errors.txt" << false;
+
+ QTest::newRow("selfInstantiation") << "SelfInstantiation.qml" << "SelfInstantiation.errors.txt" << false;
}
void tst_qqmllanguage::errors()
@@ -1462,6 +1494,16 @@ void tst_qqmllanguage::listProperties()
QCOMPARE(object->property("test").toInt(), 2);
}
+// Tests that initializing list properties of a base class does not crash
+// (QTBUG-82171)
+void tst_qqmllanguage::listPropertiesInheritanceNoCrash()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("listPropertiesChild.qml"));
+ QScopedPointer<QObject> object(component.create()); // should not crash
+ QVERIFY(object != nullptr);
+}
+
void tst_qqmllanguage::badListItemType()
{
QQmlComponent component(&engine, testFileUrl("badListItemType.qml"));
@@ -1636,6 +1678,120 @@ 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.4.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!component.errors().empty());
+ QVERIFY(component.errorString().contains("Required property objectName was not initialized"));
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.3.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!component.errors().empty());
+ QVERIFY(component.errorString().contains("Required property i was not initialized"));
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.5.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!component.errors().empty());
+ QVERIFY(component.errorString().contains("Required property i was not initialized"));
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.6.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(object);
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("requiredProperties.7.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!component.errors().empty());
+ QVERIFY(component.errorString().contains("Property blub was marked as required but does not exist"));
+ }
+}
+
+class MyClassWithRequiredProperty : public QObject
+{
+public:
+ Q_OBJECT
+ Q_PROPERTY(int test MEMBER m_test REQUIRED NOTIFY testChanged)
+ Q_SIGNAL void testChanged();
+private:
+ int m_test;
+};
+
+class ChildClassWithoutOwnRequired : public MyClassWithRequiredProperty
+{
+public:
+ Q_OBJECT
+ Q_PROPERTY(int test2 MEMBER m_test2 NOTIFY test2Changed)
+ Q_SIGNAL void test2Changed();
+private:
+ int m_test2;
+};
+
+class ChildClassWithOwnRequired : public MyClassWithRequiredProperty
+{
+public:
+ Q_OBJECT
+ Q_PROPERTY(int test2 MEMBER m_test2 REQUIRED NOTIFY test2Changed)
+ Q_SIGNAL void test2Changed();
+private:
+ int m_test2;
+};
+
+void tst_qqmllanguage::requiredPropertyFromCpp_data()
+{
+ qmlRegisterType<MyClassWithRequiredProperty>("example.org", 1, 0, "MyClass");
+ qmlRegisterType<ChildClassWithoutOwnRequired>("example.org", 1, 0, "Child");
+ qmlRegisterType<ChildClassWithOwnRequired>("example.org", 1, 0, "Child2");
+
+
+ QTest::addColumn<QUrl>("setFile");
+ QTest::addColumn<QUrl>("notSetFile");
+ QTest::addColumn<QString>("errorMessage");
+ QTest::addColumn<int>("expectedValue");
+
+ QTest::addRow("direct") << testFileUrl("cppRequiredProperty.qml") << testFileUrl("cppRequiredPropertyNotSet.qml") << QString(":4 Required property test was not initialized\n") << 42;
+ QTest::addRow("in parent") << testFileUrl("cppRequiredPropertyInParent.qml") << testFileUrl("cppRequiredPropertyInParentNotSet.qml") << QString(":4 Required property test was not initialized\n") << 42;
+ QTest::addRow("in child and parent") << testFileUrl("cppRequiredPropertyInChildAndParent.qml") << testFileUrl("cppRequiredPropertyInChildAndParentNotSet.qml") << QString(":4 Required property test2 was not initialized\n") << 18;
+}
+
+void tst_qqmllanguage::requiredPropertyFromCpp()
+{
+ QQmlEngine engine;
+ QFETCH(QUrl, setFile);
+ QFETCH(QUrl, notSetFile);
+ QFETCH(QString, errorMessage);
+ QFETCH(int, expectedValue);
+ {
+ QQmlComponent comp(&engine, notSetFile);
+ QScopedPointer<QObject> o { comp.create() };
+ QVERIFY(o.isNull());
+ QVERIFY(comp.isError());
+ QCOMPARE(comp.errorString(), notSetFile.toString() + errorMessage);
+ }
+ {
+ QQmlComponent comp(&engine, setFile);
+ QScopedPointer<QObject> o { comp.create() };
+ QVERIFY(!o.isNull());
+ QCOMPARE(o->property("test").toInt(), expectedValue);
+ }
+}
+
void tst_qqmllanguage::attachedProperties()
{
QQmlComponent component(&engine, testFileUrl("attachedProperties.qml"));
@@ -1704,21 +1860,30 @@ void tst_qqmllanguage::valueTypes()
void tst_qqmllanguage::cppnamespace()
{
- {
- QQmlComponent component(&engine, testFileUrl("cppnamespace.qml"));
+ QScopedPointer<QObject> object;
+
+ auto create = [&](const char *file) {
+ QQmlComponent component(&engine, testFileUrl(file));
VERIFY_ERRORS(0);
- QScopedPointer<QObject> object(component.create());
+ object.reset(component.create());
QVERIFY(object != nullptr);
+ };
- QCOMPARE(object->property("intProperty").toInt(), (int)MyNamespace::MyOtherNSEnum::OtherKey2);
- }
+ auto createAndCheck = [&](const char *file) {
+ create(file);
+ return !QTest::currentTestFailed();
+ };
- {
- QQmlComponent component(&engine, testFileUrl("cppnamespace.2.qml"));
- VERIFY_ERRORS(0);
- QScopedPointer<QObject> object(component.create());
- QVERIFY(object != nullptr);
- }
+ QVERIFY(createAndCheck("cppnamespace.qml"));
+ QCOMPARE(object->property("intProperty").toInt(),
+ (int)MyNamespace::MyOtherNSEnum::OtherKey2);
+
+ QVERIFY(createAndCheck("cppstaticnamespace.qml"));
+ QCOMPARE(object->property("intProperty").toInt(),
+ (int)MyStaticNamespace::MyOtherNSEnum::OtherKey2);
+
+ QVERIFY(createAndCheck("cppnamespace.2.qml"));
+ QVERIFY(createAndCheck("cppstaticnamespace.2.qml"));
}
void tst_qqmllanguage::aliasProperties()
@@ -1936,7 +2101,6 @@ void tst_qqmllanguage::aliasProperties()
// "Nested" aliases within an object that require iterative resolution
{
- // This is known to fail at the moment.
QQmlComponent component(&engine, testFileUrl("alias.14.qml"));
VERIFY_ERRORS(0);
@@ -2035,6 +2199,11 @@ void tst_qqmllanguage::aliasProperties()
auto text = myText->property("text").toString();
QCOMPARE(text, "alias:\n20");
}
+
+ {
+ QQmlComponent component(&engine, testFileUrl("alias.18.qml"));
+ VERIFY_ERRORS("alias.18.errors.txt");
+ }
}
// QTBUG-13374 Test that alias properties and signals can coexist
@@ -2294,20 +2463,31 @@ void tst_qqmllanguage::scriptStringJs()
QVERIFY(!object->scriptProperty().booleanLiteral(&ok) && !ok);
}
+struct FreeUnitData
+{
+ static void cleanup(const QV4::CompiledData::Unit *readOnlyQmlUnit)
+ {
+ if (readOnlyQmlUnit && !(readOnlyQmlUnit->flags & QV4::CompiledData::Unit::StaticData))
+ free(const_cast<QV4::CompiledData::Unit *>(readOnlyQmlUnit));
+ }
+};
+
void tst_qqmllanguage::scriptStringWithoutSourceCode()
{
QUrl url = testFileUrl("scriptString7.qml");
+ QScopedPointer<const QV4::CompiledData::Unit, FreeUnitData> readOnlyQmlUnit;
{
QQmlEnginePrivate *eng = QQmlEnginePrivate::get(&engine);
QQmlRefPointer<QQmlTypeData> td = eng->typeLoader.getType(url);
Q_ASSERT(td);
- const QV4::CompiledData::Unit *readOnlyQmlUnit = td->compilationUnit()->unitData();
+ QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit = td->compilationUnit();
+ readOnlyQmlUnit.reset(compilationUnit->unitData());
Q_ASSERT(readOnlyQmlUnit);
QV4::CompiledData::Unit *qmlUnit = reinterpret_cast<QV4::CompiledData::Unit *>(malloc(readOnlyQmlUnit->unitSize));
- memcpy(qmlUnit, readOnlyQmlUnit, readOnlyQmlUnit->unitSize);
+ memcpy(qmlUnit, readOnlyQmlUnit.data(), readOnlyQmlUnit->unitSize);
+
qmlUnit->flags &= ~QV4::CompiledData::Unit::StaticData;
- QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit = td->compilationUnit();
compilationUnit->setUnitData(qmlUnit);
const QV4::CompiledData::Object *rootObject = compilationUnit->objectAt(/*root object*/0);
@@ -2743,12 +2923,12 @@ void tst_qqmllanguage::importsLocal_data()
QTest::newRow("local import QTBUG-7721 A")
<< "subdir.Test {}" // no longer allowed (QTBUG-7721)
<< ""
- << "subdir.Test - subdir is not a namespace";
+ << "subdir.Test - subdir is neither a type nor a namespace";
QTest::newRow("local import QTBUG-7721 B")
<< "import \"subdir\" as X\n"
"X.subsubdir.SubTest {}" // no longer allowed (QTBUG-7721)
<< ""
- << "X.subsubdir.SubTest - nested namespaces not allowed";
+ << "X.subsubdir.SubTest - subsubdir is not a type";
QTest::newRow("local import as")
<< "import \"subdir\" as T\n"
"T.Test {}"
@@ -4709,11 +4889,13 @@ static void beginDeferredOnce(QQmlEnginePrivate *enginePriv,
typedef QMultiHash<int, const QV4::CompiledData::Binding *> QV4PropertyBindingHash;
auto it = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.second);
auto last = std::reverse_iterator<QV4PropertyBindingHash::iterator>(range.first);
+ state->creator->beginPopulateDeferred(deferData->context);
while (it != last) {
- if (!state->creator->populateDeferredBinding(property, deferData, *it))
- state->errors << state->creator->errors;
+ state->creator->populateDeferredBinding(property, deferData->deferredIdx, *it);
++it;
}
+ state->creator->finalizePopulateDeferred();
+ state->errors << state->creator->errors;
deferredState->constructionStates += state;
@@ -4938,24 +5120,24 @@ void tst_qqmllanguage::instanceof_data()
// assert that basic types don't convert to QObject
QTest::newRow("1 instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
QTest::newRow("true instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
QTest::newRow("\"foobar\" instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
// assert that Managed don't either
QTest::newRow("new String(\"foobar\") instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
QTest::newRow("new Object() instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
QTest::newRow("new Date() instanceof QtObject")
<< testFileUrl("instanceof_qtqml.qml")
- << QVariant("TypeError: Type error");
+ << QVariant(false);
// test that simple QtQml comparisons work
QTest::newRow("qtobjectInstance instanceof QtObject")
@@ -5240,29 +5422,341 @@ 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"));
+}
+
+void tst_qqmllanguage::selfReference()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("SelfReference.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+
+ QQmlComponentPrivate *componentPrivate = QQmlComponentPrivate::get(&component);
+ auto compilationUnit = componentPrivate->compilationUnit;
+ QVERIFY(compilationUnit);
+
+ const QMetaObject *metaObject = o->metaObject();
+ QMetaProperty selfProperty = metaObject->property(metaObject->indexOfProperty("self"));
+ QCOMPARE(selfProperty.userType(), compilationUnit->metaTypeId);
+
+ QByteArray typeName = selfProperty.typeName();
+ QVERIFY(typeName.endsWith('*'));
+ typeName = typeName.chopped(1);
+ QCOMPARE(typeName, metaObject->className());
+
+ QMetaMethod selfFunction = metaObject->method(metaObject->indexOfMethod("returnSelf()"));
+ QVERIFY(selfFunction.isValid());
+ QCOMPARE(selfFunction.returnType(), compilationUnit->metaTypeId);
+
+ QMetaMethod selfSignal;
+
+ for (int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i) {
+ QMetaMethod method = metaObject->method(i);
+ if (method.isValid() && method.name().startsWith("blah")) {
+ selfSignal = method;
+ break;
+ }
+ }
+
+ QVERIFY(selfSignal.isValid());
+ QCOMPARE(selfSignal.parameterCount(), 1);
+ QCOMPARE(selfSignal.parameterType(0), compilationUnit->metaTypeId);
+}
+
+void tst_qqmllanguage::selfReferencingSingleton()
+{
+ QQmlEngine engine;
+ engine.addImportPath(dataDirectory());
+
+ QPointer<QObject> singletonPointer;
+ {
+ QQmlComponent component(&engine);
+ component.setData(QByteArray(R"(import QtQml 2.0
+ import selfreferencingsingletonmodule 1.0
+ QtObject {
+ property SelfReferencingSingleton singletonPointer: SelfReferencingSingleton
+ })"), QUrl());
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+ singletonPointer = o->property("singletonPointer").value<QObject*>();
+ }
+
+ QVERIFY(!singletonPointer.isNull());
+ QCOMPARE(singletonPointer->property("dummy").toInt(), 42);
+}
+
+void tst_qqmllanguage::listContainingDeletedObject()
+{
+ QQmlEngine engine;
+ auto url = testFileUrl("listContainingDeleted.qml");
+ const QString message = url.toString() + ":24: TypeError: Cannot read property 'enabled' of null";
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, message.toUtf8().data());
+ QQmlComponent comp(&engine, url);
+ QScopedPointer<QObject> root(comp.create());
+ QVERIFY(root);
+
+ auto cmp = root->property("a").value<QQmlComponent*>();
+ auto o = cmp->create();
+
+ QMetaObject::invokeMethod(root.get(), "doAssign", Q_ARG(QVariant, QVariant::fromValue(o)));
+ delete o;
+ QMetaObject::invokeMethod(root.get(), "use");
+
+}
+
+void tst_qqmllanguage::overrideSingleton()
+{
+ auto check = [](const QString &name, const QByteArray &singletonElement) {
+ const QByteArray testQml = "import Test 1.0\n"
+ "import QtQml 2.0\n"
+ "QtObject { objectName: " + singletonElement + ".objectName }";
+ QQmlEngine engine;
+ QQmlComponent component(&engine, nullptr);
+ component.setData(testQml, QUrl("singleton.qml"));
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QCOMPARE(obj->objectName(), name);
+ };
+
+ check("statically registered", "BareSingleton");
+
+ BareSingleton singleton;
+ singleton.setObjectName("dynamically registered");
+ qmlRegisterSingletonInstance("Test", 1, 0, "BareSingleton", &singleton);
+
+ check("dynamically registered", "BareSingleton");
+
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "singleton.qml:3: TypeError: Cannot read property 'objectName' of undefined");
+ check("", "UncreatableSingleton");
+
+ qmlRegisterSingletonInstance("Test", 1, 0, "UncreatableSingleton",
+ UncreatableSingleton::instance());
+ check("uncreatable", "UncreatableSingleton");
+}
+
+void tst_qqmllanguage::inlineComponent()
+{
+ QFETCH(QUrl, componentUrl);
+ QFETCH(QColor, color);
+ QFETCH(int, width);
+ QQmlEngine engine;
+ QQmlComponent component(&engine, componentUrl);
+ QScopedPointer<QObject> o(component.create());
+ if (component.isError()) {
+ qDebug() << component.errorString();
+ }
+ QVERIFY(!o.isNull());
+ auto icInstance = o->findChild<QObject *>("icInstance");
+ QVERIFY(icInstance);
+ QCOMPARE(icInstance->property("color").value<QColor>(),color);
+ QCOMPARE(icInstance->property("width").value<qreal>(), width);
+}
+
+void tst_qqmllanguage::inlineComponent_data()
+{
+ QTest::addColumn<QUrl>("componentUrl");
+ QTest::addColumn<QColor>("color");
+ QTest::addColumn<int>("width");
+
+ QTest::newRow("Usage from other component") << testFileUrl("inlineComponentUser1.qml") << QColorConstants::Blue << 24;
+ QTest::newRow("Reexport") << testFileUrl("inlineComponentUser2.qml") << QColorConstants::Svg::green << 24;
+ QTest::newRow("Usage in same component") << testFileUrl("inlineComponentUser3.qml") << QColorConstants::Blue << 24;
+
+ QTest::newRow("Resolution happens at instantiation") << testFileUrl("inlineComponentUser4.qml") << QColorConstants::Blue << 24;
+ QTest::newRow("Non-toplevel IC is found") << testFileUrl("inlineComponentUser5.qml") << QColorConstants::Svg::red << 24;
+
+ QTest::newRow("Resolved in correct order") << testFileUrl("inlineComponentOrder.qml") << QColorConstants::Blue << 200;
+
+ QTest::newRow("ID resolves correctly") << testFileUrl("inlineComponentWithId.qml") << QColorConstants::Svg::red << 42;
+ QTest::newRow("Alias resolves correctly") << testFileUrl("inlineComponentWithAlias.qml") << QColorConstants::Svg::lime << 42;
+}
+
+void tst_qqmllanguage::inlineComponentReferenceCycle_data()
+{
+ QTest::addColumn<QUrl>("componentUrl");
+
+ QTest::newRow("Simple cycle") << testFileUrl("icSimpleCycle.qml");
+ QTest::newRow("Via property") << testFileUrl("icCycleViaProperty.qml");
+}
+
+void tst_qqmllanguage::inlineComponentReferenceCycle()
+{
+ QFETCH(QUrl, componentUrl);
+ QQmlEngine engine;
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QQmlComponent: Component is not ready");
+ QQmlComponent component(&engine, componentUrl);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o.isNull());
+ QVERIFY(component.isError());
+ QCOMPARE(component.errorString(), componentUrl.toString() + QLatin1String(":-1 Inline components form a cycle!\n"));
+}
+
+void tst_qqmllanguage::nestedInlineComponentNotAllowed()
+{
+ QQmlEngine engine;
+ auto url = testFileUrl("nestedIC.qml");
+ QQmlComponent component(&engine, url);
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "QQmlComponent: Component is not ready");
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(component.isError());
+ QCOMPARE(component.errorString(), QLatin1String("%1:%2").arg(url.toString(), QLatin1String("5 Nested inline components are not supported\n")));
+}
+
+void tst_qqmllanguage::inlineComponentStaticTypeResolution()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("InlineComponentChild.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(o);
+ QCOMPARE(o->property("i").toInt(), 42);
+}
+
+void tst_qqmllanguage::inlineComponentInSingleton()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("singletonICTest.qml"));
+ VERIFY_ERRORS(0);
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+ auto untyped = o->property("singleton1");
+ QVERIFY(untyped.isValid());
+ auto singleton1 = untyped.value<QObject*>();
+ QVERIFY(singleton1);
+ QCOMPARE(singleton1->property("iProp").value<int>(), 42);
+ QCOMPARE(singleton1->property("sProp").value<QString>(), QString::fromLatin1("Hello, world"));
+ QVERIFY(!o.isNull());
+}
+
+void tst_qqmllanguage::nonExistingInlineComponent_data()
+{
+ QTest::addColumn<QUrl>("componentUrl");
+ QTest::addColumn<QString>("errorMessage");
+ QTest::addColumn<int>("line");
+ QTest::addColumn<int>("column");
+
+ QTest::newRow("Property type") << testFileUrl("nonExistingICUser1.qml") << QString("Type InlineComponentProvider has no inline component type called NonExisting") << 4 << 5;
+ QTest::newRow("Instantiation") << testFileUrl("nonExistingICUser2.qml") << QString("Type InlineComponentProvider has no inline component type called NotExisting") << 4 << 5;
+ QTest::newRow("Inheritance") << testFileUrl("nonExistingICUser3.qml") << QString("Type InlineComponentProvider has no inline component type called NotExisting") << 3 << 1;
+ QTest::newRow("From singleton") << testFileUrl("nonExistingICUser4.qml") << QString("Type MySingleton.SingletonTypeWithIC has no inline component type called NonExisting") << 5 << 5;
+
+ QTest::newRow("Cannot access parent inline components from child") << testFileUrl("nonExistingICUser5.qml") << QString("Type InlineComponentProviderChild has no inline component type called StyledRectangle") << 4 << 5;
+}
+
+void tst_qqmllanguage::nonExistingInlineComponent()
+{
+ QFETCH(QUrl, componentUrl);
+ QFETCH(QString, errorMessage);
+ QFETCH(int, line);
+ QFETCH(int, column);
+ QQmlEngine engine;
+ QQmlComponent component(&engine, componentUrl);
+ auto errors = component.errors();
+ QCOMPARE(errors.size(), 1);
+ const auto &error = errors.first();
+ QCOMPARE(error.description(), errorMessage);
+ QCOMPARE(error.line(), line);
+ QCOMPARE(error.column(), column);
+}
+
+void tst_qqmllanguage::inlineComponentFoundBeforeOtherImports()
+{
+ QQmlEngine engine;
+ QUrl url = testFileUrl("inlineComponentFoundBeforeOtherImports.qml");
+ QQmlComponent component(&engine, url);
+
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Created");
+ QScopedPointer<QObject> root {component.create()};
+}
+
+void tst_qqmllanguage::inlineComponentDuplicateNameError()
+{
+ QQmlEngine engine;
+ QUrl url = testFileUrl("inlineComponentDuplicateName.qml");
+ QQmlComponent component(&engine, url);
+
+ QString message = QLatin1String("%1:5 Inline component names must be unique per file\n").arg(url.toString());
+ QScopedPointer<QObject> root {component.create()};
+ QVERIFY(root.isNull());
+ QVERIFY(component.isError());
+ QCOMPARE(component.errorString(), message);
+}
+
class TestItem : public QObject
{
Q_OBJECT
Q_PROPERTY( QVector<QPointF> positions MEMBER m_points )
+ Q_PROPERTY( QSet<QByteArray> barrays MEMBER m_barrays )
public:
TestItem() = default;
QVector< QPointF > m_points;
+ QSet<QByteArray> m_barrays;
};
Q_DECLARE_METATYPE(QVector<QPointF>);
+Q_DECLARE_METATYPE(QSet<QByteArray>);
void tst_qqmllanguage::arrayToContainer()
{
QQmlEngine engine;
qmlRegisterType<TestItem>("qt.test", 1, 0, "TestItem");
QVector<QPointF> points { QPointF (2.0, 3.0) };
+ QSet<QByteArray> barrays { QByteArray("hello"), QByteArray("world") };
engine.rootContext()->setContextProperty("test", QVariant::fromValue(points));
QQmlComponent component(&engine, testFileUrl("arrayToContainer.qml"));
VERIFY_ERRORS(0);
- QScopedPointer<TestItem> root(qobject_cast<TestItem *>(component.createWithInitialProperties( {{"vector", QVariant::fromValue(points)}} )));
+ QScopedPointer<TestItem> root(qobject_cast<TestItem *>(component.createWithInitialProperties( {{"vector", QVariant::fromValue(points)}, {"myset", QVariant::fromValue(barrays)} } )));
QVERIFY(root);
QCOMPARE(root->m_points.at(0), QPointF (2.0, 3.0) );
+ QVERIFY(root->m_barrays.contains("hello"));
+ QVERIFY(root->m_barrays.contains("world"));
+}
+
+class EnumTester : public QObject
+{
+ Q_OBJECT
+public:
+ enum Types
+ {
+ FIRST = 0,
+ SECOND,
+ THIRD
+ };
+ Q_ENUM(Types)
+};
+
+void tst_qqmllanguage::qualifiedScopeInCustomParser()
+{
+ qmlRegisterUncreatableType<EnumTester>("scoped.custom.test", 1, 0, "EnumTester",
+ "Object only creatable in C++");
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQml.Models 2.12\n"
+ "import scoped.custom.test 1.0 as BACKEND\n"
+ "ListModel {\n"
+ " ListElement { text: \"a\"; type: BACKEND.EnumTester.FIRST }\n"
+ "}\n", QUrl());
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
}
QTEST_MAIN(tst_qqmllanguage)
diff --git a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
index 4d44d6b22b..c0808f8599 100644
--- a/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
+++ b/tests/auto/qml/qqmllistmodel/qqmllistmodel.pro
@@ -8,4 +8,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private qml-private quick-private testlib qmlmodels-private
+QT += core-private gui-private qml-private quick-private testlib qmlmodels-private
diff --git a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
index 75a932b6f4..d54e3467b7 100644
--- a/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
+++ b/tests/auto/qml/qqmllistmodel/tst_qqmllistmodel.cpp
@@ -700,7 +700,7 @@ void tst_qqmllistmodel::error_data()
QTest::newRow("unknown qualified ListElement not allowed")
<< "import QtQuick 2.0\nListModel { Foo.ListElement { a: 123 } }"
- << "Foo.ListElement - Foo is not a namespace";
+ << "Foo.ListElement - Foo is neither a type nor a namespace";
}
void tst_qqmllistmodel::error()
diff --git a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
index 199f7bc7e4..e25d555d61 100644
--- a/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
+++ b/tests/auto/qml/qqmllistreference/tst_qqmllistreference.cpp
@@ -45,6 +45,9 @@ class tst_qqmllistreference : public QQmlDataTest
public:
tst_qqmllistreference() {}
+private:
+ void modeData();
+
private slots:
void initTestCase();
void qmllistreference();
@@ -56,12 +59,19 @@ private slots:
void canAt();
void canClear();
void canCount();
+ void canReplace();
+ void canRemoveLast();
void isReadable();
void isManipulable();
void append();
void at();
+ void clear_data() { modeData(); }
void clear();
void count();
+ void replace_data() { modeData(); }
+ void replace();
+ void removeLast_data() { modeData(); }
+ void removeLast();
void copy();
void qmlmetaproperty();
void engineTypes();
@@ -76,7 +86,67 @@ class TestType : public QObject
Q_PROPERTY(int intProperty READ intProperty)
public:
- TestType() : property(this, data) {}
+ enum Mode {
+ SyntheticClear,
+ SyntheticReplace,
+ SyntheticClearAndReplace,
+ SyntheticRemoveLast,
+ SyntheticRemoveLastAndReplace,
+ AutomaticReference,
+ AutomaticPointer
+ };
+
+ static void append(QQmlListProperty<TestType> *p, TestType *v) {
+ reinterpret_cast<QList<TestType *> *>(p->data)->append(v);
+ }
+ static int count(QQmlListProperty<TestType> *p) {
+ return reinterpret_cast<QList<TestType *> *>(p->data)->count();
+ }
+ static TestType *at(QQmlListProperty<TestType> *p, int idx) {
+ return reinterpret_cast<QList<TestType *> *>(p->data)->at(idx);
+ }
+ static void clear(QQmlListProperty<TestType> *p) {
+ return reinterpret_cast<QList<TestType *> *>(p->data)->clear();
+ }
+ static void replace(QQmlListProperty<TestType> *p, int idx, TestType *v) {
+ return reinterpret_cast<QList<TestType *> *>(p->data)->replace(idx, v);
+ }
+ static void removeLast(QQmlListProperty<TestType> *p) {
+ return reinterpret_cast<QList<TestType *> *>(p->data)->removeLast();
+ }
+
+ TestType(Mode mode = AutomaticReference)
+ {
+ switch (mode) {
+ case SyntheticClear:
+ property = QQmlListProperty<TestType>(this, &data, append, count, at, nullptr,
+ replace, removeLast);
+ break;
+ case SyntheticReplace:
+ property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
+ nullptr, removeLast);
+ break;
+ case SyntheticClearAndReplace:
+ property = QQmlListProperty<TestType>(this, &data, append, count, at, nullptr,
+ nullptr, removeLast);
+ break;
+ case SyntheticRemoveLast:
+ property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
+ replace, nullptr);
+ break;
+ case SyntheticRemoveLastAndReplace:
+ property = QQmlListProperty<TestType>(this, &data, append, count, at, clear,
+ nullptr, nullptr);
+ break;
+ case AutomaticReference:
+ property = QQmlListProperty<TestType>(this, data);
+ break;
+ case AutomaticPointer:
+ property = QQmlListProperty<TestType>(this, &data);
+ break;
+ }
+ }
+
QQmlListProperty<TestType> dataProperty() { return property; }
int intProperty() const { return 10; }
@@ -84,10 +154,24 @@ public:
QQmlListProperty<TestType> property;
};
+Q_DECLARE_METATYPE(TestType::Mode)
+
+void tst_qqmllistreference::modeData()
+{
+ QTest::addColumn<TestType::Mode>("mode");
+ QTest::addRow("AutomaticReference") << TestType::AutomaticReference;
+ QTest::addRow("AutomaticPointer") << TestType::AutomaticPointer;
+ QTest::addRow("SyntheticClear") << TestType::SyntheticClear;
+ QTest::addRow("SyntheticReplace") << TestType::SyntheticReplace;
+ QTest::addRow("SyntheticClearAndReplace") << TestType::SyntheticClearAndReplace;
+ QTest::addRow("SyntheticRemoveLast") << TestType::SyntheticRemoveLast;
+ QTest::addRow("SyntheticRemoveLastAndReplace") << TestType::SyntheticRemoveLastAndReplace;
+}
+
void tst_qqmllistreference::initTestCase()
{
QQmlDataTest::initTestCase();
- qmlRegisterType<TestType>();
+ qmlRegisterAnonymousType<TestType>("Test", 1);
}
void tst_qqmllistreference::qmllistreference()
@@ -340,6 +424,64 @@ void tst_qqmllistreference::canCount()
}
}
+void tst_qqmllistreference::canReplace()
+{
+ QScopedPointer<TestType> tt(new TestType);
+
+ {
+ QQmlListReference ref;
+ QVERIFY(!ref.canReplace());
+ }
+
+ {
+ QQmlListReference ref(tt.data(), "blah");
+ QVERIFY(!ref.canReplace());
+ }
+
+ {
+ QQmlListReference ref(tt.data(), "data");
+ QVERIFY(ref.canReplace());
+ tt.reset();
+ QVERIFY(!ref.canReplace());
+ }
+
+ {
+ TestType tt;
+ tt.property.replace = nullptr;
+ QQmlListReference ref(&tt, "data");
+ QVERIFY(!ref.canReplace());
+ }
+}
+
+void tst_qqmllistreference::canRemoveLast()
+{
+ QScopedPointer<TestType> tt(new TestType);
+
+ {
+ QQmlListReference ref;
+ QVERIFY(!ref.canRemoveLast());
+ }
+
+ {
+ QQmlListReference ref(tt.data(), "blah");
+ QVERIFY(!ref.canRemoveLast());
+ }
+
+ {
+ QQmlListReference ref(tt.data(), "data");
+ QVERIFY(ref.canRemoveLast());
+ tt.reset();
+ QVERIFY(!ref.canRemoveLast());
+ }
+
+ {
+ TestType tt;
+ tt.property.removeLast = nullptr;
+ QQmlListReference ref(&tt, "data");
+ QVERIFY(!ref.canRemoveLast());
+ }
+}
+
void tst_qqmllistreference::isReadable()
{
TestType *tt = new TestType;
@@ -474,7 +616,8 @@ void tst_qqmllistreference::at()
void tst_qqmllistreference::clear()
{
- TestType *tt = new TestType;
+ QFETCH(TestType::Mode, mode);
+ TestType *tt = new TestType(mode);
tt->data.append(tt);
tt->data.append(0);
tt->data.append(tt);
@@ -540,6 +683,70 @@ void tst_qqmllistreference::count()
}
}
+void tst_qqmllistreference::replace()
+{
+ QFETCH(TestType::Mode, mode);
+ QScopedPointer<TestType> tt(new TestType(mode));
+ tt->data.append(tt.get());
+ tt->data.append(nullptr);
+ tt->data.append(tt.get());
+
+ {
+ QQmlListReference ref(tt.get(), "data");
+ QVERIFY(ref.replace(1, tt.get()));
+ QCOMPARE(ref.at(1), tt.get());
+ QVERIFY(ref.replace(2, nullptr));
+ QCOMPARE(ref.at(2), nullptr);
+ QCOMPARE(ref.count(), 3);
+ tt.reset();
+ QVERIFY(!ref.replace(0, tt.get()));
+ }
+
+ {
+ TestType tt;
+ tt.data.append(&tt);
+ tt.property.replace = nullptr;
+ QQmlListReference ref(&tt, "data");
+ QVERIFY(!ref.replace(0, nullptr));
+ }
+}
+
+void tst_qqmllistreference::removeLast()
+{
+ QFETCH(TestType::Mode, mode);
+ QScopedPointer<TestType> tt(new TestType(mode));
+ tt->data.append(tt.get());
+ tt->data.append(nullptr);
+ tt->data.append(tt.get());
+
+ {
+ QQmlListReference ref;
+ QVERIFY(!ref.removeLast());
+ }
+
+ {
+ QQmlListReference ref(tt.get(), "blah");
+ QVERIFY(!ref.removeLast());
+ }
+
+ {
+ QQmlListReference ref(tt.get(), "data");
+ QCOMPARE(tt->data.count(), 3);
+ QVERIFY(ref.removeLast());
+ QCOMPARE(tt->data.count(), 2);
+ tt.reset();
+ QVERIFY(!ref.removeLast());
+ }
+
+ {
+ TestType tt;
+ tt.property.removeLast = nullptr;
+ QQmlListReference ref(&tt, "data");
+ ref.append(&tt);
+ QVERIFY(!ref.removeLast());
+ }
+}
+
void tst_qqmllistreference::copy()
{
TestType tt;
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
index a90749208c..e3094db708 100644
--- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
+++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
@@ -102,6 +102,7 @@ private slots:
void numberFromLocaleString_data();
void numberFromLocaleString();
void numberConstToLocaleString();
+ void numberOptions();
void stringLocaleCompare_data();
void stringLocaleCompare();
@@ -448,7 +449,7 @@ void tst_qqmllocale::firstDayOfWeek()
Q_ARG(QVariant, QVariant(locale)));
QVariant val = obj->property("firstDayOfWeek");
- QCOMPARE(val.type(), QVariant::Int);
+ QCOMPARE(val.userType(), QMetaType::Int);
int day = int(QLocale(locale).firstDayOfWeek());
if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday)
@@ -1157,6 +1158,35 @@ void tst_qqmllocale::numberConstToLocaleString()
QCOMPARE(obj->property("const2").toString(), l.toString(1234., 'f', 2));
}
+void tst_qqmllocale::numberOptions()
+{
+ QQmlEngine engine;
+ QQmlComponent comp(&engine);
+ comp.setData(R"(
+ import QtQml 2.15
+ QtObject {
+ id: root
+ property string formatted
+ property bool caughtException: false
+ Component.onCompleted: () => {
+ const myLocale = Qt.locale("de_DE")
+ myLocale.numberOptions = Locale.OmitGroupSeparator | Locale.RejectTrailingZeroesAfterDot
+ root.formatted = Number(10000).toLocaleString(myLocale, 'f', 4)
+ try {
+ Number.fromLocaleString(myLocale, "1,10");
+ } catch (e) {console.warn(e); root.caughtException = true}
+ }
+ }
+ )", QUrl("testdata"));
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "Error: Locale: Number.fromLocaleString(): Invalid format");
+ QScopedPointer<QObject> root {comp.create()};
+ qDebug() << comp.errorString();
+ QVERIFY(root);
+ QCOMPARE(root->property("formatted").toString(), QLatin1String("10000,0000"));
+ QCOMPARE(root->property("caughtException").toBool(), true);
+
+}
+
void tst_qqmllocale::stringLocaleCompare_data()
{
QTest::addColumn<QString>("string1");
diff --git a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp
index ea157a7d15..b21d2a908d 100644
--- a/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp
+++ b/tests/auto/qml/qqmlmetaobject/tst_qqmlmetaobject.cpp
@@ -112,9 +112,9 @@ void tst_QQmlMetaObject::property_data()
QTest::newRow("date") << "property.date.qml"
<< QByteArray("QDateTime") << int(QMetaType::QDateTime)
<< false // default
- << QVariant(QDateTime(QDate(2012, 2, 7)))
+ << QVariant(QDate(2012, 2, 7).startOfDay())
<< true // writable
- << QVariant(QDateTime(QDate(2010, 7, 2)));
+ << QVariant(QDate(2010, 7, 2).startOfDay());
QTest::newRow("variant") << "property.variant.qml"
<< QByteArray("QVariant") << int(QMetaType::QVariant)
<< true // default
diff --git a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
index 76185a97e0..296d1b14e0 100644
--- a/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
+++ b/tests/auto/qml/qqmlmetatype/tst_qqmlmetatype.cpp
@@ -157,7 +157,7 @@ void tst_qqmlmetatype::initTestCase()
void tst_qqmlmetatype::qmlParserStatusCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).parserStatusCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ValueSourceTestType *>()).isValid());
@@ -177,7 +177,7 @@ void tst_qqmlmetatype::qmlParserStatusCast()
void tst_qqmlmetatype::qmlPropertyValueSourceCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueSourceCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
@@ -197,7 +197,7 @@ void tst_qqmlmetatype::qmlPropertyValueSourceCast()
void tst_qqmlmetatype::qmlPropertyValueInterceptorCast()
{
- QVERIFY(!QQmlMetaType::qmlType(QVariant::Int).isValid());
+ QVERIFY(!QQmlMetaType::qmlType(QMetaType::Int).isValid());
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).isValid());
QCOMPARE(QQmlMetaType::qmlType(qMetaTypeId<TestType *>()).propertyValueInterceptorCast(), -1);
QVERIFY(QQmlMetaType::qmlType(qMetaTypeId<ParserStatusTestType *>()).isValid());
@@ -256,8 +256,8 @@ void tst_qqmlmetatype::prettyTypeName()
void tst_qqmlmetatype::isList()
{
- QCOMPARE(QQmlMetaType::isList(QVariant::Invalid), false);
- QCOMPARE(QQmlMetaType::isList(QVariant::Int), false);
+ QCOMPARE(QQmlMetaType::isList(QMetaType::UnknownType), false);
+ QCOMPARE(QQmlMetaType::isList(QMetaType::Int), false);
QQmlListProperty<TestType> list;
@@ -307,7 +307,7 @@ void tst_qqmlmetatype::compositeType()
//Loading the test file also loads all composite types it imports
QQmlComponent c(&engine, testFileUrl("testImplicitComposite.qml"));
- QObject* obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
QVERIFY(obj);
QQmlType type = QQmlMetaType::qmlType(QString("ImplicitType"), QString(""), 1, 0);
@@ -324,13 +324,13 @@ void tst_qqmlmetatype::externalEnums()
qmlRegisterSingletonType<ExternalEnums>("x.y.z", 1, 0, "ExternalEnums", ExternalEnums::create);
QQmlComponent c(&engine, testFileUrl("testExternalEnums.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
QVERIFY(obj);
QVariant a = obj->property("a");
- QCOMPARE(a.type(), QVariant::Int);
+ QCOMPARE(a.userType(), QVariant::Int);
QCOMPARE(a.toInt(), int(QStandardPaths::DocumentsLocation));
QVariant b = obj->property("b");
- QCOMPARE(b.type(), QVariant::Int);
+ QCOMPARE(b.userType(), QVariant::Int);
QCOMPARE(b.toInt(), int(QStandardPaths::DocumentsLocation));
}
@@ -394,10 +394,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller1 *>(controller));
QVariant stringVal = controller->property("string");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1"));
QVariant enumVal = controller->property("enumVal");
- QCOMPARE(enumVal.type(), QVariant::Int);
+ QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 1);
}
QQmlMetaType::unregisterType(controllerId);
@@ -417,10 +417,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller2 *>(controller));
QVariant stringVal = controller->property("string");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #2"));
QVariant enumVal = controller->property("enumVal");
- QCOMPARE(enumVal.type(), QVariant::Int);
+ QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 111);
}
QQmlMetaType::unregisterType(controllerId);
@@ -440,10 +440,10 @@ void tst_qqmlmetatype::unregisterCustomType()
QObject *controller = obj->findChild<QObject *>("controller");
QVERIFY(qobject_cast<Controller1 *>(controller));
QVariant stringVal = controller->property("string");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("Controller #1"));
QVariant enumVal = controller->property("enumVal");
- QCOMPARE(enumVal.type(), QVariant::Int);
+ QCOMPARE(enumVal.userType(), QVariant::Int);
QCOMPARE(enumVal.toInt(), 1);
}
}
@@ -489,7 +489,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #1"));
}
QQmlMetaType::unregisterType(staticProviderId);
@@ -505,7 +505,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #2"));
}
QQmlMetaType::unregisterType(staticProviderId);
@@ -521,7 +521,7 @@ void tst_qqmlmetatype::unregisterCustomSingletonType()
QScopedPointer<QObject> obj(c.create());
QVERIFY(obj.data());
QVariant stringVal = obj->property("text");
- QCOMPARE(stringVal.type(), QVariant::String);
+ QCOMPARE(stringVal.userType(), QVariant::String);
QCOMPARE(stringVal.toString(), QStringLiteral("StaticProvider #1"));
}
}
@@ -552,7 +552,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties()
QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)),
attachedType.metaObject());
- QVERIFY(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(obj);
}
qmlClearTypeRegistrations();
@@ -571,7 +572,8 @@ void tst_qqmlmetatype::unregisterAttachedProperties()
QCOMPARE(attachedType.attachedPropertiesType(QQmlEnginePrivate::get(&e)),
attachedType.metaObject());
- QVERIFY(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(obj);
}
}
diff --git a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml
index 9789be8191..258667be18 100644
--- a/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml
+++ b/tests/auto/qml/qqmlmoduleplugin/moduleWithQmlSingleton/MySingleton.qml
@@ -1,5 +1,6 @@
pragma Singleton
import QtQuick 2.0
+import Test 1.0
QtObject {
property Loader _loader: Loader {
@@ -7,10 +8,10 @@ QtObject {
}
Component.onCompleted: {
- if (tracker.objectName === "first")
- tracker.objectName = "second"
+ if (Tracker.objectName === "first")
+ Tracker.objectName = "second"
else
- tracker.objectName = "first"
+ Tracker.objectName = "first"
//console.log("created singleton", this)
}
}
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/tst_qqmlmoduleplugin.cpp b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
index f89cc9f24a..75885bc84a 100644
--- a/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
+++ b/tests/auto/qml/qqmlmoduleplugin/tst_qqmlmoduleplugin.cpp
@@ -609,7 +609,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"
@@ -777,7 +777,7 @@ void tst_qqmlmoduleplugin::multiSingleton()
{
QQmlEngine engine;
QObject obj;
- engine.rootContext()->setContextProperty("tracker", &obj);
+ qmlRegisterSingletonInstance("Test", 1, 0, "Tracker", &obj);
engine.addImportPath(m_importsDirectory);
QQmlComponent component(&engine, testFileUrl("multiSingleton.qml"));
QObject *object = component.create();
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/qqmlparser/data/annotations/View1.qml b/tests/auto/qml/qqmlparser/data/annotations/View1.qml
new file mode 100644
index 0000000000..2d3d7d2cfd
--- /dev/null
+++ b/tests/auto/qml/qqmlparser/data/annotations/View1.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+@Pippo{ atg1:3 }
+@Annotation2{}
+Item {
+ @Annotate{}
+ anchors.fill: parent
+ @AnnotateMore{
+ property int x: 5
+ }
+ @AnnotateALot{}
+ property variant othersSlice: 0
+
+ //![1]
+ ChartView {
+ id: chart
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+@ExtraAnnotation{
+ signal pippo
+}
+ PieSeries {
+ id: pieSeries
+ PieSlice { label: "Volkswagen"; value: 13.5 }
+ PieSlice { label: "Toyota"; value: 10.9 }
+ PieSlice { label: "Ford"; value: 8.6 }
+ PieSlice { label: "Skoda"; value: 8.2 }
+ PieSlice { label: "Volvo"; value: 6.8 }
+ }
+ }
+
+@SuperComplete{
+binding: late
+}
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52.0);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+}
diff --git a/tests/auto/qml/qqmlparser/data/noannotations/View1.qml b/tests/auto/qml/qqmlparser/data/noannotations/View1.qml
new file mode 100644
index 0000000000..945bce3a44
--- /dev/null
+++ b/tests/auto/qml/qqmlparser/data/noannotations/View1.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Charts module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL$
+** 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 or (at your option) 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.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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//![2]
+import QtQuick 2.0
+//![2]
+import QtCharts 2.0
+
+
+
+Item {
+
+ anchors.fill: parent
+
+
+
+
+ property variant othersSlice: 0
+
+ //![1]
+ ChartView {
+ id: chart
+ title: "Top-5 car brand shares in Finland"
+ anchors.fill: parent
+ legend.alignment: Qt.AlignBottom
+ antialiasing: true
+
+
+
+
+ PieSeries {
+ id: pieSeries
+ PieSlice { label: "Volkswagen"; value: 13.5 }
+ PieSlice { label: "Toyota"; value: 10.9 }
+ PieSlice { label: "Ford"; value: 8.6 }
+ PieSlice { label: "Skoda"; value: 8.2 }
+ PieSlice { label: "Volvo"; value: 6.8 }
+ }
+ }
+
+
+
+
+ Component.onCompleted: {
+ // You can also manipulate slices dynamically, like append a slice or set a slice exploded
+ othersSlice = pieSeries.append("Others", 52.0);
+ pieSeries.find("Volkswagen").exploded = true;
+ }
+ //![1]
+}
diff --git a/tests/auto/qml/qqmlparser/qqmlparser.pro b/tests/auto/qml/qqmlparser/qqmlparser.pro
index d8e4b0dd06..7f117b3157 100644
--- a/tests/auto/qml/qqmlparser/qqmlparser.pro
+++ b/tests/auto/qml/qqmlparser/qqmlparser.pro
@@ -11,3 +11,4 @@ cross_compile: DEFINES += QTEST_CROSS_COMPILED
TESTDATA = data/*
include (../../shared/util.pri)
+include (../../shared/astdump.pri)
diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
index 9d8818d01e..c7d09f9d6e 100644
--- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
+++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp
@@ -33,6 +33,7 @@
#include <private/qqmljsast_p.h>
#include "../../shared/util.h"
+#include "../../shared/qqmljsastdumper.h"
#include <qtest.h>
#include <QDir>
@@ -62,6 +63,11 @@ private slots:
void typeAnnotations();
void disallowedTypeAnnotations_data();
void disallowedTypeAnnotations();
+ void semicolonPartOfExpressionStatement();
+ void typeAssertion_data();
+ void typeAssertion();
+ void annotations_data();
+ void annotations();
private:
QStringList excludedDirs;
@@ -141,6 +147,30 @@ struct TypeAnnotationObserver: public AST::Visitor
}
};
+struct ExpressionStatementObserver: public AST::Visitor
+{
+ int expressionsSeen = 0;
+ bool endsWithSemicolon = true;
+
+ void operator()(AST::Node *node)
+ {
+ AST::Node::accept(node, this);
+ }
+
+ virtual bool visit(AST::ExpressionStatement *statement)
+ {
+ ++expressionsSeen;
+ endsWithSemicolon = endsWithSemicolon
+ && (statement->lastSourceLocation().end() == statement->semicolonToken.end());
+ return true;
+ }
+
+ void throwRecursionDepthError() final
+ {
+ QFAIL("Maximum statement or expression depth exceeded");
+ }
+};
+
}
tst_qqmlparser::tst_qqmlparser()
@@ -438,6 +468,123 @@ void tst_qqmlparser::disallowedTypeAnnotations()
QVERIFY2(parser.errorMessage().startsWith("Type annotations are not permitted "), qPrintable(parser.errorMessage()));
}
+void tst_qqmlparser::semicolonPartOfExpressionStatement()
+{
+ QQmlJS::Engine engine;
+ QQmlJS::Lexer lexer(&engine);
+ lexer.setCode(QLatin1String("A { property int x: 1+1; property int y: 2+2 \n"
+ "tt: {'a': 5, 'b': 6}; ff: {'c': 'rrr'}}"), 1);
+ QQmlJS::Parser parser(&engine);
+ QVERIFY(parser.parse());
+
+ check::ExpressionStatementObserver observer;
+ observer(parser.rootNode());
+
+ QCOMPARE(observer.expressionsSeen, 4);
+ QVERIFY(observer.endsWithSemicolon);
+}
+
+void tst_qqmlparser::typeAssertion_data()
+{
+ QTest::addColumn<QString>("expression");
+ QTest::addRow("as A")
+ << QString::fromLatin1("A { onStuff: (b as A).happen() }");
+ QTest::addRow("as double paren")
+ << QString::fromLatin1("A { onStuff: console.log((12 as double)); }");
+ QTest::addRow("as double noparen")
+ << QString::fromLatin1("A { onStuff: console.log(12 as double); }");
+ QTest::addRow("property as double")
+ << QString::fromLatin1("A { prop: (12 as double); }");
+ QTest::addRow("property noparen as double")
+ << QString::fromLatin1("A { prop: 12 as double; }");
+
+ // rabbits cannot be discerned from types on a syntactical level.
+ // We could detect this on a semantical level, once we implement type assertions there.
+
+ QTest::addRow("as rabbit")
+ << QString::fromLatin1("A { onStuff: (b as rabbit).happen() }");
+ QTest::addRow("as rabbit paren")
+ << QString::fromLatin1("A { onStuff: console.log((12 as rabbit)); }");
+ QTest::addRow("as rabbit noparen")
+ << QString::fromLatin1("A { onStuff: console.log(12 as rabbit); }");
+ QTest::addRow("property as rabbit")
+ << QString::fromLatin1("A { prop: (12 as rabbit); }");
+ QTest::addRow("property noparen as rabbit")
+ << QString::fromLatin1("A { prop: 12 as rabbit; }");
+}
+
+void tst_qqmlparser::typeAssertion()
+{
+ QFETCH(QString, expression);
+
+ QQmlJS::Engine engine;
+ QQmlJS::Lexer lexer(&engine);
+ lexer.setCode(expression, 1);
+ QQmlJS::Parser parser(&engine);
+ QVERIFY(parser.parse());
+}
+
+void tst_qqmlparser::annotations_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("refFile");
+
+ QString tests = dataDirectory() + "/annotations/";
+ QString compare = dataDirectory() + "/noannotations/";
+
+ QStringList files;
+ files << findFiles(QDir(tests));
+
+ QStringList refFiles;
+ refFiles << findFiles(QDir(compare));
+
+ for (const QString &file: qAsConst(files)) {
+ auto fileNameStart = file.lastIndexOf(QDir::separator());
+ QStringRef fileName(&file, fileNameStart, file.length()-fileNameStart);
+ auto ref=std::find_if(refFiles.constBegin(),refFiles.constEnd(), [fileName](const QString &s){ return s.endsWith(fileName); });
+ if (ref != refFiles.constEnd())
+ QTest::newRow(qPrintable(file)) << file << *ref;
+ else
+ QTest::newRow(qPrintable(file)) << file << QString();
+ }
+}
+
+void tst_qqmlparser::annotations()
+{
+ using namespace QQmlJS;
+
+ QFETCH(QString, file);
+ QFETCH(QString, refFile);
+
+ QString code;
+ QString refCode;
+
+ QFile f(file);
+ if (f.open(QFile::ReadOnly))
+ code = QString::fromUtf8(f.readAll());
+ QFile refF(refFile);
+ if (!refFile.isEmpty() && refF.open(QFile::ReadOnly))
+ refCode = QString::fromUtf8(refF.readAll());
+
+ const bool qmlMode = true;
+
+ Engine engine;
+ Lexer lexer(&engine);
+ lexer.setCode(code, 1, qmlMode);
+ Parser parser(&engine);
+ QVERIFY(parser.parse());
+
+ if (!refCode.isEmpty()) {
+ Engine engine2;
+ Lexer lexer2(&engine2);
+ lexer2.setCode(refCode, 1, qmlMode);
+ Parser parser2(&engine2);
+ QVERIFY(parser2.parse());
+
+ QCOMPARE(AstDumper::diff(parser.ast(), parser2.rootNode(), 3, DumperOptions::NoAnnotations | DumperOptions::NoLocations), QString());
+ }
+}
+
QTEST_MAIN(tst_qqmlparser)
#include "tst_qqmlparser.moc"
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/data/interfaceBinding2.qml b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml
new file mode 100644
index 0000000000..e7c5dc7344
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/data/interfaceBinding2.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.12
+import io.qt.bugreports 2.0
+Item {
+ InterfaceConsumer2 {
+ objectName: "a1"
+ i: A2 {
+ property int i: 42
+ }
+ }
+
+ InterfaceConsumer2 {
+ objectName: "a2"
+ property A2 a: A2 {
+ property int i: 43
+ }
+ i: a
+ }
+
+ InterfaceConsumer2 {
+ objectName: "a3"
+ property A2 a: A2 {
+ id : aa
+ property int i: 44
+ }
+ i: aa
+ }
+}
diff --git a/tests/auto/qml/qqmlproperty/interfaces.h b/tests/auto/qml/qqmlproperty/interfaces.h
new file mode 100644
index 0000000000..2c06c5f594
--- /dev/null
+++ b/tests/auto/qml/qqmlproperty/interfaces.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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$
+**
+****************************************************************************/
+
+#ifndef INTERFACES_H
+#define INTERFACES_H
+
+#include <QtQml/qqml.h>
+
+struct Interface {
+};
+
+QT_BEGIN_NAMESPACE
+#define MyInterface_iid "io.qt.bugreports.Interface"
+Q_DECLARE_INTERFACE(Interface, MyInterface_iid);
+QT_END_NAMESPACE
+
+class A : public QObject, Interface {
+ Q_OBJECT
+ Q_INTERFACES(Interface)
+};
+
+class B : public QObject, Interface {
+ Q_OBJECT
+ Q_INTERFACES(Interface)
+};
+
+class C : public QObject {
+ Q_OBJECT
+};
+
+struct Interface2
+{
+ Q_GADGET
+ QML_INTERFACE
+};
+
+QT_BEGIN_NAMESPACE
+#define MyInterface2_iid "io.qt.bugreports.Interface2"
+Q_DECLARE_INTERFACE(Interface2, MyInterface2_iid);
+QT_END_NAMESPACE
+
+class A2 : public QObject, Interface2 {
+ Q_OBJECT
+ QML_ELEMENT
+ Q_INTERFACES(Interface2)
+};
+
+class B2 : public QObject, Interface2 {
+ Q_OBJECT
+ QML_ELEMENT
+ Q_INTERFACES(Interface2)
+};
+
+class C2 : public QObject {
+ Q_OBJECT
+ QML_ELEMENT
+};
+
+class InterfaceConsumer : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(Interface *i READ interface WRITE setInterface NOTIFY interfaceChanged)
+ Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
+
+public:
+
+ Interface* interface() const
+ {
+ return m_interface;
+ }
+ void setInterface(Interface* interface)
+ {
+ QObject* object = reinterpret_cast<QObject*>(interface);
+ m_testValue = object->property("i").toInt();
+ emit testValueChanged();
+ if (m_interface == interface)
+ return;
+
+ m_interface = interface;
+ emit interfaceChanged();
+ }
+
+ int testValue() {
+ return m_testValue;
+ }
+
+signals:
+ void interfaceChanged();
+ void testValueChanged();
+
+private:
+ Interface* m_interface = nullptr;
+ int m_testValue = 0;
+};
+
+
+class InterfaceConsumer2 : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Interface2 *i READ interface WRITE setInterface NOTIFY interfaceChanged)
+ Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
+
+ QML_ELEMENT
+
+public:
+
+ Interface2* interface() const
+ {
+ return m_interface;
+ }
+ void setInterface(Interface2* interface2)
+ {
+ QObject* object = reinterpret_cast<QObject*>(interface2);
+ m_testValue = object->property("i").toInt();
+ emit testValueChanged();
+ if (m_interface == interface2)
+ return;
+
+ m_interface = interface2;
+ emit interfaceChanged();
+ }
+
+ int testValue() {
+ return m_testValue;
+ }
+
+signals:
+ void interfaceChanged();
+ void testValueChanged();
+
+private:
+ Interface2 *m_interface = nullptr;
+ int m_testValue = 0;
+};
+
+#endif // INTERFACES_H
diff --git a/tests/auto/qml/qqmlproperty/qqmlproperty.pro b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
index b1bcf1f17d..4d42975369 100644
--- a/tests/auto/qml/qqmlproperty/qqmlproperty.pro
+++ b/tests/auto/qml/qqmlproperty/qqmlproperty.pro
@@ -1,7 +1,10 @@
-CONFIG += testcase
+CONFIG += testcase qmltypes
TARGET = tst_qqmlproperty
macx:CONFIG -= app_bundle
+QML_IMPORT_NAME = io.qt.bugreports
+QML_IMPORT_VERSION = 2.0
+
SOURCES += tst_qqmlproperty.cpp
include (../../shared/util.pri)
@@ -9,3 +12,6 @@ include (../../shared/util.pri)
TESTDATA = data/*
QT += core-private gui-private qml-private testlib
+
+HEADERS += \
+ interfaces.h
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 864a47e998..8a96fc52c5 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -25,6 +25,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+
+#include "interfaces.h"
#include <qtest.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
@@ -157,6 +159,8 @@ private slots:
void copy();
+ void bindingToAlias();
+
void nestedQQmlPropertyMap();
void underscorePropertyChangeHandler();
@@ -1224,10 +1228,10 @@ void tst_qqmlproperty::read()
}
{
QQmlComponent component(&engine, testFileUrl("readSynthesizedObject.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QQmlProperty p(object, "test", &engine);
+ QQmlProperty p(object.data(), "test", &engine);
QCOMPARE(p.propertyTypeCategory(), QQmlProperty::Object);
QVERIFY(p.propertyType() != QMetaType::QObjectStar);
@@ -1239,10 +1243,10 @@ void tst_qqmlproperty::read()
}
{ // static
QQmlComponent component(&engine, testFileUrl("readSynthesizedObject.qml"));
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QVariant v = QQmlProperty::read(object, "test", &engine);
+ QVariant v = QQmlProperty::read(object.data(), "test", &engine);
QCOMPARE(v.userType(), int(QMetaType::QObjectStar));
QCOMPARE(qvariant_cast<QObject *>(v)->property("a").toInt(), 10);
QCOMPARE(qvariant_cast<QObject *>(v)->property("b").toInt(), 19);
@@ -1252,41 +1256,38 @@ void tst_qqmlproperty::read()
{
QQmlComponent component(&engine);
component.setData("import Test 1.0\nMyContainer { }", QUrl());
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QQmlProperty p(object, "MyContainer.foo", qmlContext(object));
+ QQmlProperty p(object.data(), "MyContainer.foo", qmlContext(object.data()));
QCOMPARE(p.read(), QVariant(13));
- delete object;
}
{
QQmlComponent component(&engine);
component.setData("import Test 1.0\nMyContainer { MyContainer.foo: 10 }", QUrl());
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QQmlProperty p(object, "MyContainer.foo", qmlContext(object));
+ QQmlProperty p(object.data(), "MyContainer.foo", qmlContext(object.data()));
QCOMPARE(p.read(), QVariant(10));
- delete object;
}
{
QQmlComponent component(&engine);
component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl());
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QQmlProperty p(object, "Foo.MyContainer.foo", qmlContext(object));
+ QQmlProperty p(object.data(), "Foo.MyContainer.foo", qmlContext(object.data()));
QCOMPARE(p.read(), QVariant(10));
- delete object;
}
{ // static
QQmlComponent component(&engine);
component.setData("import Test 1.0 as Foo\nFoo.MyContainer { Foo.MyContainer.foo: 10 }", QUrl());
- QObject *object = component.create();
+ QScopedPointer<QObject> object(component.create());
QVERIFY(object != nullptr);
- QCOMPARE(QQmlProperty::read(object, "Foo.MyContainer.foo", qmlContext(object)), QVariant(10));
- delete object;
+ QCOMPARE(QQmlProperty::read(object.data(), "Foo.MyContainer.foo",
+ qmlContext(object.data())), QVariant(10));
}
}
@@ -1447,11 +1448,12 @@ void tst_qqmlproperty::write()
{ // QChar -> QString
QQmlComponent component(&engine);
component.setData("import Test 1.0\nPropertyObject { stringProperty: constQChar }", QUrl());
- PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
- QVERIFY(obj != nullptr);
- if (obj) {
- QQmlProperty stringProperty(obj, "stringProperty");
- QCOMPARE(stringProperty.read(), QVariant(QString(obj->constQChar())));
+ QScopedPointer<QObject> object(component.create());
+ PropertyObject *propertyObject = qobject_cast<PropertyObject*>(object.data());
+ QVERIFY(propertyObject != nullptr);
+ if (propertyObject) {
+ QQmlProperty stringProperty(propertyObject, "stringProperty");
+ QCOMPARE(stringProperty.read(), QVariant(QString(propertyObject->constQChar())));
}
}
@@ -1628,29 +1630,32 @@ void tst_qqmlproperty::writeObjectToList()
{
QQmlComponent containerComponent(&engine);
containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl());
- MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create());
+ QScopedPointer<QObject> object(containerComponent.create());
+ MyContainer *container = qobject_cast<MyContainer*>(object.data());
QVERIFY(container != nullptr);
QQmlListReference list(container, "children");
QCOMPARE(list.count(), 1);
- MyQmlObject *object = new MyQmlObject;
+ QScopedPointer<MyQmlObject> childObject(new MyQmlObject);
QQmlProperty prop(container, "children");
- prop.write(QVariant::fromValue(object));
+ prop.write(QVariant::fromValue(childObject.data()));
QCOMPARE(list.count(), 1);
- QCOMPARE(list.at(0), qobject_cast<QObject*>(object));
+ QCOMPARE(list.at(0), qobject_cast<QObject*>(childObject.data()));
}
void tst_qqmlproperty::writeListToList()
{
QQmlComponent containerComponent(&engine);
containerComponent.setData("import Test 1.0\nMyContainer { children: MyQmlObject {} }", QUrl());
- MyContainer *container = qobject_cast<MyContainer*>(containerComponent.create());
+ QScopedPointer<QObject> object(containerComponent.create());
+ MyContainer *container = qobject_cast<MyContainer*>(object.data());
QVERIFY(container != nullptr);
QQmlListReference list(container, "children");
QCOMPARE(list.count(), 1);
QList<QObject*> objList;
- objList << new MyQmlObject() << new MyQmlObject() << new MyQmlObject() << new MyQmlObject();
+ objList << new MyQmlObject(this) << new MyQmlObject(this)
+ << new MyQmlObject(this) << new MyQmlObject(this);
QQmlProperty prop(container, "children");
prop.write(QVariant::fromValue(objList));
QCOMPARE(list.count(), 4);
@@ -1828,10 +1833,11 @@ void tst_qqmlproperty::crashOnValueProperty()
QQmlComponent component(engine);
component.setData("import Test 1.0\nPropertyObject { wrectProperty.x: 10 }", QUrl());
- PropertyObject *obj = qobject_cast<PropertyObject*>(component.create());
- QVERIFY(obj != nullptr);
+ QScopedPointer<QObject> object(component.create());
+ PropertyObject *propertyObject = qobject_cast<PropertyObject*>(object.data());
+ QVERIFY(propertyObject != nullptr);
- QQmlProperty p(obj, "wrectProperty.x", qmlContext(obj));
+ QQmlProperty p(propertyObject, "wrectProperty.x", qmlContext(propertyObject));
QCOMPARE(p.name(), QString("wrectProperty.x"));
QCOMPARE(p.read(), QVariant(10));
@@ -1999,11 +2005,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);
@@ -2090,74 +2094,20 @@ void tst_qqmlproperty::nullPropertyBinding()
QMetaObject::invokeMethod(root.get(), "tog");
}
-struct Interface {
-};
-
-QT_BEGIN_NAMESPACE
-#define MyInterface_iid "io.qt.bugreports.Interface"
-Q_DECLARE_INTERFACE(Interface, MyInterface_iid);
-QT_END_NAMESPACE
-
-class A : public QObject, Interface {
- Q_OBJECT
- Q_INTERFACES(Interface)
-};
-
-class B : public QObject, Interface {
- Q_OBJECT
- Q_INTERFACES(Interface)
-};
-
-class C : public QObject {
- Q_OBJECT
-};
-
-class InterfaceConsumer : public QObject {
- Q_OBJECT
- Q_PROPERTY(Interface* i READ interface WRITE setInterface NOTIFY interfaceChanged)
- Q_PROPERTY(int testValue READ testValue NOTIFY testValueChanged)
-
-
-public:
-
- Interface* interface() const
- {
- return m_interface;
- }
- void setInterface(Interface* interface)
- {
- QObject* object = reinterpret_cast<QObject*>(interface);
- m_testValue = object->property("i").toInt();
- emit testValueChanged();
- if (m_interface == interface)
- return;
-
- m_interface = interface;
- emit interfaceChanged();
- }
-
- int testValue() {
- return m_testValue;
- }
-
-signals:
- void interfaceChanged();
- void testValueChanged();
-
-private:
- Interface* m_interface = nullptr;
- int m_testValue = 0;
-};
void tst_qqmlproperty::interfaceBinding()
{
-
- qmlRegisterInterface<Interface>("Interface");
- qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A");
- qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B");
- qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C");
- qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer");
-
- const QUrl url = testFileUrl("interfaceBinding.qml");
+ qmlRegisterInterface<Interface>("Interface");
+ qmlRegisterType<A>("io.qt.bugreports", 1, 0, "A");
+ qmlRegisterType<B>("io.qt.bugreports", 1, 0, "B");
+ qmlRegisterType<C>("io.qt.bugreports", 1, 0, "C");
+ qmlRegisterType<InterfaceConsumer>("io.qt.bugreports", 1, 0, "InterfaceConsumer");
+
+ const QVector<QUrl> urls = {
+ testFileUrl("interfaceBinding.qml"),
+ testFileUrl("interfaceBinding2.qml")
+ };
+
+ for (const QUrl &url : urls) {
QQmlEngine engine;
QQmlComponent component(&engine, url);
QScopedPointer<QObject> root(component.create());
@@ -2165,6 +2115,7 @@ void tst_qqmlproperty::interfaceBinding()
QCOMPARE(root->findChild<QObject*>("a1")->property("testValue").toInt(), 42);
QCOMPARE(root->findChild<QObject*>("a2")->property("testValue").toInt(), 43);
QCOMPARE(root->findChild<QObject*>("a3")->property("testValue").toInt(), 44);
+ }
}
void tst_qqmlproperty::floatToStringPrecision_data()
@@ -2214,6 +2165,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());
+}
+
void tst_qqmlproperty::nestedQQmlPropertyMap()
{
QQmlPropertyMap mainPropertyMap;
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/formattingLocale.qml b/tests/auto/qml/qqmlqt/data/formattingLocale.qml
new file mode 100644
index 0000000000..9da349b101
--- /dev/null
+++ b/tests/auto/qml/qqmlqt/data/formattingLocale.qml
@@ -0,0 +1,12 @@
+import QtQml 2.15
+
+QtObject {
+ required property var myDateTime
+ required property var myDate
+ property var myTime
+
+ property string dateTimeString: Qt.formatDateTime(myDateTime, Qt.locale("de_DE"), Locale.NarrowFormat)
+ property string dateString: Qt.formatDate(myDate, Qt.locale("de_DE"))
+
+ function invalidUsage() { Qt.formatTime(myTime, null, "hello") }
+}
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..1a54397f1a 100644
--- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
+++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp
@@ -91,6 +91,7 @@ private slots:
void dateTimeFormatting_data();
void dateTimeFormattingVariants();
void dateTimeFormattingVariants_data();
+ void dateTimeFormattingWithLocale();
void isQtObject();
void btoa();
void atob();
@@ -777,24 +778,24 @@ 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;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Invalid date format"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Invalid arguments"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Invalid time format"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Invalid arguments"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Invalid datetime format"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Invalid arguments";
+ warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
+ << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
+ << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
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);
@@ -815,6 +816,8 @@ void tst_qqmlqt::dateTimeFormatting()
void tst_qqmlqt::dateTimeFormatting_data()
{
+ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ // Test intentionally uses deprecated enumerators from Qt::DateFormat
QTest::addColumn<QString>("method");
QTest::addColumn<QStringList>("inputProperties");
QTest::addColumn<QStringList>("expectedResults");
@@ -844,6 +847,7 @@ void tst_qqmlqt::dateTimeFormatting_data()
<< (QStringList() << dateTime.toString(Qt::DefaultLocaleShortDate)
<< dateTime.toString(Qt::DefaultLocaleLongDate)
<< dateTime.toString("M/d/yy H:m:s a"));
+ QT_WARNING_POP
}
void tst_qqmlqt::dateTimeFormattingVariants()
@@ -853,21 +857,20 @@ void tst_qqmlqt::dateTimeFormattingVariants()
QFETCH(QStringList, expectedResults);
QQmlEngine eng;
- eng.rootContext()->setContextProperty("qvariant", variant);
QQmlComponent component(&eng, testFileUrl("formatting.qml"));
QStringList warnings;
- warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Invalid date format"
- << component.url().toString() + ":36: Error: Qt.formatDate(): Invalid arguments"
- << component.url().toString() + ":40: Error: Qt.formatTime(): Invalid time format"
- << component.url().toString() + ":39: Error: Qt.formatTime(): Invalid arguments"
- << component.url().toString() + ":43: Error: Qt.formatDateTime(): Invalid datetime format"
- << component.url().toString() + ":42: Error: Qt.formatDateTime(): Invalid arguments";
+ warnings << component.url().toString() + ":37: Error: Qt.formatDate(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":36: Error: Qt.formatDate(): Missing argument"
+ << component.url().toString() + ":40: Error: Qt.formatTime(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":39: Error: Qt.formatTime(): Missing argument"
+ << component.url().toString() + ":43: Error: Qt.formatDateTime(): Bad second argument (must be either string, number or locale)"
+ << component.url().toString() + ":42: Error: Qt.formatDateTime(): Missing argument";
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);
@@ -883,6 +886,8 @@ void tst_qqmlqt::dateTimeFormattingVariants()
void tst_qqmlqt::dateTimeFormattingVariants_data()
{
+ QT_WARNING_PUSH QT_WARNING_DISABLE_DEPRECATED
+ // Test intentionally uses deprecated enumerators from Qt::DateFormat
QTest::addColumn<QString>("method");
QTest::addColumn<QVariant>("variant");
QTest::addColumn<QStringList>("expectedResults");
@@ -923,6 +928,28 @@ void tst_qqmlqt::dateTimeFormattingVariants_data()
QTest::newRow("formatDate, int") << "formatDate" << QVariant::fromValue(integer) << (QStringList() << temporary.date().toString(Qt::DefaultLocaleShortDate) << temporary.date().toString(Qt::DefaultLocaleLongDate) << temporary.date().toString("ddd MMMM d yy"));
QTest::newRow("formatDateTime, int") << "formatDateTime" << QVariant::fromValue(integer) << (QStringList() << temporary.toString(Qt::DefaultLocaleShortDate) << temporary.toString(Qt::DefaultLocaleLongDate) << temporary.toString("M/d/yy H:m:s a"));
QTest::newRow("formatTime, int") << "formatTime" << QVariant::fromValue(integer) << (QStringList() << temporary.time().toString(Qt::DefaultLocaleShortDate) << temporary.time().toString(Qt::DefaultLocaleLongDate) << temporary.time().toString("H:m:s a") << temporary.time().toString("hh:mm:ss.zzz"));
+ QT_WARNING_POP
+}
+
+void tst_qqmlqt::dateTimeFormattingWithLocale()
+{
+ QQmlEngine engine;
+ auto url = testFileUrl("formattingLocale.qml");
+ QQmlComponent comp(&engine, url);
+ QDateTime dateTime = QDateTime::fromString("M1d1y9800:01:02",
+ "'M'M'd'd'y'yyhh:mm:ss");
+ QDate date(1995, 5, 17);
+ QScopedPointer<QObject> o(comp.createWithInitialProperties({ {"myDateTime", dateTime}, {"myDate", date} }));
+ QVERIFY(!o.isNull());
+
+ auto dateTimeString = o->property("dateTimeString").toString();
+ QCOMPARE(dateTimeString, QLocale("de_DE").toString(dateTime, QLocale::NarrowFormat));
+ auto dateString = o->property("dateString").toString();
+ QCOMPARE(dateString, QLocale("de_DE").toString(date, QLocale::ShortFormat));
+
+ QString warningMsg = url.toString() + QLatin1String(":11: Error: Qt.formatTime(): Third argument must be a Locale format option");
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, warningMsg.toUtf8().constData());
+ QMetaObject::invokeMethod(o.get(), "invalidUsage");
}
void tst_qqmlqt::isQtObject()
@@ -1174,6 +1201,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 +1282,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/qqmltablemodel/qqmltablemodel.pro b/tests/auto/qml/qqmltablemodel/qqmltablemodel.pro
index 9d298dfdf2..11b11132aa 100644
--- a/tests/auto/qml/qqmltablemodel/qqmltablemodel.pro
+++ b/tests/auto/qml/qqmltablemodel/qqmltablemodel.pro
@@ -7,4 +7,4 @@ include (../../shared/util.pri)
TESTDATA = data/*
-QT += core gui qml-private qml quick-private quick testlib qmlmodels-private
+QT += core gui qml-private qml quick-private quick testlib
diff --git a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp
index 321896a8f3..3923824fa2 100644
--- a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp
+++ b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -29,8 +29,8 @@
#include <QtTest/qtest.h>
#include <QtTest/qsignalspy.h>
#include <QtCore/qregularexpression.h>
+#include <QtCore/qabstractitemmodel.h>
#include <QtQml/private/qqmlengine_p.h>
-#include <QtQmlModels/private/qqmltablemodel_p.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
@@ -69,7 +69,7 @@ void tst_QQmlTableModel::appendRemoveRow()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel") .value<QAbstractTableModel *>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -214,7 +214,7 @@ void tst_QQmlTableModel::appendRowToEmptyModel()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 0);
QCOMPARE(model->columnCount(), 2);
@@ -249,7 +249,7 @@ void tst_QQmlTableModel::clear()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -288,7 +288,7 @@ void tst_QQmlTableModel::getRow()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -319,7 +319,7 @@ void tst_QQmlTableModel::insertRow()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -475,7 +475,7 @@ void tst_QQmlTableModel::moveRow()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->columnCount(), 2);
QCOMPARE(model->rowCount(), 2);
@@ -603,7 +603,7 @@ void tst_QQmlTableModel::setRow()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->columnCount(), 2);
QCOMPARE(model->rowCount(), 2);
@@ -763,7 +763,7 @@ void tst_QQmlTableModel::setDataThroughDelegate()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -826,7 +826,7 @@ void tst_QQmlTableModel::setRowsImperatively()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 0);
QCOMPARE(model->columnCount(), 2);
@@ -863,7 +863,7 @@ void tst_QQmlTableModel::setRowsMultipleTimes()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -920,7 +920,7 @@ void tst_QQmlTableModel::dataAndEditing()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("model").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("model").value<QAbstractTableModel*>();
QVERIFY(model);
const QHash<int, QByteArray> roleNames = model->roleNames();
@@ -940,7 +940,7 @@ void tst_QQmlTableModel::omitTableModelColumnIndex()
QQmlComponent component(&engine, testFileUrl("omitTableModelColumnIndex.qml"));
QCOMPARE(component.status(), QQmlComponent::Ready);
- QScopedPointer<QQmlTableModel> model(qobject_cast<QQmlTableModel*>(component.create()));
+ QScopedPointer<QAbstractTableModel> model(qobject_cast<QAbstractTableModel*>(component.create()));
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -964,7 +964,7 @@ void tst_QQmlTableModel::complexRow()
QCOMPARE(tableView->rows(), 2);
QCOMPARE(tableView->columns(), 2);
- QQmlTableModel *model = tableView->model().value<QQmlTableModel*>();
+ auto *model = tableView->model().value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
@@ -983,7 +983,7 @@ void tst_QQmlTableModel::appendRowWithDouble()
view.show();
QVERIFY(QTest::qWaitForWindowActive(&view));
- QQmlTableModel *model = view.rootObject()->property("testModel").value<QQmlTableModel*>();
+ auto *model = view.rootObject()->property("testModel").value<QAbstractTableModel*>();
QVERIFY(model);
QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->columnCount(), 2);
diff --git a/tests/auto/qml/qqmltypeloader/data/declarativeCppType.qml b/tests/auto/qml/qqmltypeloader/data/declarativeCppType.qml
new file mode 100644
index 0000000000..9061f3beb5
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/data/declarativeCppType.qml
@@ -0,0 +1,6 @@
+import QtQml 2.0
+import declarative.import.for.typeloader.test 3.2
+
+DeclarativeTestType {
+ objectName: "ddddd"
+}
diff --git a/tests/auto/qml/qqmltypeloader/declarativetesttype.h b/tests/auto/qml/qqmltypeloader/declarativetesttype.h
new file mode 100644
index 0000000000..a21cdcfd1d
--- /dev/null
+++ b/tests/auto/qml/qqmltypeloader/declarativetesttype.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef DECLARATIVETESTTYPE_H
+#define DECLARATIVETESTTYPE_H
+
+#include <QObject>
+#include <qqml.h>
+
+class DeclarativeTestType : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+
+public:
+ explicit DeclarativeTestType(QObject *parent = nullptr) : QObject(parent) {}
+};
+
+#endif // DECLARATIVETESTTYPE_H
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
index 9ad53aaa8b..266a4e97d6 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.cpp
@@ -58,9 +58,11 @@ private slots:
void qmlSingletonWithinModule();
void multiSingletonModule();
void implicitComponentModule();
+ void customDiskCachePath();
void qrcRootPathUrl();
void implicitImport();
void compositeSingletonCycle();
+ void declarativeCppType();
};
void tst_QQMLTypeLoader::testLoadComplete()
@@ -94,6 +96,8 @@ void tst_QQMLTypeLoader::trimCache()
{
QQmlEngine engine;
QQmlTypeLoader &loader = QQmlEnginePrivate::get(&engine)->typeLoader;
+ QVector<QQmlTypeData *> releaseLater;
+ QVector<QV4::ExecutableCompilationUnit *> releaseCompilationUnitLater;
for (int i = 0; i < 256; ++i) {
QUrl url = testFileUrl("trim_cache.qml");
url.setQuery(QString::number(i));
@@ -106,8 +110,10 @@ void tst_QQMLTypeLoader::trimCache()
// QQmlTypeData or its compiledData() should prevent the trimming.
if (i % 10 == 0) {
// keep ref on data, don't add ref on data->compiledData()
+ releaseLater.append(data);
} else if (i % 5 == 0) {
data->compilationUnit()->addref();
+ releaseCompilationUnitLater.append(data->compilationUnit());
data->release();
} else {
data->release();
@@ -123,6 +129,12 @@ void tst_QQMLTypeLoader::trimCache()
QVERIFY(!loader.isTypeLoaded(url));
// The cache is free to keep the others.
}
+
+ for (auto *data : qAsConst(releaseCompilationUnitLater))
+ data->release();
+
+ for (auto *data : qAsConst(releaseLater))
+ data->release();
}
void tst_QQMLTypeLoader::trimCache2()
@@ -508,6 +520,35 @@ void tst_QQMLTypeLoader::implicitComponentModule()
checkCleanCacheLoad(QLatin1String("implicitComponentModule"));
}
+void tst_QQMLTypeLoader::customDiskCachePath()
+{
+#if QT_CONFIG(process)
+ const char *skipKey = "QT_TST_QQMLTYPELOADER_SKIP_MISMATCH";
+ if (qEnvironmentVariableIsSet(skipKey)) {
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("Base.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Ready);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+ return;
+ }
+
+ QTemporaryDir dir;
+ QProcess child;
+ child.setProgram(QCoreApplication::applicationFilePath());
+ child.setArguments(QStringList(QLatin1String("customDiskCachePath")));
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert(QLatin1String(skipKey), QLatin1String("1"));
+ env.insert(QLatin1String("QML_DISK_CACHE_PATH"), dir.path());
+ child.setProcessEnvironment(env);
+ child.start();
+ QVERIFY(child.waitForFinished());
+ QCOMPARE(child.exitCode(), 0);
+ QDir cacheDir(dir.path());
+ QVERIFY(!cacheDir.isEmpty());
+#endif
+}
+
void tst_QQMLTypeLoader::qrcRootPathUrl()
{
QQmlEngine engine;
@@ -542,6 +583,15 @@ void tst_QQMLTypeLoader::compositeSingletonCycle()
QCOMPARE(qvariant_cast<QColor>(object->property("color")), QColorConstants::Black);
}
+void tst_QQMLTypeLoader::declarativeCppType()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("declarativeCppType.qml"));
+ QCOMPARE(component.status(), QQmlComponent::Ready);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(!obj.isNull());
+}
+
QTEST_MAIN(tst_QQMLTypeLoader)
#include "tst_qqmltypeloader.moc"
diff --git a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
index 0352561e03..19834ff537 100644
--- a/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
+++ b/tests/auto/qml/qqmltypeloader/tst_qqmltypeloader.pro
@@ -1,4 +1,4 @@
-CONFIG += testcase
+CONFIG += testcase qmltypes
TARGET = tst_qqmltypeloader
QT += qml testlib qml-private quick
macx:CONFIG -= app_bundle
@@ -8,7 +8,10 @@ SOURCES += \
../../shared/testhttpserver.cpp
HEADERS += \
- ../../shared/testhttpserver.h
+ ../../shared/testhttpserver.h \
+ declarativetesttype.h
-include (../../shared/util.pri)
+QML_IMPORT_VERSION = 3.2
+QML_IMPORT_NAME = "declarative.import.for.typeloader.test"
+include (../../shared/util.pri)
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/qmlproperty_read.qml b/tests/auto/qml/qqmlvaluetypes/data/qmlproperty_read.qml
new file mode 100644
index 0000000000..b9c9ee779b
--- /dev/null
+++ b/tests/auto/qml/qqmlvaluetypes/data/qmlproperty_read.qml
@@ -0,0 +1,9 @@
+import Test 1.0
+import QtQml 2.0
+
+MyTypeObject {
+ property QtObject colorPropertyObject: colorProperty.object
+ property string colorPropertyName: colorProperty.name
+ property QtObject invalidPropertyObject: invalidProperty.object
+ property string invalidPropertyName: invalidProperty.name
+}
diff --git a/tests/auto/qml/qqmlvaluetypes/testtypes.h b/tests/auto/qml/qqmlvaluetypes/testtypes.h
index 798c96e188..78797f06b1 100644
--- a/tests/auto/qml/qqmlvaluetypes/testtypes.h
+++ b/tests/auto/qml/qqmlvaluetypes/testtypes.h
@@ -48,6 +48,8 @@
#include <private/qqmlproperty_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
+Q_DECLARE_METATYPE(QQmlProperty)
+
class MyTypeObject : public QObject
{
Q_OBJECT
@@ -71,6 +73,8 @@ class MyTypeObject : public QObject
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)
+ Q_PROPERTY(QQmlProperty colorProperty READ colorProperty CONSTANT)
+ Q_PROPERTY(QQmlProperty invalidProperty READ invalidProperty CONSTANT)
public:
MyTypeObject() :
@@ -173,6 +177,10 @@ public:
QVariant variant() const { return sizef(); }
+ QQmlProperty colorProperty() { return QQmlProperty(this, "color"); }
+
+ QQmlProperty invalidProperty() const { return QQmlProperty(); }
+
void emitRunScript() { emit runScript(); }
signals:
diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
index 3e9047cc5a..7c75743311 100644
--- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
+++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp
@@ -67,6 +67,7 @@ private slots:
void color();
void variant();
void locale();
+ void qmlproperty();
void bindingAssignment();
void bindingRead();
@@ -360,6 +361,20 @@ void tst_qqmlvaluetypes::locale()
}
}
+void tst_qqmlvaluetypes::qmlproperty()
+{
+ QQmlComponent component(&engine, testFileUrl("qmlproperty_read.qml"));
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(object != nullptr);
+
+ QCOMPARE(object->property("colorPropertyObject").value<QObject *>(), object);
+ QCOMPARE(object->property("colorPropertyName").toString(), "color");
+ QCOMPARE(object->property("invalidPropertyObject").value<QObject *>(), nullptr);
+ QCOMPARE(object->property("invalidPropertyName").toString(), "");
+
+ delete object;
+}
+
void tst_qqmlvaluetypes::sizereadonly()
{
{
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/file_request.qml b/tests/auto/qml/qqmlxmlhttprequest/data/file_request.qml
new file mode 100644
index 0000000000..51020c185e
--- /dev/null
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/file_request.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.0
+
+QtObject {
+ // Inputs
+
+ id: root
+
+ property string writeURL
+ property string readURL
+ // Outputs
+ property bool writeDone: false
+ property variant readResult
+
+ Component.onCompleted: {
+ // PUT
+ var xhrWrite = new XMLHttpRequest;
+ xhrWrite.open("PUT", writeURL);
+ xhrWrite.onreadystatechange = function() {
+ if (xhrWrite.readyState === XMLHttpRequest.DONE)
+ writeDone = true;
+ };
+ xhrWrite.send("Test-String");
+ // GET
+ var xhrRead = new XMLHttpRequest;
+ xhrRead.open("GET", readURL);
+ xhrRead.onreadystatechange = function() {
+ if (xhrRead.readyState === XMLHttpRequest.DONE)
+ readResult = xhrRead.responseText;
+ };
+ xhrRead.send();
+ }
+}
diff --git a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
index 6cf80ccfdb..ae794e76a9 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
+++ b/tests/auto/qml/qqmlxmlhttprequest/tst_qqmlxmlhttprequest.cpp
@@ -35,6 +35,13 @@
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
+#include <QTemporaryFile>
+
+#if QT_CONFIG(process)
+#include <QProcess>
+#include <QProcessEnvironment>
+#endif
+
#include "testhttpserver.h"
#include "../../shared/util.h"
@@ -45,6 +52,8 @@ public:
tst_qqmlxmlhttprequest() {}
private slots:
+ void initTestCase();
+
void domExceptionCodes();
void callbackException();
void callbackException_data();
@@ -97,6 +106,14 @@ private slots:
void nonUtf8();
void nonUtf8_data();
+ void sendFileRequest();
+
+#if QT_CONFIG(process)
+ void sendFileRequestNotSet();
+ void sendFileRequestNoWrite();
+ void sendFileRequestNoRead();
+#endif
+
// WebDAV
void sendPropfind();
void sendPropfind_data();
@@ -119,13 +136,27 @@ private slots:
void stateChangeCallingContext();
private:
- QQmlEngine engine;
+ void doFileRequest(std::function<void(QObject *component, QTemporaryFile &writeFile)> verifyFunction);
+
+ QScopedPointer<QQmlEngine> engine;
};
+void tst_qqmlxmlhttprequest::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+
+ if (!qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) {
+ qputenv("QML_XHR_ALLOW_FILE_READ", "1");
+ qputenv("QML_XHR_ALLOW_FILE_WRITE", "1");
+ }
+
+ engine.reset(new QQmlEngine);
+}
+
// Test that the dom exception codes are correct
void tst_qqmlxmlhttprequest::domExceptionCodes()
{
- QQmlComponent component(&engine, testFileUrl("domExceptionCodes.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("domExceptionCodes.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -168,8 +199,8 @@ void tst_qqmlxmlhttprequest::callbackException()
QString expect = testFileUrl("callbackException.qml").toString() + ":"+QString::number(line)+": Error: Exception from Callback";
QTest::ignoreMessage(QtWarningMsg, expect.toLatin1());
- QQmlComponent component(&engine, testFileUrl("callbackException.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("callbackException.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", "testdocument.html");
object->setProperty("which", which);
@@ -182,7 +213,7 @@ void tst_qqmlxmlhttprequest::callbackException()
// ### WebKit does not do this, but it seems to fit the standard and QML better
void tst_qqmlxmlhttprequest::staticStateValues()
{
- QQmlComponent component(&engine, testFileUrl("staticStateValues.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("staticStateValues.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -196,7 +227,7 @@ void tst_qqmlxmlhttprequest::staticStateValues()
// Test that the state value properties on instances have the correct values.
void tst_qqmlxmlhttprequest::instanceStateValues()
{
- QQmlComponent component(&engine, testFileUrl("instanceStateValues.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("instanceStateValues.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -210,7 +241,7 @@ void tst_qqmlxmlhttprequest::instanceStateValues()
// Test calling constructor
void tst_qqmlxmlhttprequest::constructor()
{
- QQmlComponent component(&engine, testFileUrl("constructor.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("constructor.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -221,7 +252,7 @@ void tst_qqmlxmlhttprequest::constructor()
// Test that all the properties are set correctly before any request is sent
void tst_qqmlxmlhttprequest::defaultState()
{
- QQmlComponent component(&engine, testFileUrl("defaultState.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("defaultState.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -248,8 +279,8 @@ void tst_qqmlxmlhttprequest::open()
url = server.urlString(url);
}
- QQmlComponent component(&engine, qmlFile);
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), qmlFile);
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", url);
component.completeCreate();
@@ -281,7 +312,7 @@ void tst_qqmlxmlhttprequest::open_data()
// Test that calling XMLHttpRequest.open() with an invalid method raises an exception
void tst_qqmlxmlhttprequest::open_invalid_method()
{
- QQmlComponent component(&engine, testFileUrl("open_invalid_method.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("open_invalid_method.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -330,8 +361,8 @@ void tst_qqmlxmlhttprequest::open_sync()
{
TestThreadedHTTPServer server(testFileUrl("open_network.expect"), testFileUrl("open_network.reply"), testFileUrl("testdocument.html"));
- QQmlComponent component(&engine, testFileUrl("open_sync.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("open_sync.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.serverBaseUrl.resolved(QStringLiteral("/testdocument.html")).toString());
component.completeCreate();
@@ -343,7 +374,7 @@ void tst_qqmlxmlhttprequest::open_sync()
void tst_qqmlxmlhttprequest::open_arg_count()
{
{
- QQmlComponent component(&engine, testFileUrl("open_arg_count.1.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("open_arg_count.1.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -351,7 +382,7 @@ void tst_qqmlxmlhttprequest::open_arg_count()
}
{
- QQmlComponent component(&engine, testFileUrl("open_arg_count.2.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("open_arg_count.2.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -368,8 +399,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader()
testFileUrl("setRequestHeader.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("setRequestHeader.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
component.completeCreate();
@@ -386,8 +417,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader_caseInsensitive()
testFileUrl("setRequestHeader.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("setRequestHeader_caseInsensitive.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader_caseInsensitive.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
component.completeCreate();
@@ -397,7 +428,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_caseInsensitive()
// Test setting headers before open() throws exception
void tst_qqmlxmlhttprequest::setRequestHeader_unsent()
{
- QQmlComponent component(&engine, testFileUrl("setRequestHeader_unsent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader_unsent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -443,8 +474,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader_illegalName()
testFileUrl("open_network.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("setRequestHeader_illegalName.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader_illegalName.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
object->setProperty("header", name);
@@ -469,8 +500,8 @@ void tst_qqmlxmlhttprequest::setRequestHeader_sent()
testFileUrl("open_network.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("setRequestHeader_sent.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader_sent.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
component.completeCreate();
@@ -483,7 +514,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_sent()
// Invalid arg count throws exception
void tst_qqmlxmlhttprequest::setRequestHeader_args()
{
- QQmlComponent component(&engine, testFileUrl("setRequestHeader_args.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("setRequestHeader_args.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -493,7 +524,7 @@ void tst_qqmlxmlhttprequest::setRequestHeader_args()
// Test that calling send() in UNSENT state throws an exception
void tst_qqmlxmlhttprequest::send_unsent()
{
- QQmlComponent component(&engine, testFileUrl("send_unsent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("send_unsent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -503,7 +534,7 @@ void tst_qqmlxmlhttprequest::send_unsent()
// Test attempting to resend a sent request throws an exception
void tst_qqmlxmlhttprequest::send_alreadySent()
{
- QQmlComponent component(&engine, testFileUrl("send_alreadySent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("send_alreadySent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -521,8 +552,8 @@ void tst_qqmlxmlhttprequest::send_ignoreData()
testFileUrl("send_ignoreData.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("send_ignoreData.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("send_ignoreData.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("reqType", "GET");
object->setProperty("url", server.urlString("/testdocument.html"));
@@ -538,8 +569,8 @@ void tst_qqmlxmlhttprequest::send_ignoreData()
testFileUrl("send_ignoreData.reply"),
QUrl()));
- QQmlComponent component(&engine, testFileUrl("send_ignoreData.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("send_ignoreData.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("reqType", "HEAD");
object->setProperty("url", server.urlString("/testdocument.html"));
@@ -555,8 +586,8 @@ void tst_qqmlxmlhttprequest::send_ignoreData()
testFileUrl("send_ignoreData.reply"),
QUrl()));
- QQmlComponent component(&engine, testFileUrl("send_ignoreData.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("send_ignoreData.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("reqType", "DELETE");
object->setProperty("url", server.urlString("/testdocument.html"));
@@ -578,8 +609,8 @@ void tst_qqmlxmlhttprequest::send_withdata()
testFileUrl("send_data.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl(file_qml));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl(file_qml));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
component.completeCreate();
@@ -615,8 +646,8 @@ void tst_qqmlxmlhttprequest::send_options()
testFileUrl(file_reply),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl(file_qml));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl(file_qml));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
QString url = server.baseUrl().toString();
if (url_suffix != "/")
@@ -652,8 +683,8 @@ void tst_qqmlxmlhttprequest::send_patch()
// the content of response file will be ignored due to 204 status code
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("send_patch.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("send_patch.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/qqmlxmlhttprequest.cpp"));
component.completeCreate();
@@ -666,8 +697,8 @@ void tst_qqmlxmlhttprequest::send_patch()
// Test abort() has no effect in unsent state
void tst_qqmlxmlhttprequest::abort_unsent()
{
- QQmlComponent component(&engine, testFileUrl("abort_unsent.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("abort_unsent.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", "testdocument.html");
component.completeCreate();
@@ -685,8 +716,8 @@ void tst_qqmlxmlhttprequest::abort_unsent()
// Test abort() cancels an open (but unsent) request
void tst_qqmlxmlhttprequest::abort_opened()
{
- QQmlComponent component(&engine, testFileUrl("abort_opened.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("abort_opened.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", "testdocument.html");
component.completeCreate();
@@ -710,8 +741,8 @@ void tst_qqmlxmlhttprequest::abort()
testFileUrl("abort.reply"),
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("abort.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("abort.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
const QUrl url = server.url("/testdocument.html");
QUrl dummyUrl = url;
@@ -767,7 +798,7 @@ void tst_qqmlxmlhttprequest::getResponseHeader()
// Test getResponseHeader throws an exception in an invalid state
void tst_qqmlxmlhttprequest::getResponseHeader_unsent()
{
- QQmlComponent component(&engine, testFileUrl("getResponseHeader_unsent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getResponseHeader_unsent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -777,7 +808,7 @@ void tst_qqmlxmlhttprequest::getResponseHeader_unsent()
// Test getResponseHeader throws an exception in an invalid state
void tst_qqmlxmlhttprequest::getResponseHeader_sent()
{
- QQmlComponent component(&engine, testFileUrl("getResponseHeader_sent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getResponseHeader_sent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -787,7 +818,7 @@ void tst_qqmlxmlhttprequest::getResponseHeader_sent()
// Invalid arg count throws exception
void tst_qqmlxmlhttprequest::getResponseHeader_args()
{
- QQmlComponent component(&engine, testFileUrl("getResponseHeader_args.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getResponseHeader_args.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -827,7 +858,7 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders()
// Test getAllResponseHeaders throws an exception in an invalid state
void tst_qqmlxmlhttprequest::getAllResponseHeaders_unsent()
{
- QQmlComponent component(&engine, testFileUrl("getAllResponseHeaders_unsent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getAllResponseHeaders_unsent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -837,7 +868,7 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders_unsent()
// Test getAllResponseHeaders throws an exception in an invalid state
void tst_qqmlxmlhttprequest::getAllResponseHeaders_sent()
{
- QQmlComponent component(&engine, testFileUrl("getAllResponseHeaders_sent.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getAllResponseHeaders_sent.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -847,7 +878,7 @@ void tst_qqmlxmlhttprequest::getAllResponseHeaders_sent()
// Invalid arg count throws exception
void tst_qqmlxmlhttprequest::getAllResponseHeaders_args()
{
- QQmlComponent component(&engine, testFileUrl("getAllResponseHeaders_args.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("getAllResponseHeaders_args.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -862,8 +893,8 @@ void tst_qqmlxmlhttprequest::getBinaryData()
testFileUrl("receive_binary_data.reply"),
testFileUrl("qml_logo.png")));
- QQmlComponent component(&engine, testFileUrl("receiveBinaryData.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("receiveBinaryData.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/gml_logo.png"));
component.completeCreate();
@@ -881,8 +912,8 @@ void tst_qqmlxmlhttprequest::getJsonData()
testFileUrl("receive_binary_data.reply"),
testFileUrl("json.data")));
- QQmlComponent component(&engine, testFileUrl("receiveJsonData.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("receiveJsonData.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/json.data"));
component.completeCreate();
@@ -901,8 +932,8 @@ void tst_qqmlxmlhttprequest::status()
replyUrl,
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("status.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("status.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
object->setProperty("expectedStatus", status);
@@ -943,8 +974,8 @@ void tst_qqmlxmlhttprequest::statusText()
replyUrl,
testFileUrl("testdocument.html")));
- QQmlComponent component(&engine, testFileUrl("statusText.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("statusText.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
object->setProperty("expectedStatus", statusText);
@@ -983,8 +1014,8 @@ void tst_qqmlxmlhttprequest::responseText()
replyUrl,
bodyUrl));
- QQmlComponent component(&engine, testFileUrl("responseText.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("responseText.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/testdocument.html"));
object->setProperty("expectedText", responseText);
@@ -1020,7 +1051,7 @@ void tst_qqmlxmlhttprequest::nonUtf8()
QFETCH(QString, responseText);
QFETCH(QString, xmlRootNodeValue);
- QQmlComponent component(&engine, testFileUrl("utf16.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("utf16.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1053,6 +1084,163 @@ void tst_qqmlxmlhttprequest::nonUtf8_data()
QTest::newRow("responseXML") << "utf16.xml" << "<?xml version=\"1.0\" encoding=\"UTF-16\" standalone='yes'?>\n<root>\n" + uc + "\n</root>\n" << QString('\n' + uc + '\n');
}
+static const QString testString = QStringLiteral("Test-String");
+
+void tst_qqmlxmlhttprequest::doFileRequest(std::function<void(QObject *component, QTemporaryFile &writeFile)> verifyFunction)
+{
+ // Create test files
+ QTemporaryFile writeFile;
+ QTemporaryFile readFile;
+
+ writeFile.open();
+ writeFile.close();
+
+ QVERIFY(readFile.open());
+ readFile.write(testString.toUtf8());
+ readFile.close();
+
+ // Avoid cached environment variables
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("file_request.qml"));
+
+ const QVariantMap properties = {
+ {"writeURL", QUrl::fromLocalFile(writeFile.fileName()).toString()},
+ {"readURL", QUrl::fromLocalFile(readFile.fileName()).toString()}
+ };
+
+ QScopedPointer<QObject> object(component.createWithInitialProperties(properties, engine.rootContext()));
+ QVERIFY(!object.isNull());
+
+ verifyFunction(object.get(), writeFile);
+}
+
+// Test file:// requests
+void tst_qqmlxmlhttprequest::sendFileRequest()
+{
+ // Test with both writing and reading allowed
+ doFileRequest([](QObject* object, QTemporaryFile &writeFile) {
+ QTRY_COMPARE(object->property("readResult").toString(), testString);
+
+ QTRY_VERIFY(object->property("writeDone").toBool());
+
+ QVERIFY(writeFile.open());
+ QCOMPARE(QString::fromUtf8(writeFile.readAll()), testString);
+ writeFile.close();
+ });
+}
+
+#if QT_CONFIG(process)
+void tst_qqmlxmlhttprequest::sendFileRequestNotSet() {
+ if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) {
+ // Test with no settings
+ // Should just result in warnings in Qt 5
+ doFileRequest([](QObject* object, QTemporaryFile &writeFile) {
+ QTRY_COMPARE(object->property("readResult").toString(), testString);
+
+ QTRY_VERIFY(object->property("writeDone").toBool());
+
+ QVERIFY(writeFile.open());
+ QCOMPARE(QString::fromUtf8(writeFile.readAll()), testString);
+ writeFile.close();
+ });
+ return;
+ }
+
+ QProcess child;
+ child.setProgram(QCoreApplication::applicationFilePath());
+ child.setArguments(QStringList(QLatin1String("sendFileRequestNotSet")));
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert(QLatin1String("TEST_CUSTOM_PERMISSIONS"), QLatin1String("1"));
+ env.remove("QML_XHR_ALLOW_FILE_WRITE");
+ env.remove("QML_XHR_ALLOW_FILE_READ");
+ child.setProcessEnvironment(env);
+ child.start();
+ QVERIFY(child.waitForFinished());
+
+ // Check exit code
+ QCOMPARE(child.exitCode(), 0);
+
+ // Check if all warnings were printed
+ QString output = QString::fromUtf8(child.readAllStandardOutput());
+
+
+ const QString readingWarning = QLatin1String(
+ "XMLHttpRequest: Using GET on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_READ to 1 if you wish to continue using this feature.");
+
+ const QString writingWarning = QLatin1String(
+ "XMLHttpRequest: Using PUT on a local file is dangerous "
+ "and will be disabled by default in a future Qt version."
+ "Set QML_XHR_ALLOW_FILE_WRITE to 1 if you wish to continue using this feature.");
+
+ QVERIFY(output.contains(readingWarning));
+ QVERIFY(output.contains(writingWarning));
+}
+#endif
+
+#if QT_CONFIG(process)
+void tst_qqmlxmlhttprequest::sendFileRequestNoWrite() {
+ if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) {
+ // Test with no writing enabled
+ doFileRequest([](QObject* object, QTemporaryFile &writeFile) {
+ QTRY_COMPARE(object->property("readResult").toString(), testString);
+
+ // Check that the file stays empty
+ QVERIFY(writeFile.open());
+ QCOMPARE(QString::fromUtf8(writeFile.readAll()), "");
+ writeFile.close();
+ });
+ return;
+ }
+
+ QProcess child;
+ child.setProgram(QCoreApplication::applicationFilePath());
+ child.setArguments(QStringList(QLatin1String("sendFileRequestNoWrite")));
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert(QLatin1String("TEST_CUSTOM_PERMISSIONS"), QLatin1String("1"));
+ env.insert(QLatin1String("QML_XHR_ALLOW_FILE_WRITE"), QLatin1String("0"));
+ env.insert(QLatin1String("QML_XHR_ALLOW_FILE_READ"), QLatin1String("1"));
+ child.setProcessEnvironment(env);
+ child.start();
+ QVERIFY(child.waitForFinished());
+ QCOMPARE(child.exitCode(), 0);
+}
+#endif
+
+#if QT_CONFIG(process)
+void tst_qqmlxmlhttprequest::sendFileRequestNoRead() {
+ if (qEnvironmentVariableIsSet("TEST_CUSTOM_PERMISSIONS")) {
+ // Test with no reading enabled
+ doFileRequest([](QObject* object, QTemporaryFile &writeFile) {
+ // Check that the write happens
+ QTRY_VERIFY(object->property("writeDone").toBool());
+
+ QVERIFY(writeFile.open());
+ QCOMPARE(QString::fromUtf8(writeFile.readAll()), testString);
+ writeFile.close();
+
+ // Verify that the read has not yielded any value
+ QVERIFY(object->property("readResult").isNull());
+ });
+ return;
+ }
+
+ QProcess child;
+ child.setProgram(QCoreApplication::applicationFilePath());
+ child.setArguments(QStringList(QLatin1String("sendFileRequestNoRead")));
+ QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+ env.insert(QLatin1String("TEST_CUSTOM_PERMISSIONS"), QLatin1String("1"));
+ env.insert(QLatin1String("QML_XHR_ALLOW_FILE_WRITE"), QLatin1String("1"));
+ env.insert(QLatin1String("QML_XHR_ALLOW_FILE_READ"), QLatin1String("0"));
+ child.setProcessEnvironment(env);
+ child.start();
+ QVERIFY(child.waitForFinished());
+ QCOMPARE(child.exitCode(), 0);
+}
+#endif
+
void tst_qqmlxmlhttprequest::sendPropfind()
{
const QString prefix = "WebDAV//";
@@ -1070,8 +1258,8 @@ void tst_qqmlxmlhttprequest::sendPropfind()
testFileUrl(prefix + replyHeader),
testFileUrl(prefix + replyBody)));
- QQmlComponent component(&engine, testFileUrl(prefix + qml));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl(prefix + qml));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString(resource));
component.completeCreate();
@@ -1097,7 +1285,7 @@ void tst_qqmlxmlhttprequest::sendPropfind_data()
// throws an exception
void tst_qqmlxmlhttprequest::invalidMethodUsage()
{
- QQmlComponent component(&engine, testFileUrl("invalidMethodUsage.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("invalidMethodUsage.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1124,8 +1312,8 @@ void tst_qqmlxmlhttprequest::redirects()
server.addRedirect("redirect.html", server.urlString("/redirecttarget.html"));
server.serveDirectory(dataDirectory());
- QQmlComponent component(&engine, testFileUrl("redirects.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("redirects.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/redirect.html"));
object->setProperty("expectedText", "");
@@ -1141,8 +1329,8 @@ void tst_qqmlxmlhttprequest::redirects()
server.addRedirect("redirect.html", server.urlString("/redirectmissing.html"));
server.serveDirectory(dataDirectory());
- QQmlComponent component(&engine, testFileUrl("redirectError.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("redirectError.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/redirect.html"));
object->setProperty("expectedText", "");
@@ -1158,8 +1346,8 @@ void tst_qqmlxmlhttprequest::redirects()
server.addRedirect("redirect.html", server.urlString("/redirect.html"));
server.serveDirectory(dataDirectory());
- QQmlComponent component(&engine, testFileUrl("redirectRecur.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("redirectRecur.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("url", server.urlString("/redirect.html"));
object->setProperty("expectedText", "");
@@ -1177,7 +1365,7 @@ void tst_qqmlxmlhttprequest::redirects()
void tst_qqmlxmlhttprequest::responseXML_invalid()
{
- QQmlComponent component(&engine, testFileUrl("responseXML_invalid.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("responseXML_invalid.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1189,7 +1377,7 @@ void tst_qqmlxmlhttprequest::responseXML_invalid()
// Test the Document DOM element
void tst_qqmlxmlhttprequest::document()
{
- QQmlComponent component(&engine, testFileUrl("document.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("document.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1201,7 +1389,7 @@ void tst_qqmlxmlhttprequest::document()
// Test the Element DOM element
void tst_qqmlxmlhttprequest::element()
{
- QQmlComponent component(&engine, testFileUrl("element.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("element.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1213,7 +1401,7 @@ void tst_qqmlxmlhttprequest::element()
// Test the Attr DOM element
void tst_qqmlxmlhttprequest::attr()
{
- QQmlComponent component(&engine, testFileUrl("attr.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("attr.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1225,7 +1413,7 @@ void tst_qqmlxmlhttprequest::attr()
// Test the Text DOM element
void tst_qqmlxmlhttprequest::text()
{
- QQmlComponent component(&engine, testFileUrl("text.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("text.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1238,7 +1426,7 @@ void tst_qqmlxmlhttprequest::text()
// Test the CDataSection DOM element
void tst_qqmlxmlhttprequest::cdata()
{
- QQmlComponent component(&engine, testFileUrl("cdata.qml"));
+ QQmlComponent component(engine.get(), testFileUrl("cdata.qml"));
QScopedPointer<QObject> object(component.create());
QVERIFY(!object.isNull());
@@ -1285,8 +1473,8 @@ void tst_qqmlxmlhttprequest::stateChangeCallingContext()
QVERIFY2(server.listen(), qPrintable(server.errorString()));
server.serveDirectory(dataDirectory(), TestHTTPServer::Delay);
- QQmlComponent component(&engine, testFileUrl("stateChangeCallingContext.qml"));
- QScopedPointer<QObject> object(component.beginCreate(engine.rootContext()));
+ QQmlComponent component(engine.get(), testFileUrl("stateChangeCallingContext.qml"));
+ QScopedPointer<QObject> object(component.beginCreate(engine.get()->rootContext()));
QVERIFY(!object.isNull());
object->setProperty("serverBaseUrl", server.baseUrl().toString());
component.completeCreate();
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index ae99e35467..dccd3951b3 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -76,6 +76,7 @@ private slots:
void sortCaseSensitive_data();
void sortCaseSensitive();
void updateProperties();
+ void importBothVersions();
private:
void checkNoErrors(const QQmlComponent& component);
QQmlEngine engine;
@@ -467,6 +468,22 @@ void tst_qquickfolderlistmodel::updateProperties()
QCOMPARE(showHidden.toBool(), true);
}
+void tst_qquickfolderlistmodel::importBothVersions()
+{
+ {
+ QQmlComponent component(&engine, testFileUrl("sortReversed.qml"));
+ checkNoErrors(component);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(obj);
+ }
+ {
+ QQmlComponent component(&engine, testFileUrl("qrc.qml"));
+ checkNoErrors(component);
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(obj);
+ }
+}
+
QTEST_MAIN(tst_qquickfolderlistmodel)
#include "tst_qquickfolderlistmodel.moc"
diff --git a/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml b/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml
index 0ac56d9b66..1d3420e186 100644
--- a/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml
+++ b/tests/auto/qml/qquickworkerscript/data/BaseWorker.qml
@@ -1,11 +1,14 @@
import QtQuick 2.0
+import QtQml.WorkerScript 2.15
WorkerScript {
id: worker
property variant response
+ property bool readyChangedCalled : false
signal done()
+ signal ready()
function testSend(value) {
worker.sendMessage(value)
@@ -20,5 +23,7 @@ WorkerScript {
worker.response = messageObject
worker.done()
}
+
+ onReadyChanged: worker.readyChangedCalled = true
}
diff --git a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
index d11e7bde4b..2f79f7157f 100644
--- a/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
+++ b/tests/auto/qml/qquickworkerscript/tst_qquickworkerscript.cpp
@@ -47,6 +47,7 @@ public:
tst_QQuickWorkerScript() {}
private slots:
void source();
+ void ready();
void messaging();
void messaging_data();
void messaging_sendQObjectList();
@@ -105,6 +106,22 @@ void tst_QQuickWorkerScript::source()
qApp->processEvents();
}
+void tst_QQuickWorkerScript::ready()
+{
+ QQmlComponent component(&m_engine, testFileUrl("worker.qml"));
+ QScopedPointer<QQuickWorkerScript>worker(qobject_cast<QQuickWorkerScript*>(component.create()));
+ QVERIFY(worker != nullptr);
+
+ const QMetaObject *mo = worker->metaObject();
+
+ QTRY_VERIFY(worker->ready());
+
+ QVariant readyChangedCalled = mo->property(mo->indexOfProperty("readyChangedCalled")).read(worker.data()).value<QVariant>();
+
+ QVERIFY(!readyChangedCalled.isNull());
+ QVERIFY(readyChangedCalled.toBool());
+}
+
void tst_QQuickWorkerScript::messaging()
{
QFETCH(QVariant, value);
@@ -152,6 +169,7 @@ void tst_QQuickWorkerScript::messaging_data()
QRegExp::RegExp2));
QTest::newRow("regularexpression") << QVariant::fromValue(QRegularExpression(
"^\\d\\d?$", QRegularExpression::CaseInsensitiveOption));
+ QTest::newRow("url") << QVariant::fromValue(QUrl("http://example.com/foo/bar"));
}
void tst_QQuickWorkerScript::messaging_sendQObjectList()