summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/Chattables.cpp12
-rw-r--r--Swift/Controllers/Chat/Chattables.h6
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChattablesTest.cpp137
-rw-r--r--Swift/Controllers/SConscript1
-rw-r--r--Swift/QtUI/ChattablesModel.cpp19
-rw-r--r--Swift/QtUI/ChattablesModel.h6
6 files changed, 171 insertions, 10 deletions
diff --git a/Swift/Controllers/Chat/Chattables.cpp b/Swift/Controllers/Chat/Chattables.cpp
index 599ff48..707046f 100644
--- a/Swift/Controllers/Chat/Chattables.cpp
+++ b/Swift/Controllers/Chat/Chattables.cpp
@@ -24,14 +24,20 @@ void Chattables::addJID(const JID& jid, State::Type type) {
State state;
state.type = type;
state.jid = jid;
+ onBeginAdd(static_cast<int>(list_.size()));
list_.push_back(jid);
states_[jid] = state;
- onAdded(jid);
+ onAdded();
}
void Chattables::setState(const JID& jid, State state) {
- states_[jid] = state;
- onChanged(jid);
+ auto stateIter = states_.find(jid);
+ if (stateIter == states_.end()) {
+ return;
+ }
+ stateIter->second = state;
+ auto listPos = static_cast<int>(std::distance(list_.begin(), std::find(list_.begin(), list_.end(), jid)));
+ onChanged(jid, listPos);
}
}
diff --git a/Swift/Controllers/Chat/Chattables.h b/Swift/Controllers/Chat/Chattables.h
index c5c7b85..c115fb3 100644
--- a/Swift/Controllers/Chat/Chattables.h
+++ b/Swift/Controllers/Chat/Chattables.h
@@ -34,9 +34,9 @@ class Chattables {
void addJID(const JID& jid, State::Type type);
void setState(const JID& jid, State state);
- boost::signals2::signal<void (const JID&)> onAdded;
- boost::signals2::signal<void (const JID&)> onRemoved;
- boost::signals2::signal<void (const JID&)> onChanged;
+ boost::signals2::signal<void (int)> onBeginAdd;
+ boost::signals2::signal<void ()> onAdded;
+ boost::signals2::signal<void (const JID&, int)> onChanged;
/// The UI has activated a chattable item (e.g. clicked in the roster)
boost::signals2::signal<void (const JID&)> onActivated;
private:
diff --git a/Swift/Controllers/Chat/UnitTest/ChattablesTest.cpp b/Swift/Controllers/Chat/UnitTest/ChattablesTest.cpp
new file mode 100644
index 0000000..6339ad9
--- /dev/null
+++ b/Swift/Controllers/Chat/UnitTest/ChattablesTest.cpp
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <gtest/gtest.h>
+#include <hippomocks.h>
+
+#include <Swift/Controllers/Chat/Chattables.h>
+
+using namespace Swift;
+
+class ChattablesTest : public ::testing::Test {
+ protected:
+ void SetUp() {
+ beginListSize_ = 0;
+ endListSize_ = 0;
+ callsToBegin_ = 0;
+ callsToEnd_ = 0;
+ }
+
+ void TearDown() {
+ }
+
+ void updateBeginListSize(int listSize);
+ void updateEndListSize();
+
+ Chattables chattables_;
+ int beginListSize_;
+ int endListSize_;
+ int callsToBegin_;
+ int callsToEnd_;
+};
+
+void ChattablesTest::updateBeginListSize(int listSize) {
+ beginListSize_ = listSize;
+ callsToBegin_++;
+}
+
+void ChattablesTest::updateEndListSize() {
+ endListSize_ = chattables_.get().size();
+ callsToEnd_++;
+}
+
+TEST_F(ChattablesTest, testAddJID) {
+ chattables_.onBeginAdd.connect([this](int listSize){ updateBeginListSize(listSize); });
+ chattables_.onAdded.connect([this](){ updateEndListSize(); });
+ JID jid("user@swift.jid");
+
+ chattables_.addJID(jid, Chattables::State::Type::Person);
+ ASSERT_EQ(0, beginListSize_);
+ ASSERT_EQ(1, endListSize_);
+ ASSERT_EQ(1, callsToBegin_);
+ ASSERT_EQ(1, callsToEnd_);
+
+ ASSERT_EQ(jid, chattables_.get()[0]);
+ Chattables::State state = chattables_.getState(jid);
+ ASSERT_EQ(jid, state.jid);
+ ASSERT_EQ(Chattables::State::Type::Person, state.type);
+}
+
+TEST_F(ChattablesTest, testAddMultipleJIDs) {
+ chattables_.onBeginAdd.connect([this](int listSize){ updateBeginListSize(listSize); });
+ chattables_.onAdded.connect([this](){ updateEndListSize(); });
+ JID jid0("user0@swift.jid");
+ JID jid1("user1@swift.jid");
+ JID jid2("user2@swift.jid");
+
+ chattables_.addJID(jid0, Chattables::State::Type::Person);
+ ASSERT_EQ(0, beginListSize_);
+ ASSERT_EQ(1, endListSize_);
+ ASSERT_EQ(1, callsToBegin_);
+ ASSERT_EQ(1, callsToEnd_);
+ chattables_.addJID(jid1, Chattables::State::Type::Person);
+ ASSERT_EQ(1, beginListSize_);
+ ASSERT_EQ(2, endListSize_);
+ ASSERT_EQ(2, callsToBegin_);
+ ASSERT_EQ(2, callsToEnd_);
+ chattables_.addJID(jid2, Chattables::State::Type::Person);
+ ASSERT_EQ(2, beginListSize_);
+ ASSERT_EQ(3, endListSize_);
+ ASSERT_EQ(3, callsToBegin_);
+ ASSERT_EQ(3, callsToEnd_);
+}
+
+TEST_F(ChattablesTest, testAddRoomJID) {
+ chattables_.onBeginAdd.connect([this](int listSize){ updateBeginListSize(listSize); });
+ chattables_.onAdded.connect([this](){ updateEndListSize(); });
+ JID jid("room@swift.jid");
+
+ chattables_.addJID(jid, Chattables::State::Type::Room);
+ ASSERT_EQ(0, beginListSize_);
+ ASSERT_EQ(1, endListSize_);
+ ASSERT_EQ(1, callsToBegin_);
+ ASSERT_EQ(1, callsToEnd_);
+
+ ASSERT_EQ(jid, chattables_.get()[0]);
+ Chattables::State state = chattables_.getState(jid);
+ ASSERT_EQ(jid, state.jid);
+ ASSERT_EQ(Chattables::State::Type::Room, state.type);
+}
+
+TEST_F(ChattablesTest, testSetState) {
+ JID jid("user@swift.jid");
+ chattables_.addJID(jid, Chattables::State::Type::Person);
+ ASSERT_EQ(1, chattables_.get().size());
+ ASSERT_EQ(jid, chattables_.get()[0]);
+ ASSERT_EQ(Chattables::State::Type::Person, chattables_.getState(jid).type);
+ ASSERT_EQ(StatusShow::None, chattables_.getState(jid).status);
+
+ JID returnedJID;
+ int returnedIndex;
+ int callsToChanged = 0;
+ chattables_.onChanged.connect([this, &returnedJID, &returnedIndex, &callsToChanged](const JID& jid, int index){
+ returnedJID = jid;
+ returnedIndex = index;
+ callsToChanged++;
+ });
+
+ Chattables::State newState;
+ newState.jid = jid;
+ newState.type = Chattables::State::Type::Room;
+ newState.status = StatusShow::Online;
+ chattables_.setState(jid, newState);
+
+ auto storedState = chattables_.getState(jid);
+
+ ASSERT_EQ(1, chattables_.get().size());
+ ASSERT_EQ(jid, chattables_.get()[0]);
+ ASSERT_EQ(jid, returnedJID);
+ ASSERT_EQ(0, returnedIndex);
+ ASSERT_EQ(1, callsToChanged);
+ ASSERT_EQ(jid, storedState.jid);
+ ASSERT_EQ(Chattables::State::Type::Room, storedState.type);
+ ASSERT_EQ(StatusShow::Online, storedState.status);
+}
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 25d326a..3840fbf 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -100,6 +100,7 @@ if env["SCONS_STAGE"] == "build" :
File("Chat/UnitTest/ChatMessageParserTest.cpp"),
File("Chat/UnitTest/ChatsManagerTest.cpp"),
File("Chat/UnitTest/ChatControllerTest.cpp"),
+ File("Chat/UnitTest/ChattablesTest.cpp"),
File("Chat/UnitTest/MUCControllerTest.cpp"),
File("Roster/UnitTest/LeastCommonSubsequenceTest.cpp"),
File("Roster/UnitTest/RosterControllerTest.cpp"),
diff --git a/Swift/QtUI/ChattablesModel.cpp b/Swift/QtUI/ChattablesModel.cpp
index d1257b9..67d0579 100644
--- a/Swift/QtUI/ChattablesModel.cpp
+++ b/Swift/QtUI/ChattablesModel.cpp
@@ -15,10 +15,21 @@
namespace Swift {
ChattablesModel::ChattablesModel(Chattables& chattables, QObject* parent) : QAbstractListModel(parent), chattables_(chattables) {
- //FIXME: scoped connections, do it properly not reset.
- chattables_.onAdded.connect([this](const JID& /*jid*/) {beginResetModel(); endResetModel();});
- chattables_.onRemoved.connect([this](const JID& /*jid*/) {beginResetModel(); endResetModel();});
- chattables_.onChanged.connect([this](const JID& /*jid*/) {beginResetModel(); endResetModel();});
+ using scoped_connection = boost::signals2::scoped_connection;
+ connectionList_.emplace_back(std::make_unique<scoped_connection>(
+ chattables_.onBeginAdd.connect([this](int index) {beginInsertRows(QModelIndex(), index, index);})
+ ));
+ connectionList_.emplace_back(std::make_unique<scoped_connection>(
+ chattables_.onAdded.connect([this]() {endInsertRows();})
+ ));
+ connectionList_.emplace_back(std::make_unique<scoped_connection>(
+ chattables_.onChanged.connect(
+ [this](const JID& jid, int index) {
+ auto modelIndex = createIndex(index, 0, const_cast<JID*>(&jid));
+ dataChanged(modelIndex, modelIndex, {});
+ }
+ )
+ ));
}
int ChattablesModel::rowCount(const QModelIndex& /*parent*/) const {
diff --git a/Swift/QtUI/ChattablesModel.h b/Swift/QtUI/ChattablesModel.h
index 57073aa..6617d97 100644
--- a/Swift/QtUI/ChattablesModel.h
+++ b/Swift/QtUI/ChattablesModel.h
@@ -6,6 +6,11 @@
#pragma once
+#include <memory>
+#include <vector>
+
+#include <boost/signals2/connection.hpp>
+
#include <QAbstractListModel>
namespace Swift {
@@ -23,6 +28,7 @@ class ChattablesModel : public QAbstractListModel {
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
private:
Chattables& chattables_;
+ std::vector<std::unique_ptr<boost::signals2::scoped_connection>> connectionList_;
};
}