QtQuick: Add delegateModelAccess test for QQuickTreeView
QQuickTreeView can't handle array or object models and therefore we don't need to take special measures to propagate changes to arrays back out of the view. Change-Id: I0d0bc2ea04b5862c1a2eac71cb9f5195c5b07af6 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
parent
6bc664ac8c
commit
de368f8f4d
|
@ -0,0 +1,92 @@
|
|||
import QtQuick
|
||||
import Test
|
||||
|
||||
Item {
|
||||
width: 100
|
||||
height: 100
|
||||
|
||||
property alias treeView: root
|
||||
|
||||
TreeView {
|
||||
id: root
|
||||
width: 100
|
||||
height: 100
|
||||
|
||||
property Component typedDelegate: Item {
|
||||
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: Item {
|
||||
implicitWidth: 10
|
||||
implicitHeight: 10
|
||||
|
||||
property real immediateX: a
|
||||
property real modelX: model.a
|
||||
|
||||
function writeImmediate() {
|
||||
a = 1;
|
||||
}
|
||||
|
||||
function writeThroughModel() {
|
||||
model.a = 3;
|
||||
}
|
||||
}
|
||||
|
||||
property ListModel singularModel: ListModel {
|
||||
ListElement {
|
||||
a: 11
|
||||
}
|
||||
}
|
||||
|
||||
property ListModel listModel: ListModel {
|
||||
ListElement {
|
||||
a: 11
|
||||
y: 12
|
||||
}
|
||||
}
|
||||
|
||||
function aAt0() : real {
|
||||
switch (modelIndex) {
|
||||
case Model.Singular:
|
||||
case Model.List:
|
||||
return model.get(0).a
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
property int modelIndex: Model.None
|
||||
property int delegateIndex: Delegate.None
|
||||
|
||||
model: {
|
||||
switch (modelIndex) {
|
||||
case Model.Singular: return singularModel
|
||||
case Model.List: return listModel
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
delegate: {
|
||||
switch (delegateIndex) {
|
||||
case Delegate.Untyped: return untypedDelegate
|
||||
case Delegate.Typed: return typedDelegate
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -98,6 +98,8 @@ private slots:
|
|||
void editUsingEditTriggers();
|
||||
void editOnNonEditableCell_data();
|
||||
void editOnNonEditableCell();
|
||||
void delegateModelAccess_data();
|
||||
void delegateModelAccess();
|
||||
};
|
||||
|
||||
tst_qquicktreeview::tst_qquicktreeview()
|
||||
|
@ -1643,6 +1645,135 @@ void tst_qquicktreeview::editOnNonEditableCell()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Model {
|
||||
Q_NAMESPACE
|
||||
QML_ELEMENT
|
||||
enum Kind : qint8
|
||||
{
|
||||
None = -1,
|
||||
Singular,
|
||||
List,
|
||||
};
|
||||
Q_ENUM_NS(Kind)
|
||||
}
|
||||
|
||||
namespace Delegate {
|
||||
Q_NAMESPACE
|
||||
QML_ELEMENT
|
||||
enum Kind : qint8
|
||||
{
|
||||
None = -1,
|
||||
Untyped,
|
||||
Typed
|
||||
};
|
||||
Q_ENUM_NS(Kind)
|
||||
}
|
||||
|
||||
template<typename Enum>
|
||||
const char *enumKey(Enum value) {
|
||||
const QMetaObject *mo = qt_getEnumMetaObject(value);
|
||||
const QMetaEnum metaEnum = mo->enumerator(mo->indexOfEnumerator(qt_getEnumName(value)));
|
||||
return metaEnum.valueToKey(value);
|
||||
}
|
||||
|
||||
void tst_qquicktreeview::delegateModelAccess_data()
|
||||
{
|
||||
QTest::addColumn<QQmlDelegateModel::DelegateModelAccess>("access");
|
||||
QTest::addColumn<Model::Kind>("modelKind");
|
||||
QTest::addColumn<Delegate::Kind>("delegateKind");
|
||||
|
||||
using Access = QQmlDelegateModel::DelegateModelAccess;
|
||||
for (auto access : { Access::Qt5ReadWrite, Access::ReadOnly, Access::ReadWrite }) {
|
||||
for (auto model : { Model::Singular, Model::List }) {
|
||||
for (auto delegate : { Delegate::Untyped, Delegate::Typed }) {
|
||||
QTest::addRow("%s-%s-%s", enumKey(access), enumKey(model), enumKey(delegate))
|
||||
<< access << model << delegate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_qquicktreeview::delegateModelAccess()
|
||||
{
|
||||
static const bool initialized = []() {
|
||||
qmlRegisterNamespaceAndRevisions(&Model::staticMetaObject, "Test", 1);
|
||||
qmlRegisterNamespaceAndRevisions(&Delegate::staticMetaObject, "Test", 1);
|
||||
return true;
|
||||
}();
|
||||
QVERIFY(initialized);
|
||||
|
||||
QFETCH(QQmlDelegateModel::DelegateModelAccess, access);
|
||||
QFETCH(Model::Kind, modelKind);
|
||||
QFETCH(Delegate::Kind, delegateKind);
|
||||
|
||||
const QUrl url = testFileUrl("delegateModelAccess.qml");
|
||||
LOAD_TREEVIEW("delegateModelAccess.qml");
|
||||
|
||||
QSignalSpy modelChangedSpy(treeView, &QQuickTreeView::modelChanged);
|
||||
|
||||
if (access == QQmlDelegateModel::ReadOnly) {
|
||||
const QRegularExpression message(
|
||||
url.toString() + ":[0-9]+: TypeError: Cannot assign to read-only property \"a\"");
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, message);
|
||||
if (delegateKind == Delegate::Untyped)
|
||||
QTest::ignoreMessage(QtWarningMsg, message);
|
||||
}
|
||||
|
||||
treeView->setProperty("delegateModelAccess", access);
|
||||
treeView->setProperty("modelIndex", modelKind);
|
||||
treeView->setProperty("delegateIndex", delegateKind);
|
||||
|
||||
WAIT_UNTIL_POLISHED;
|
||||
|
||||
QCOMPARE(QQuickTreeViewPrivate::get(treeView)->loadedItems.size(), 1);
|
||||
QObject *delegate = QQuickTreeViewPrivate::get(treeView)->loadedItems.begin().value()->item;
|
||||
QVERIFY(delegate);
|
||||
|
||||
const bool modelWritable = access != QQmlDelegateModel::ReadOnly;
|
||||
const bool immediateWritable = (delegateKind == Delegate::Untyped)
|
||||
? access != QQmlDelegateModel::ReadOnly
|
||||
: access == QQmlDelegateModel::ReadWrite;
|
||||
|
||||
double expected = 11;
|
||||
|
||||
// Initial setting of the model, signals one update. Beyond that, no updates are signaled
|
||||
// because we only accept QAIM and the model object doesn't change.
|
||||
QCOMPARE(modelChangedSpy.count(), 1);
|
||||
|
||||
QCOMPARE(delegate->property("immediateX").toDouble(), expected);
|
||||
QCOMPARE(delegate->property("modelX").toDouble(), expected);
|
||||
|
||||
if (modelWritable)
|
||||
expected = 3;
|
||||
|
||||
QMetaObject::invokeMethod(delegate, "writeThroughModel");
|
||||
QCOMPARE(delegate->property("immediateX").toDouble(), expected);
|
||||
QCOMPARE(delegate->property("modelX").toDouble(), expected);
|
||||
QCOMPARE(modelChangedSpy.count(), 1);
|
||||
|
||||
double aAt0 = -1;
|
||||
QMetaObject::invokeMethod(treeView, "aAt0", Q_RETURN_ARG(double, aAt0));
|
||||
QCOMPARE(aAt0, expected);
|
||||
|
||||
if (immediateWritable)
|
||||
expected = 1;
|
||||
|
||||
QMetaObject::invokeMethod(delegate, "writeImmediate");
|
||||
|
||||
// Writes to required properties always succeed, but might not be propagated to the model
|
||||
QCOMPARE(delegate->property("immediateX").toDouble(),
|
||||
delegateKind == Delegate::Untyped ? expected : 1);
|
||||
|
||||
QCOMPARE(delegate->property("modelX").toDouble(), expected);
|
||||
QCOMPARE(modelChangedSpy.count(), 1);
|
||||
|
||||
aAt0 = -1;
|
||||
QMetaObject::invokeMethod(treeView, "aAt0", Q_RETURN_ARG(double, aAt0));
|
||||
QCOMPARE(aAt0, expected);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qquicktreeview)
|
||||
|
||||
#include "tst_qquicktreeview.moc"
|
||||
|
|
Loading…
Reference in New Issue