Android: Add Java QtAbstractItemModel auto test
QtAbstractItemModel used to be a part of QtDeclarative and is being moved to QtCore based on API reviews. Pick-to: 6.8 Task-number: QTBUG-126976 Task-number: QTBUG-127089 Change-Id: I28a921a113ec4f3ad298bf55b40aea334e7721cf Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
55fc15ce82
commit
baed8a24d0
@ -4,6 +4,7 @@
|
||||
if(ANDROID)
|
||||
add_subdirectory(android)
|
||||
add_subdirectory(android_appless)
|
||||
add_subdirectory(androiditemmodel)
|
||||
endif()
|
||||
if(WIN32)
|
||||
add_subdirectory(windows)
|
||||
|
24
tests/auto/corelib/platform/androiditemmodel/CMakeLists.txt
Normal file
24
tests/auto/corelib/platform/androiditemmodel/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2024 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_androiditemmodel Test:
|
||||
#####################################################################
|
||||
|
||||
if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(tst_androiditemmodel LANGUAGES CXX)
|
||||
find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST)
|
||||
endif()
|
||||
|
||||
qt_internal_add_test(tst_androiditemmodel
|
||||
SOURCES
|
||||
tst_androiditemmodel.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::CorePrivate
|
||||
)
|
||||
|
||||
set_property(TARGET tst_androiditemmodel APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/testdata
|
||||
)
|
@ -0,0 +1,134 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
package org.qtproject.qt.android.tests;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.qtproject.qt.android.QtAbstractItemModel;
|
||||
import org.qtproject.qt.android.QtModelIndex;
|
||||
|
||||
public class TestModel extends QtAbstractItemModel
|
||||
{
|
||||
int m_rows = 0;
|
||||
int m_cols = 0;
|
||||
|
||||
@Override
|
||||
public int columnCount(QtModelIndex parent)
|
||||
{
|
||||
return parent.isValid() ? 0 : m_cols;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object data(QtModelIndex index, int role)
|
||||
{
|
||||
int r = index.row();
|
||||
int c = index.column();
|
||||
if (r < 0 || c < 0 || c > m_cols || r > m_rows)
|
||||
return null;
|
||||
|
||||
switch (role) {
|
||||
case 0:
|
||||
return String.format("r%d/c%d", r, c);
|
||||
case 1:
|
||||
return new Boolean(((r + c) % 2) == 0);
|
||||
case 2:
|
||||
return new Integer((c << 8) + r);
|
||||
case 3:
|
||||
return new Double((r + 1.0) / (c + 1.0));
|
||||
case 4:
|
||||
return new Long((c << 8) * (r << 8));
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QtModelIndex index(int row, int column, QtModelIndex parent)
|
||||
{
|
||||
return hasIndex(row, column, parent) ? createIndex(row, column, 0) : new QtModelIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QtModelIndex parent(QtModelIndex qtModelIndex)
|
||||
{
|
||||
return new QtModelIndex();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int rowCount(QtModelIndex parent)
|
||||
{
|
||||
return parent.isValid() ? 0 : m_rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, String> roleNames()
|
||||
{
|
||||
final HashMap<Integer, String> roles = new HashMap<Integer, String>();
|
||||
roles.put(0, "stringRole");
|
||||
roles.put(1, "booleanRole");
|
||||
roles.put(2, "integerRole");
|
||||
roles.put(3, "doubleRole");
|
||||
roles.put(4, "longRole");
|
||||
return roles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFetchMore(QtModelIndex parent)
|
||||
{
|
||||
return !parent.isValid() && (m_rows < 30);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fetchMore(QtModelIndex parent)
|
||||
{
|
||||
if (!canFetchMore(parent))
|
||||
return;
|
||||
int toAdd = Math.min(10, 30 - rowCount(parent));
|
||||
beginInsertRows(new QtModelIndex(), m_rows, m_rows + toAdd - 1);
|
||||
m_rows += toAdd;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
public void addRow()
|
||||
{
|
||||
beginInsertRows(new QtModelIndex(), m_rows, m_rows);
|
||||
m_rows++;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
public void removeRow()
|
||||
{
|
||||
if (m_rows == 0)
|
||||
return;
|
||||
beginRemoveRows(new QtModelIndex(), 0, 0);
|
||||
m_rows--;
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
public void addCol()
|
||||
{
|
||||
beginInsertColumns(new QtModelIndex(), m_cols, m_cols);
|
||||
m_cols++;
|
||||
endInsertColumns();
|
||||
}
|
||||
|
||||
public void removeCol()
|
||||
{
|
||||
if (m_cols == 0)
|
||||
return;
|
||||
beginRemoveColumns(new QtModelIndex(), 0, 0);
|
||||
m_cols--;
|
||||
endRemoveColumns();
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
beginResetModel();
|
||||
m_rows = 0;
|
||||
m_cols = 0;
|
||||
endResetModel();
|
||||
}
|
||||
}
|
@ -0,0 +1,182 @@
|
||||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include <QtTest/QTest>
|
||||
|
||||
#include <QtCore/private/qandroiditemmodelproxy_p.h>
|
||||
#include <QtCore/private/qandroidmodelindexproxy_p.h>
|
||||
#include <QtCore/private/qandroidtypes_p.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QtCore/qabstractitemmodel.h>
|
||||
#include <QtCore/qjniobject.h>
|
||||
#include <QtCore/qjnitypes.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
using namespace Qt::Literals;
|
||||
|
||||
Q_DECLARE_JNI_CLASS(JTestModel, "org/qtproject/qt/android/tests/TestModel")
|
||||
|
||||
class tst_AndroidItemModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
JTestModel jModel;
|
||||
QAbstractItemModel *qProxy;
|
||||
void resetModel();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void cleanup();
|
||||
void addRow();
|
||||
void addColumn();
|
||||
void removeRow();
|
||||
void removeColumn();
|
||||
void roleNames();
|
||||
void fetchMore();
|
||||
void hasIndex();
|
||||
void data();
|
||||
};
|
||||
|
||||
void tst_AndroidItemModel::initTestCase()
|
||||
{
|
||||
QVERIFY(jModel.isValid());
|
||||
qProxy = QAndroidItemModelProxy::createNativeProxy(jModel);
|
||||
QVERIFY(qProxy);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::cleanup()
|
||||
{
|
||||
resetModel();
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::addRow()
|
||||
{
|
||||
const int rowsBefore = qProxy->rowCount();
|
||||
jModel.callMethod<void>("addRow");
|
||||
QCOMPARE_EQ(qProxy->rowCount(), rowsBefore + 1);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::addColumn()
|
||||
{
|
||||
const int columnsBefore = qProxy->columnCount();
|
||||
jModel.callMethod<void>("addCol");
|
||||
QCOMPARE_EQ(qProxy->columnCount(), columnsBefore + 1);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::removeRow()
|
||||
{
|
||||
jModel.callMethod<void>("addRow");
|
||||
jModel.callMethod<void>("addRow");
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 2);
|
||||
jModel.callMethod<void>("removeRow");
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 1);
|
||||
jModel.callMethod<void>("removeRow");
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 0);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::removeColumn()
|
||||
{
|
||||
jModel.callMethod<void>("addCol");
|
||||
jModel.callMethod<void>("addCol");
|
||||
QCOMPARE_EQ(qProxy->columnCount(), 2);
|
||||
jModel.callMethod<void>("removeCol");
|
||||
QCOMPARE_EQ(qProxy->columnCount(), 1);
|
||||
jModel.callMethod<void>("removeCol");
|
||||
QCOMPARE_EQ(qProxy->columnCount(), 0);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::roleNames()
|
||||
{
|
||||
const static QHash<int, QByteArray> expectedRoles = { { 0, "stringRole" },
|
||||
{ 1, "booleanRole" },
|
||||
{ 2, "integerRole" },
|
||||
{ 3, "doubleRole" },
|
||||
{ 4, "longRole" } };
|
||||
QCOMPARE(qProxy->roleNames(), expectedRoles);
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::fetchMore()
|
||||
{
|
||||
// In the Java TestModel :
|
||||
// canFetchMore() returns true when row count is less than 30
|
||||
// fetchMore() adds 10 rows at most, or the remaining until row count is 30
|
||||
QVERIFY(qProxy->canFetchMore(QModelIndex()));
|
||||
qProxy->fetchMore(QModelIndex());
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 10);
|
||||
QVERIFY(qProxy->canFetchMore(QModelIndex()));
|
||||
qProxy->fetchMore(QModelIndex());
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 20);
|
||||
jModel.callMethod<void>("addRow");
|
||||
QVERIFY(qProxy->canFetchMore(QModelIndex()));
|
||||
qProxy->fetchMore(QModelIndex());
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 30);
|
||||
QVERIFY(!qProxy->canFetchMore(QModelIndex()));
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::hasIndex()
|
||||
{
|
||||
// fetchMore() adds 10 rows
|
||||
qProxy->fetchMore(QModelIndex());
|
||||
jModel.callMethod<void>("addCol");
|
||||
jModel.callMethod<void>("addCol");
|
||||
|
||||
for (int r = 0; r < 10; ++r) {
|
||||
for (int c = 0; c < 2; ++c) {
|
||||
QVERIFY(qProxy->hasIndex(r, c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::data()
|
||||
{
|
||||
const static QHash<int, QMetaType::Type> roleToType = { { 0, QMetaType::QString },
|
||||
{ 1, QMetaType::Bool },
|
||||
{ 2, QMetaType::Int },
|
||||
{ 3, QMetaType::Double },
|
||||
{ 4, QMetaType::Long } };
|
||||
QVERIFY(qProxy->canFetchMore(QModelIndex()));
|
||||
qProxy->fetchMore(QModelIndex());
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 10);
|
||||
jModel.callMethod<void>("addCol");
|
||||
jModel.callMethod<void>("addCol");
|
||||
jModel.callMethod<void>("addCol");
|
||||
|
||||
for (int r = 0; r < 10; ++r) {
|
||||
for (int c = 0; c < 3; ++c) {
|
||||
QModelIndex index = qProxy->index(r, c);
|
||||
for (int role : roleToType.keys()) {
|
||||
const QVariant data = qProxy->data(index, role);
|
||||
QCOMPARE_EQ(data.typeId(), roleToType[role]);
|
||||
switch (role) {
|
||||
case 0:
|
||||
QCOMPARE(data.toString(),
|
||||
"r%1/c%2"_L1.arg(QString::number(r), QString::number(c)));
|
||||
break;
|
||||
case 1:
|
||||
QCOMPARE(data.toBool(), ((r + c) % 2) == 0);
|
||||
break;
|
||||
case 2:
|
||||
QCOMPARE(data.toInt(), (c << 8) + r);
|
||||
break;
|
||||
case 3:
|
||||
QVERIFY(qFuzzyCompare(data.toDouble(), (1.0 + r) / (1.0 + c)));
|
||||
break;
|
||||
case 4:
|
||||
QCOMPARE(data.toULongLong(), ((c << 8) * (r << 8)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_AndroidItemModel::resetModel()
|
||||
{
|
||||
jModel.callMethod<void>("reset");
|
||||
QCOMPARE_EQ(qProxy->rowCount(), 0);
|
||||
QCOMPARE_EQ(qProxy->columnCount(), 0);
|
||||
}
|
||||
|
||||
#include "tst_androiditemmodel.moc"
|
||||
|
||||
QTEST_MAIN(tst_AndroidItemModel)
|
Loading…
x
Reference in New Issue
Block a user