diff options
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/declarative_ui/Delegate.qml | 12 | ||||
-rw-r--r-- | tests/auto/declarative_ui/Model.qml | 14 | ||||
-rw-r--r-- | tests/auto/declarative_ui/tst_map_itemview.qml | 224 |
3 files changed, 250 insertions, 0 deletions
diff --git a/tests/auto/declarative_ui/Delegate.qml b/tests/auto/declarative_ui/Delegate.qml new file mode 100644 index 00000000..210aae29 --- /dev/null +++ b/tests/auto/declarative_ui/Delegate.qml @@ -0,0 +1,12 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQml + +QtObject { + enum Variants { + None = -1, + Untyped, + Typed + } +} diff --git a/tests/auto/declarative_ui/Model.qml b/tests/auto/declarative_ui/Model.qml new file mode 100644 index 00000000..fb3681de --- /dev/null +++ b/tests/auto/declarative_ui/Model.qml @@ -0,0 +1,14 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQml + +QtObject { + enum Variants { + None = -1, + Singular, + List, + Array, + Object + } +} diff --git a/tests/auto/declarative_ui/tst_map_itemview.qml b/tests/auto/declarative_ui/tst_map_itemview.qml index fc4e9472..d4f84b72 100644 --- a/tests/auto/declarative_ui/tst_map_itemview.qml +++ b/tests/auto/declarative_ui/tst_map_itemview.qml @@ -20,6 +20,7 @@ Item { && mapForView.mapReady && mapForTestingListModel.mapReady && mapForTestingRouteModel.mapReady + && mapForTestingDelegateModelAccess.mapReady MapItemView { id: routeItemViewExtra @@ -274,6 +275,100 @@ Item { } } + Map { + id: mapForTestingDelegateModelAccess + + property int mapItemsLength: mapItems.length + + plugin: testPlugin + center: mapDefaultCenter + anchors.fill: parent + zoomLevel: 2 + + MapItemView { + id: delegateModelAccessItemView + width: 100 + height: 100 + + property Component typedDelegate: MapQuickItem { + implicitWidth: 10 + implicitHeight: 10 + + required property QtObject model + + required property real a + + property real immediateX: a + property real modelX: model.a + + function writeImmediate() { + a = 1; + } + + function writeThroughModel() { + model.a = 3; + } + } + + property Component untypedDelegate: MapQuickItem { + implicitWidth: 10 + implicitHeight: 10 + + property real immediateX: a + property real modelX: model.a + + function writeImmediate() { + a = 1; + } + + function writeThroughModel() { + model.a = 3; + } + } + + property Component singularModel: ListModel { + ListElement { + a: 11 + } + } + + property Component listModel: ListModel { + ListElement { + a: 11 + y: 12 + } + } + + function array() { return [ {a: 11, y: 12} ] } + + property Component object: QtObject { + property int a: 11 + property int y: 12 + } + + property int modelIndex: Model.None + property int delegateIndex: Delegate.None + + model: { + switch (modelIndex) { + case Model.Singular: return singularModel.createObject() + case Model.List: return listModel.createObject() + case Model.Array: return array() + case Model.Object: return object.createObject() + } + return undefined; + } + + delegate: { + switch (delegateIndex) { + case Delegate.Untyped: return untypedDelegate + case Delegate.Typed: return typedDelegate + } + return null + } + } + } + TestCase { name: "MapItem" when: windowShown && allMapsReady @@ -555,5 +650,134 @@ Item { mapForTestingRouteModel.clearMapItems() compare(mapForTestingRouteModel.mapItems.length, 0) } + + function test_delegateModelAccess_data() { + function modelKey(value) { + switch (value) { + case Model.None: + return "None" + case Model.Singular: + return "Singular" + case Model.List: + return "List" + case Model.Array: + return "Array" + case Model.Object: + return "Object" + default: + break + } + + return "" + } + + function delegateKey(value) { + switch (value) { + case Delegate.None: + return "None" + case Delegate.Untyped: + return "Untyped" + case Delegate.Typed: + return "Typed" + default: + break + } + + return "" + } + + function accessKey(value) { + switch (value) { + case DelegateModel.Qt5ReadWrite: + return "Qt5ReadWrite" + case DelegateModel.ReadOnly: + return "ReadOnly" + case DelegateModel.ReadWrite: + return "ReadWrite" + default: + break; + } + + return ""; + } + + let data = []; + for (let access of [ + DelegateModel.Qt5ReadWrite, + DelegateModel.ReadOnly, + DelegateModel.ReadWrite]) { + for (let model of [Model.Singular, Model.List, Model.Array, Model.Object]) { + for (let delegate of [Delegate.Untyped, Delegate.Typed]) { + data.push({ + tag: `${accessKey(access)}-${modelKey(model)}-${delegateKey(delegate)}`, + access: access, + modelKind: model, + delegateKind: delegate + }); + } + } + } + return data + } + + function test_delegateModelAccess(data) { + delegateModelAccessItemView.delegateModelAccess = DelegateModel.Qt5ReadWrite + delegateModelAccessItemView.modelIndex = Model.None + delegateModelAccessItemView.delegateIndex = Delegate.None + tryCompare(mapForTestingDelegateModelAccess, "mapItemsLength", 0) + + const access = data.access + const modelKind = data.modelKind + const delegateKind = data.delegateKind + + if (delegateKind === Delegate.Untyped && modelKind === Model.Array) + skip("Properties of objects in arrays are not exposed as context properties") + + delegateModelAccessItemView.delegateModelAccess = access + delegateModelAccessItemView.modelIndex = modelKind + delegateModelAccessItemView.delegateIndex = delegateKind + + tryCompare(mapForTestingDelegateModelAccess, "mapItemsLength", 1) + const delegate = mapForTestingDelegateModelAccess.mapItems[0] + verify(delegate) + + const modelWritable = (access !== DelegateModel.ReadOnly) + const immediateWritable = (delegateKind === Delegate.Untyped) + ? access !== DelegateModel.ReadOnly + : access === DelegateModel.ReadWrite + + let expected = 11 + + compare(delegate.immediateX, expected) + compare(delegate.modelX, expected) + + if (modelWritable) + expected = 3 + + try { + delegate.writeThroughModel() + } catch (e1) { + compare(e1.message, 'Cannot assign to read-only property "a"') + compare(access, DelegateModel.ReadOnly) + } + + compare(delegate.immediateX, expected) + compare(delegate.modelX, expected) + + if (immediateWritable) + expected = 1 + + try { + delegate.writeImmediate() + } catch (e2) { + compare(e2.message, 'Cannot assign to read-only property "a"') + compare(access, DelegateModel.ReadOnly) + compare(delegateKind, Delegate.Untyped) + } + + // Writes to required properties always succeed, but might not be propagated to the model + compare(delegate.immediateX, delegateKind === Delegate.Untyped ? expected : 1) + compare(delegate.modelX, expected) + } } } |