Files
QtModelsToolkit/tests/tst_LeftJoinModel.cpp
Alex Jbanca 8a6632b94e perf(LeftJoinModel): Add LRU cache for right model data access
The right model data access is expensive because we need to search the right model for a matching key on every `data` call. This commit adds a LRU cache to the `data` call, storing by default up to 1000 rows.

The cache mechanism uses a QCache for fast index lookup and a std::list to preserve the access order and to ensure a controlled cache removal.

+ fix compilation errors on ConcatModel and WritableProxyModel
2025-08-15 16:17:16 +03:00

1441 lines
50 KiB
C++

#include <QAbstractItemModelTester>
#include <QSignalSpy>
#include <QTest>
#include <memory>
#include <qtmodelstoolkit/leftjoinmodel.h>
#include <qtmodelstoolkit/testing/persistentindexestester.h>
#include <qtmodelstoolkit/testing/testmodel.h>
using namespace qtmt;
class TestLeftJoinModel: public QObject
{
Q_OBJECT
private slots:
void emptyModelTest() {
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
void initializationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 2);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
QCOMPARE(model.roleNames(), roles);
}
void collidingRolesTest()
{
TestModel leftModel({
{ "name", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Source models contain conflicting model names: "
"\"name\"!");
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
void duplicatedRolesTest()
{
{
TestModel leftModel({
{ "name", { "Token 1", "Token 2" }},
{ "name", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "title", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Each of the source models must have unique "
"role names!");
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
{
TestModel leftModel({
{ "name", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "title", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Each of the source models must have unique "
"role names!");
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
{
TestModel leftModel({
{ "name", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "title", { "Community 1", "Community 2" }},
{ "title", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Each of the source models must have unique "
"role names!");
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
}
void noJoinRoleTest()
{
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Both left and right models have to contain "
"join role someRole!");
model.setJoinRole("someRole");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Both left and right models have to contain "
"join role title!");
model.setJoinRole("title");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
QTest::ignoreMessage(QtWarningMsg,
"Both left and right models have to contain "
"join role name!");
model.setJoinRole("name");
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
}
void basicAccesTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "color", { "red", "blue" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(0, 0), 3), QString("red"));
QCOMPARE(model.data(model.index(1, 0), 3), QString("blue"));
}
void changesPropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "color", { "red", "green" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
{
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
rightModel.update(0, 0, "Community 1 Updated");
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1 Updated"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
}
{
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
leftModel.update(1, 0, "Token 2 Updated");
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(1, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {0});
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2 Updated"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1 Updated"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
}
}
// TODO: cover also move
void insertRemovePropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "color", { "red", "green" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
QSignalSpy rowsInsertedSpy(&model, &LeftJoinModel::rowsInserted);
QSignalSpy rowsRemovedSpy(&model, &LeftJoinModel::rowsRemoved);
leftModel.insert(1, {"Token 1_1", "community_2"});
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1_1"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 2"));
QCOMPARE(modelResetSpy.count(), 0);
leftModel.remove(1);
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(rowsInsertedSpy.count(), 1);
QCOMPARE(rowsInsertedSpy.first().at(0), QModelIndex{});
QCOMPARE(rowsInsertedSpy.first().at(1), 1);
QCOMPARE(rowsInsertedSpy.first().at(2), 1);
QCOMPARE(rowsRemovedSpy.count(), 1);
QCOMPARE(rowsRemovedSpy.first().at(0), QModelIndex{});
QCOMPARE(rowsRemovedSpy.first().at(1), 1);
QCOMPARE(rowsRemovedSpy.first().at(2), 1);
QCOMPARE(modelResetSpy.count(), 0);
}
void layoutChangePropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "color", { "red", "green" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
// register types to avoid warnings regarding signal params
qRegisterMetaType<QList<QPersistentModelIndex>>();
qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
QSignalSpy layoutAboutToBeChangedSpy(
&model, &LeftJoinModel::layoutAboutToBeChanged);
QSignalSpy layoutChangedSpy(&model, &LeftJoinModel::layoutChanged);
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
PersistentIndexesTester indexesTester(&model);
leftModel.invert();
QCOMPARE(layoutAboutToBeChangedSpy.count(), 1);
QCOMPARE(layoutChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0);
QVERIFY(indexesTester.compare());
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 2"));
rightModel.invert();
QCOMPARE(layoutAboutToBeChangedSpy.count(), 1);
QCOMPARE(layoutChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0);
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 2"));
}
void rightModelJoinRoleChangesPropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
rightModel.update(1, 1, "community_3");
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), {});
}
void rightModelRemovalPropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
rightModel.remove(1);
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), {});
}
void rightModelAdditionPropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_3" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
rightModel.insert(2, {"Community 3", "community_3"});
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_3"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 3"));
}
void leftModelJoinRoleChangesPropagationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
leftModel.update(1, 1, "community_1");
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(1, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(1, 0));
auto changedRoles = dataChangedSpy.first().at(2).value<QVector<int>>();
QVERIFY(changedRoles.contains(1));
QVERIFY(changedRoles.contains(2));
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
}
void modelsDeletedBeforeInitializationTest()
{
auto leftModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(leftModel.get());
model.setRightModel(rightModel.get());
leftModel.reset();
rightModel.reset();
model.setJoinRole("communityId");
QCOMPARE(model.roleNames(), {});
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.data(model.index(0, 0), 0), {});
QCOMPARE(model.data(model.index(0, 0), 2), {});
TestModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
model.setLeftModel(&newLeftModel);
model.setRightModel(&newRightModel);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
QCOMPARE(modelResetSpy.count(), 1);
}
void modelsDeletedAfterInitializationTest()
{
auto leftModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(leftModel.get());
model.setRightModel(rightModel.get());
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 1);
leftModel.reset();
rightModel.reset();
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.data(model.index(0, 0), 0), {});
QCOMPARE(model.data(model.index(0, 0), 2), {});
TestModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
model.setLeftModel(&newLeftModel);
QCOMPARE(modelResetSpy.count(), 2);
QCOMPARE(model.rowCount(), 0);
model.setRightModel(&newRightModel);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
QCOMPARE(modelResetSpy.count(), 3);
}
void rightModelDeletedAfterInitializationTest()
{
auto leftModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestModel>(
QList<QPair<QString, QVariantList>>{
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(leftModel.get());
model.setRightModel(rightModel.get());
model.setJoinRole("communityId");
rightModel.reset();
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), "Token 1");
QCOMPARE(model.data(model.index(0, 0), 1), "community_1");
QCOMPARE(model.data(model.index(0, 0), 2), {});
TestModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
model.setRightModel(&newRightModel);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
}
void rightModelChangedWithSameRolesAfterInitializationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
TestModel newRightModel({
{ "name", { "Community A", "Community B" }},
{ "communityId", { "community_1", "community_2" }}
});
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
model.setRightModel(&newRightModel);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community A"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community B"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community A"));
QCOMPARE(modelResetSpy.count(), 0);
QCOMPARE(dataChangedSpy.count(), 1);
QCOMPARE(dataChangedSpy.first().at(0), model.index(0, 0));
QCOMPARE(dataChangedSpy.first().at(1), model.index(model.rowCount() - 1, 0));
QCOMPARE(dataChangedSpy.first().at(2).value<QVector<int>>(), {2});
}
void rightModelChangedWithDifferentRolesAfterInitializationTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
TestModel newRightModel({
{ "communityId", { "community_1", "community_2" }},
{ "name", { "Community A", "Community B" }}
});
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
QSignalSpy dataChangedSpy(&model, &LeftJoinModel::dataChanged);
model.setRightModel(&newRightModel);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {3, "name"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 3), QString("Community A"));
QCOMPARE(model.data(model.index(1, 0), 3), QString("Community B"));
QCOMPARE(model.data(model.index(2, 0), 3), QString("Community A"));
QCOMPARE(modelResetSpy.count(), 1);
QCOMPARE(dataChangedSpy.count(), 0);
}
void invalidRolesToJoinTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QTest::ignoreMessage(
QtWarningMsg,
"Role to join notExisting not found in the right model!");
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setRolesToJoin({ "name", "notExisting" });
model.setJoinRole("communityId");
QCOMPARE(model.roleNames(), {});
QCOMPARE(model.rowCount(), 0);
}
void rolesToJoinTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setRolesToJoin({ "name" });
model.setJoinRole("communityId");
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"}, {2, "name"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 0), 0), QString("Token 1"));
QCOMPARE(model.data(model.index(1, 0), 0), QString("Token 2"));
QCOMPARE(model.data(model.index(2, 0), 0), QString("Token 3"));
QCOMPARE(model.data(model.index(0, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(1, 0), 1), QString("community_2"));
QCOMPARE(model.data(model.index(2, 0), 1), QString("community_1"));
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 1"));
}
void leftModelChangedToDifferentRolesTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
TestModel leftModel2({
{ "title2", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setRightModel(nullptr);
QCOMPARE(modelResetSpy.count(), 0);
model.setLeftModel(&leftModel2);
QCOMPARE(modelResetSpy.count(), 1);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
model.setRightModel(&rightModel);
QHash<int, QByteArray> newRoles{{0, "title2" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(modelResetSpy.count(), 2);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.roleNames(), newRoles);
}
void noModelResetWhenRolesNotFetchedTest()
{
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
QCOMPARE(modelResetSpy.count(), 0);
}
void deferredLeftModelInitializationTest_data()
{
QTest::addColumn<bool>("fetchRoles");
QTest::newRow("fetch roles") << true;
QTest::newRow("don't fetch roles") << false;
}
void deferredLeftModelInitializationTest()
{
QFETCH(bool, fetchRoles);
TestModel leftModel;
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 0);
if (fetchRoles)
QCOMPARE(model.roleNames(), {});
QCOMPARE(model.rowCount(), 0);
leftModel.reset({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1 : 0);
QCOMPARE(model.rowCount(), 3);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(model.roleNames(), roles);
leftModel.insert(1, {"Token 1_1", "community_2"});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1 : 0);
QCOMPARE(model.rowCount(), 4);
}
void deferredRightModelInitializationTest_data()
{
QTest::addColumn<bool>("fetchRoles");
QTest::newRow("fetch roles") << true;
QTest::newRow("don't fetch roles") << false;
}
void deferredRightModelInitializationTest()
{
QFETCH(bool, fetchRoles);
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel;
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 0);
if (fetchRoles)
QCOMPARE(model.roleNames(), {});
QCOMPARE(model.rowCount(), 0);
rightModel.reset({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1: 0);
QCOMPARE(model.rowCount(), 3);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(model.roleNames(), roles);
leftModel.insert(1, {"Token 1_1", "community_2"});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1: 0);
QCOMPARE(model.rowCount(), 4);
}
void deferredLeftAndRightModelsInitializationTest_data()
{
QTest::addColumn<bool>("fetchRoles");
QTest::newRow("fetch roles") << true;
QTest::newRow("don't fetch roles") << false;
}
void deferredLeftAndRightModelsInitializationTest()
{
QFETCH(bool, fetchRoles);
TestModel leftModel;
TestModel rightModel;
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 0);
if (fetchRoles)
QCOMPARE(model.roleNames(), {});
QCOMPARE(model.rowCount(), 0);
leftModel.reset({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
rightModel.reset({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1 : 0);
QCOMPARE(model.rowCount(), 3);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "name"}, {4, "other"}};
QCOMPARE(model.roleNames(), roles);
leftModel.insert(1, {"Token 1_1", "community_2"});
QCOMPARE(modelResetSpy.count(), fetchRoles ? 1 : 0);
QCOMPARE(model.rowCount(), 4);
}
void leftModelResetWithDifferentRolesTest() {
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 0);
leftModel.reset({
{ "other_1", { "o1_1", "o1_2" }},
{ "other_2", { "o2_1", "o2_2" }},
{ "communityId", { "community_1", "community_2" }}
});
QCOMPARE(modelResetSpy.count(), 1);
QHash<int, QByteArray> roles{{0, "other_1" }, {1, "other_2"},
{2, "communityId"}, {3, "name"}, {5, "other"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 2);
}
void rightModelResetWithDifferentRolesTest() {
TestModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }},
{ "other", { "other_1", "other_1" }}
});
LeftJoinModel model;
QSignalSpy modelResetSpy(&model, &LeftJoinModel::modelReset);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(modelResetSpy.count(), 0);
rightModel.reset({
{ "other_1", { "o1_1", "o1_2" }},
{ "other_2", { "o2_1", "o2_2" }},
{ "communityId", { "community_1", "community_2" }}
});
QCOMPARE(modelResetSpy.count(), 1);
QHash<int, QByteArray> roles{{0, "title" }, {1, "communityId"},
{2, "other_1"}, {3, "other_2"}};
QCOMPARE(model.roleNames(), roles);
QCOMPARE(model.rowCount(), 3);
}
void cacheTest()
{
TestModel leftModel({
{ "id", { "1", "2", "3", "4" }},
{ "communityId", { "c1", "c2", "c3", "c4" }}
});
TestModel rightModel({
{ "name", { "Community 1", "Community 2", "Community 3", "Community 4" }},
{ "communityId", { "c1", "c2", "c3", "c4" }}
});
LeftJoinModel model;
model.setCacheSize(2);
QCOMPARE(model.cacheSize(), 2);
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
// Access item 0 -> cache: [c1]
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
// Access item 1 -> cache: [c2, c1]
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
// Access item 0 again -> cache: [c1, c2]
QCOMPARE(model.data(model.index(0, 0), 2), QString("Community 1"));
// Access item 2 -> cache: [c3, c1], item c2 is evicted
QCOMPARE(model.data(model.index(2, 0), 2), QString("Community 3"));
// Access item 3 -> cache: [c4, c3], item c1 is evicted
QCOMPARE(model.data(model.index(3, 0), 2), QString("Community 4"));
// Now, if we access item 1, it should be a cache miss and it will be fetched.
// This will evict item c3. cache: [c2, c4]
QCOMPARE(model.data(model.index(1, 0), 2), QString("Community 2"));
// Check that cache is cleared when right model is reset
rightModel.reset({
{ "name", { "C1", "C2", "C3", "C4" }},
{ "communityId", { "c1", "c2", "c3", "c4" }}
});
// Accessing item 1 again should give the new value
QCOMPARE(model.data(model.index(1, 0), 2), QString("C2"));
}
void benchmarkDataAccess_data()
{
QTest::addColumn<bool>("useCache");
QTest::newRow("with cache") << true;
QTest::newRow("without cache") << false;
}
void benchmarkDataAccess()
{
QFETCH(bool, useCache);
const int rowCount = 10000;
QVariantList leftIds, leftCommunityIds;
for(int i = 0; i < rowCount; ++i) {
leftIds << QString("Token %1").arg(i);
leftCommunityIds << QString("community_%1").arg(i);
}
TestModel leftModel({
{ "title", leftIds },
{ "communityId", leftCommunityIds }
});
QVariantList rightNames, rightCommunityIds;
for(int i = 0; i < rowCount; ++i) {
rightNames << QString("Community %1").arg(i);
rightCommunityIds << QString("community_%1").arg(i);
}
TestModel rightModel({
{ "name", rightNames },
{ "communityId", rightCommunityIds }
});
LeftJoinModel model;
if (useCache) {
model.setCacheSize(10000);
} else {
// A size of 1 is the minimal QCache size that does something,
// but it's effectively "no real cache" for random access.
// It behaves similarly to the original m_lastUsedRightModelIndex.
model.setCacheSize(1);
}
model.setLeftModel(&leftModel);
model.setRightModel(&rightModel);
model.setJoinRole("communityId");
QCOMPARE(model.rowCount(), rowCount);
// Role for 'name' from the right model
const int nameRole = model.roleNames().key("name");
QBENCHMARK {
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 1000; ++j) { // Access each item 1000 times
int rowIndex = rowCount - j;
model.data(model.index(rowIndex, 0), nameRole);
}
}
}
}
};
QTEST_MAIN(TestLeftJoinModel)
#include "tst_LeftJoinModel.moc"