chore(LeftJoinModel): add detection of duplicated roles
This commit is contained in:
parent
cc964508f1
commit
7847cb3b11
|
@ -22,41 +22,56 @@ void LeftJoinModel::initialize()
|
|||
auto leftRoleNames = m_leftModel->roleNames();
|
||||
auto rightRoleNames = m_rightModel->roleNames();
|
||||
|
||||
if (leftRoleNames.isEmpty() || rightRoleNames.isEmpty()) {
|
||||
qWarning() << "Both left and right models have to contain some roles!";
|
||||
auto leftNames = leftRoleNames.values();
|
||||
auto rightNames = rightRoleNames.values();
|
||||
|
||||
QSet<QByteArray> leftNamesSet(leftNames.cbegin(), leftNames.cend());
|
||||
QSet<QByteArray> rightNamesSet(rightNames.cbegin(), rightNames.cend());
|
||||
|
||||
if (leftNames.size() != leftNamesSet.size()
|
||||
|| rightNames.size() != rightNamesSet.size()) {
|
||||
qWarning() << "Each of the source models must have unique role names!";
|
||||
return;
|
||||
}
|
||||
|
||||
auto leftModelJoinRoleList = leftRoleNames.keys(m_joinRole.toUtf8());
|
||||
auto rightModelJoinRoleList = rightRoleNames.keys(m_joinRole.toUtf8());
|
||||
auto namesIntersection = leftNamesSet.intersect(rightNamesSet);
|
||||
auto hasCommonJoinRole = namesIntersection.remove(m_joinRole.toUtf8());
|
||||
|
||||
if (leftModelJoinRoleList.size() != 1
|
||||
|| rightModelJoinRoleList.size() != 1) {
|
||||
if (!hasCommonJoinRole) {
|
||||
qWarning().noquote() << QString("Both left and right models have to "
|
||||
"contain join role %1!").arg(m_joinRole);
|
||||
return;
|
||||
}
|
||||
|
||||
m_leftModelJoinRole = leftModelJoinRoleList.at(0);
|
||||
m_rightModelJoinRole = rightModelJoinRoleList.at(0);
|
||||
if (!namesIntersection.isEmpty()) {
|
||||
qWarning().nospace() << "Source models contain conflicting model names: "
|
||||
<< QList(namesIntersection.cbegin(),
|
||||
namesIntersection.cend())
|
||||
<< "!";
|
||||
return;
|
||||
}
|
||||
|
||||
auto leftRoles = leftRoleNames.keys();
|
||||
auto maxLeftRole = std::max_element(leftRoles.cbegin(), leftRoles.cend());
|
||||
auto rightRolesOffset = *maxLeftRole + 1;
|
||||
auto roleNames = leftRoleNames;
|
||||
QVector<int> joinedRoles;
|
||||
|
||||
auto i = rightRoleNames.constBegin();
|
||||
while (i != rightRoleNames.constEnd()) {
|
||||
if (i.value() != m_joinRole) {
|
||||
auto roleWithOffset = i.key() + rightRolesOffset;
|
||||
roleNames.insert(roleWithOffset, i.value());
|
||||
m_joinedRoles.append(roleWithOffset);
|
||||
joinedRoles.append(roleWithOffset);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
m_roleNames = std::move(roleNames);
|
||||
m_joinedRoles = std::move(joinedRoles);
|
||||
m_leftModelJoinRole = leftRoleNames.key(m_joinRole.toUtf8());
|
||||
m_rightModelJoinRole = rightRoleNames.key(m_joinRole.toUtf8());
|
||||
m_rightModelRolesOffset = rightRolesOffset;
|
||||
m_roleNames = roleNames;
|
||||
|
||||
connect(m_rightModel, &QAbstractItemModel::dataChanged, this,
|
||||
[this](auto& topLeft, auto& bottomRight, auto& roles) {
|
||||
|
|
|
@ -11,7 +11,6 @@ namespace {
|
|||
class TestSourceModel : public QAbstractListModel {
|
||||
|
||||
public:
|
||||
|
||||
explicit TestSourceModel(QList<QPair<QString, QVariantList>> data)
|
||||
: m_data(std::move(data))
|
||||
{
|
||||
|
@ -86,7 +85,7 @@ private:
|
|||
QHash<int, QByteArray> m_roles;
|
||||
};
|
||||
|
||||
}
|
||||
} // anonymous namespace
|
||||
|
||||
class TestLeftJoinModel: public QObject
|
||||
{
|
||||
|
@ -102,6 +101,25 @@ private slots:
|
|||
QCOMPARE(model.roleNames(), {});
|
||||
}
|
||||
|
||||
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 initializationTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
|
@ -135,23 +153,145 @@ private slots:
|
|||
QCOMPARE(model.roleNames(), roles);
|
||||
}
|
||||
|
||||
void setSourceModelDirectlyTest()
|
||||
void collidingRolesTest()
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "title", { "Token 1", "Token 2" }},
|
||||
{ "name", { "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);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Source model is not intended to be set directly "
|
||||
"on this model. Use setLeftModel and setRightModel instead!");
|
||||
model.setSourceModel(&leftModel);
|
||||
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()
|
||||
{
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "name", { "Token 1", "Token 2" }},
|
||||
{ "name", { "Token 1", "Token 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
TestSourceModel 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(), {});
|
||||
}
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "name", { "Token 1", "Token 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
TestSourceModel 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(), {});
|
||||
}
|
||||
{
|
||||
TestSourceModel leftModel({
|
||||
{ "name", { "Token 1", "Token 2" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
TestSourceModel 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()
|
||||
|
@ -266,6 +406,7 @@ private slots:
|
|||
|
||||
TestSourceModel rightModel({
|
||||
{ "name", { "Community 1", "Community 2" }},
|
||||
{ "color", { "red", "blue" }},
|
||||
{ "communityId", { "community_1", "community_2" }}
|
||||
});
|
||||
|
||||
|
@ -283,6 +424,8 @@ private slots:
|
|||
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()
|
||||
|
|
Loading…
Reference in New Issue