diff options
author | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-07-07 16:49:10 (GMT) |
---|---|---|
committer | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-07-07 16:49:10 (GMT) |
commit | 2bad2edf797c9fefb1facd2a63c69cce34a0e635 (patch) | |
tree | c71218951d0017d67284531a114a55c3c89d2b90 | |
parent | 0071e9ed46775ee4e49ed969099ce08c49c9a07b (diff) | |
download | swift-contrib-2bad2edf797c9fefb1facd2a63c69cce34a0e635.zip swift-contrib-2bad2edf797c9fefb1facd2a63c69cce34a0e635.tar.bz2 |
Added WhiteboardClient with passing simple unit test
-rw-r--r-- | Swiften/SConscript | 2 | ||||
-rw-r--r-- | Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp | 101 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardClient.cpp | 91 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardClient.h | 31 |
4 files changed, 225 insertions, 0 deletions
diff --git a/Swiften/SConscript b/Swiften/SConscript index 120186f..9c9d246 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -207,6 +207,7 @@ if env["SCONS_STAGE"] == "build" : "Whiteboard/OutgoingWhiteboardSession.cpp", "Whiteboard/WhiteboardSessionManager.cpp", "Whiteboard/WhiteboardServer.cpp", + "Whiteboard/WhiteboardClient.cpp", "Whiteboard/Elements/Color.cpp", "Whiteboard/WhiteboardTransformer.cpp", ] @@ -405,6 +406,7 @@ if env["SCONS_STAGE"] == "build" : File("TLS/UnitTest/CertificateTest.cpp"), File("VCards/UnitTest/VCardManagerTest.cpp"), File("Whiteboard/UnitTest/WhiteboardServerTest.cpp"), + File("Whiteboard/UnitTest/WhiteboardClientTest.cpp"), ]) # Generate the Swiften header diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp new file mode 100644 index 0000000..f6f8249 --- /dev/null +++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2012 Mateusz Piękos + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include <boost/smart_ptr/make_shared.hpp> +#include <Swiften/Whiteboard/WhiteboardClient.h> +#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h> +#include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h> + +using namespace Swift; + +class WhiteboardClientTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(WhiteboardClientTest); + CPPUNIT_TEST(testNoninterrupedSynchronization); + CPPUNIT_TEST_SUITE_END(); +public: + void testNoninterrupedSynchronization() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", ""); + serverOp->setPos(0); + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0"); + clientOp->setPos(1); + clientOp->setOrigin(WhiteboardOperation::Local); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(client.handleLocalOperationReceived(clientOp)); + CPPUNIT_ASSERT_EQUAL(clientOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(result)); + CPPUNIT_ASSERT_EQUAL(aElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement())); + + + clientOp = createInsertOperation("b", "a"); + clientOp->setPos(2); + clientOp->setOrigin(WhiteboardOperation::Local); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + serverOp = createInsertOperation("c", "0"); + serverOp->setPos(1); + serverOp->setOrigin(WhiteboardOperation::Other); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverOp); + result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first); + CPPUNIT_ASSERT_EQUAL(3, result->getPos()); + CPPUNIT_ASSERT_EQUAL(cElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement())); + CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getParentID()); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + serverOp = createInsertOperation("d", "c"); + serverOp->setPos(2); + serverOp->setOrigin(WhiteboardOperation::Other); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverOp); + result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first); + CPPUNIT_ASSERT_EQUAL(4, result->getPos()); + CPPUNIT_ASSERT_EQUAL(dElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement())); + CPPUNIT_ASSERT_EQUAL(std::string("c"), result->getParentID()); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + serverOp = createInsertOperation("a", "d"); + serverOp->setPos(1); + serverOp->setOrigin(WhiteboardOperation::Other); + pairResult = client.handleServerOperationReceived(serverOp); + result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.second); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + CPPUNIT_ASSERT_EQUAL(std::string("b"), result->getID()); + CPPUNIT_ASSERT_EQUAL(bElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(result->getElement())); + CPPUNIT_ASSERT_EQUAL(std::string("a"), result->getParentID()); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin()); + + serverOp = createInsertOperation("b", "a"); + serverOp->setPos(2); + serverOp->setOrigin(WhiteboardOperation::Other); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + } + + WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent) { + WhiteboardInsertOperation::ref operation = boost::make_shared<WhiteboardInsertOperation>(); + operation->setParentID(parent); + operation->setID(id); + return operation; + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(WhiteboardClientTest); diff --git a/Swiften/Whiteboard/WhiteboardClient.cpp b/Swiften/Whiteboard/WhiteboardClient.cpp new file mode 100644 index 0000000..6b352f5 --- /dev/null +++ b/Swiften/Whiteboard/WhiteboardClient.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2012 Mateusz Piękos + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <Swiften/Whiteboard/WhiteboardClient.h> +#include <Swiften/Whiteboard/WhiteboardTransformer.h> + +namespace Swift { + WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) { + localOperations_.push_back(operation); + if (lastSentOperationID_.empty()) + { + lastSentOperationID_ = operation->getID(); + return operation; + } + return WhiteboardOperation::ref(); + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardClient::handleServerOperationReceived(WhiteboardOperation::ref operation) { + serverOperations_.push_back(operation); + WhiteboardOperation::ref clientOp; + WhiteboardOperation::ref serverOp; + if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) { + localOperations_.push_back(operation); + clientOp = operation; + } else if (lastSentOperationID_ == operation->getID()) { + std::list<WhiteboardOperation::ref>::iterator it; + for (it = bridge_.begin(); it != bridge_.end(); ++it) { + if ((*it)->getParentID() == lastSentOperationID_) { + lastSentOperationID_ = (*it)->getID(); + serverOperations_.push_back(*it); + serverOp = *it; + serverOp->setOrigin(WhiteboardOperation::Other); + break; + } + } + } else { + if (bridge_.size() > 0 && bridge_.front()->getParentID() == operation->getParentID()) { + std::list<WhiteboardOperation::ref>::iterator it = bridge_.begin(); + std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair; + WhiteboardInsertOperation::ref temp; + opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*it), boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation)); + temp = opPair.first; + + *it = opPair.second; + std::string previousID = (*it)->getID(); + ++it; + for (; it != bridge_.end(); ++it) { + opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*it), temp); + temp = opPair.first; + *it = opPair.second; + (*it)->setParentID(previousID); + previousID = (*it)->getID(); + } + temp->setParentID(localOperations_.back()->getID()); + localOperations_.push_back(temp); + clientOp = temp; + } else { + std::list<WhiteboardOperation::ref>::reverse_iterator it; + std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair; + WhiteboardInsertOperation::ref temp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); + bool end = false; + for (it = localOperations_.rbegin(); it != localOperations_.rend(); ++it) { + while ((*it)->getParentID() == temp->getParentID()) { + opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*it), temp); + if (bridge_.size() > 0) { + opPair.second->setParentID(bridge_.back()->getID()); + } + temp = opPair.first; + bridge_.push_back(opPair.second); + if (it == localOperations_.rbegin()) { + localOperations_.push_back(temp); + clientOp = temp; + end = true; + break; + } else { + --it; + } + } + if (end) { + break; + } + } + } + } + + return std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref>(clientOp, serverOp); + } +} diff --git a/Swiften/Whiteboard/WhiteboardClient.h b/Swiften/Whiteboard/WhiteboardClient.h new file mode 100644 index 0000000..f781e6f --- /dev/null +++ b/Swiften/Whiteboard/WhiteboardClient.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2012 Mateusz Piękos + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <Swiften/Whiteboard/Operations/WhiteboardOperation.h> +#include <list> +#include <utility> + +namespace Swift { + class WhiteboardClient { + public: + /*! + * @return Operation to send + */ + WhiteboardOperation::ref handleLocalOperationReceived(WhiteboardOperation::ref operation); + /*! + * @return pair.first-element to handle locally, pair.second-element to send to server + */ + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> handleServerOperationReceived(WhiteboardOperation::ref operation); + + private: + std::list<WhiteboardOperation::ref> localOperations_; + std::list<WhiteboardOperation::ref> serverOperations_; + std::list<WhiteboardOperation::ref> bridge_; + std::string lastSentOperationID_; + }; +} |