status-desktop/ui/StatusQ/tests/tst_LeftJoinModel.cpp

656 lines
22 KiB
C++
Raw Normal View History

#include <QAbstractItemModelTester>
#include <QSignalSpy>
#include <QTest>
#include <memory>
#include <StatusQ/leftjoinmodel.h>
namespace {
class TestSourceModel : public QAbstractListModel {
public:
explicit TestSourceModel(QList<QPair<QString, QVariantList>> data)
: m_data(std::move(data))
{
m_roles.reserve(m_data.size());
for (auto i = 0; i < m_data.size(); i++)
m_roles.insert(i, m_data.at(i).first.toUtf8());
}
int rowCount(const QModelIndex& parent) const override
{
assert(m_data.size());
return m_data.first().second.size();
}
QVariant data(const QModelIndex& index, int role) const override
{
if (!index.isValid() || role < 0 || role >= m_data.size())
return {};
const auto row = index.row();
if (role >= m_data.length() || row >= m_data.at(0).second.length())
return {};
return m_data.at(role).second.at(row);
}
void insert(int index, QVariantList row)
{
beginInsertRows(QModelIndex{}, index, index);
assert(row.size() == m_data.size());
for (int i = 0; i < m_data.size(); i++) {
auto& roleVariantList = m_data[i].second;
assert(index <= roleVariantList.size());
roleVariantList.insert(index, row.at(i));
}
endInsertRows();
}
void update(int index, int role, QVariant value)
{
assert(role < m_data.size() && index < m_data[role].second.size());
m_data[role].second[index].setValue(std::move(value));
emit dataChanged(this->index(index, 0), this->index(index, 0), { role });
}
void remove(int index)
{
beginRemoveRows(QModelIndex{}, index, index);
for (int i = 0; i < m_data.size(); i++) {
auto& roleVariantList = m_data[i].second;
assert(index < roleVariantList.size());
roleVariantList.removeAt(index);
}
endRemoveRows();
}
QHash<int, QByteArray> roleNames() const override
{
return m_roles;
}
private:
QList<QPair<QString, QVariantList>> m_data;
QHash<int, QByteArray> m_roles;
};
}
class TestLeftJoinModel: public QObject
{
Q_OBJECT
private slots:
void emptyModelTest() {
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
void initializationTest()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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 setSourceModelDirectlyTest()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
LeftJoinModel model;
QAbstractItemModelTester tester(&model);
QTest::ignoreMessage(QtWarningMsg,
"Source model is not intended to be set directly "
"on this model. Use setLeftModel and setRightModel instead!");
model.setSourceModel(&leftModel);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.roleNames(), {});
}
void noJoinRoleTest()
{
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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(), {});
}
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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(), {});
}
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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");
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"));
}
void changesPropagationTest()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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"));
}
}
void rightModelJoinRoleChangesPropagationTest()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2" }},
{ "communityId", { "community_1", "community_2" }}
});
TestSourceModel 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()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_3" }}
});
TestSourceModel 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()
{
TestSourceModel leftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestSourceModel 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(), 2);
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>>(), {2});
QCOMPARE(dataChangedSpy.at(1).at(0), model.index(1, 0));
QCOMPARE(dataChangedSpy.at(1).at(1), model.index(1, 0));
QCOMPARE(dataChangedSpy.at(1).at(2).value<QVector<int>>(), {1});
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<TestSourceModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestSourceModel>(
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());
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), {});
TestSourceModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestSourceModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
QTest::ignoreMessage(QtWarningMsg,
"Changing left model is not supported!");
model.setLeftModel(&newLeftModel);
QTest::ignoreMessage(QtWarningMsg,
"Changing right model is not supported!");
model.setRightModel(&newRightModel);
}
void modelsDeletedAfterInitializationTest()
{
auto leftModel = std::make_unique<TestSourceModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestSourceModel>(
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");
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), {});
TestSourceModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestSourceModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
QTest::ignoreMessage(QtWarningMsg,
"Changing left model is not supported!");
model.setLeftModel(&newLeftModel);
QTest::ignoreMessage(QtWarningMsg,
"Changing right model is not supported!");
model.setRightModel(&newRightModel);
}
void rightModelDeletedAfterInitializationTest()
{
auto leftModel = std::make_unique<TestSourceModel>(
QList<QPair<QString, QVariantList>>{
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
auto rightModel = std::make_unique<TestSourceModel>(
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), {});
TestSourceModel newLeftModel({
{ "title", { "Token 1", "Token 2", "Token 3"}},
{ "communityId", { "community_1", "community_2", "community_1" }}
});
TestSourceModel newRightModel({
{ "name", { "Community 1", "Community 2" }},
{ "communityId", { "community_1", "community_2" }}
});
QTest::ignoreMessage(QtWarningMsg,
"Changing left model is not supported!");
model.setLeftModel(&newLeftModel);
QTest::ignoreMessage(QtWarningMsg,
"Changing right model is not supported!");
model.setRightModel(&newRightModel);
}
};
QTEST_MAIN(TestLeftJoinModel)
#include "tst_LeftJoinModel.moc"