diff options
Diffstat (limited to 'tests/auto/qml/qqmllanguage')
75 files changed, 1135 insertions, 37 deletions
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) |