diff options
-rw-r--r-- | Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp | 179 |
1 files changed, 176 insertions, 3 deletions
diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp index 3f90586..e30bd4e 100644 --- a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp +++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp @@ -38,6 +38,9 @@ public: CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send WhiteboardInsertOperation::ref clientOp; clientOp = createInsertOperation("a", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); @@ -46,6 +49,9 @@ public: WhiteboardInsertOperation::ref result; checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + //Client receives server operation parented off "0", which isn't last client operation + //so it have to be transformed against local operations and then transformed value can + //be returned to draw serverOp = createInsertOperation("b", "0", 1); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -54,24 +60,51 @@ public: checkOperation(pairResult.first, "b", "a", 2, bElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives confirmation from the server about processed "a" operation, it had to + //be transformed against "b" on the server side to receive operation parented off "b". + //There aren't any waiting operations to send to server, this operation should return + //nothing serverOp = createInsertOperation("a", "b", 1); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives local operation, it doesn't have to be transformed against anything + //but operation returned to send to the server should be parented off last server + //operation, which is "b" clientOp = createInsertOperation("c", "b", 3); clientOp->setOrigin(WhiteboardOperation::Local); WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); clientOp->setElement(cElement); checkOperation(client.handleLocalOperationReceived(clientOp), "c", "a", 3, cElement); - clientOp = createInsertOperation("c", "a", 1); + //Client receives confirmation from the server about processed "a" operation, it + //should be the same operation as it was sent because server didn't have to + //transform it + clientOp = createInsertOperation("c", "a", 3); clientOp->setOrigin(WhiteboardOperation::Local); clientOp->setElement(cElement); pairResult = client.handleServerOperationReceived(clientOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + //Results: + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + // + //Server operations: + //ID pos + //0 0 + //b 1 + //a 1 + //c 3 + // + //what gives 0abc on both sides } /*! @@ -87,18 +120,26 @@ public: CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send WhiteboardInsertOperation::ref clientOp = createInsertOperation("c", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); clientOp->setElement(cElement); checkOperation(client.handleLocalOperationReceived(clientOp), "c", "0", 1, cElement); + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. clientOp = createInsertOperation("d", "c", 2); clientOp->setOrigin(WhiteboardOperation::Local); WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); clientOp->setElement(dElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + //Client receives confirmation about processing "c" operation, it should be the + //same as sent operation because it wasn't transformed, client could send now + //operation "d" clientOp = createInsertOperation("c", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); clientOp->setElement(cElement); @@ -106,20 +147,40 @@ public: checkOperation(pairResult.second, "d", "c", 2, dElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); - clientOp = createInsertOperation("d", "c", 3); + //Client receives confirmation about processing "d", it should be the same as + //sent operation. There aren't any operations in queue to send. + clientOp = createInsertOperation("d", "c", 2); clientOp->setOrigin(WhiteboardOperation::Local); clientOp->setElement(dElement); pairResult = client.handleServerOperationReceived(clientOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); - serverOp = createInsertOperation("e", "d", 4); + //Client receives new operation from server, it's parented off "d" which is at + //the end of local history so it doesn't have to be transformed, so operation + //to pass to window should be the same + serverOp = createInsertOperation("e", "d", 3); WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); serverOp->setElement(eElement); pairResult = client.handleServerOperationReceived(serverOp); WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first); CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + + //Client operations: + //ID pos + //0 0 + //c 1 + //d 2 + //e 3 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //e 3 } /*! @@ -136,6 +197,9 @@ public: CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send WhiteboardInsertOperation::ref clientOp; clientOp = createInsertOperation("a", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); @@ -143,12 +207,17 @@ public: clientOp->setElement(aElement); checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. clientOp = createInsertOperation("b", "a", 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)); + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server serverOp = createInsertOperation("c", "0", 1); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -157,6 +226,10 @@ public: checkOperation(pairResult.first, "c", "b", 3, cElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives new operation from server, it should be transformed against + //results of previous transformations, returned operation should be parented off + //"c" existing in local history. + //Because client is waiting for ack of "a", there is no operation to send to server serverOp = createInsertOperation("d", "c", 2); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -165,17 +238,40 @@ public: checkOperation(pairResult.first, "d", "c", 4, dElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives confirmation about processing "a", it should send next operation + //to server which is "b", but it should be version parented of transformed "a" serverOp = createInsertOperation("a", "d", 1); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); checkOperation(pairResult.second, "b", "a", 2, bElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + + //Client receives confirmation about processing "b", there aren't any operations + //waiting so it should return nothing. serverOp = createInsertOperation("b", "a", 2); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + // + //what gives 0abcd on both sides. } /*! @@ -193,6 +289,9 @@ public: CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send WhiteboardInsertOperation::ref clientOp; clientOp = createInsertOperation("a", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); @@ -200,12 +299,17 @@ public: clientOp->setElement(aElement); checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. clientOp = createInsertOperation("b", "a", 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)); + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server serverOp = createInsertOperation("c", "0", 1); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -214,12 +318,17 @@ public: checkOperation(pairResult.first, "c", "b", 3, cElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives new local operation, client is still waiting for ack so, it + //should return nothing clientOp = createInsertOperation("e", "a", 4); clientOp->setOrigin(WhiteboardOperation::Local); WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); clientOp->setElement(eElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + //Client receives new server operation, to add it to local history it should be transformed + //against result of previous transformations and operation "e", returned operation should + //be parented off "e", which was last local operation serverOp = createInsertOperation("d", "c", 2); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -228,6 +337,9 @@ public: checkOperation(pairResult.first, "d", "e", 5, dElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives confirmation about processing "a", it had to be transformed against + //"c" and "d" and it is now parented off "d", returned value should be next operation + //which have to be send to server("b" parented off server version of "a"). serverOp = createInsertOperation("a", "d", 1); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); @@ -235,6 +347,9 @@ public: // CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin()); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + //Client receives confirmation about processing "b", it is the same operation as sent because + //it didn't have to be transformed, returned value should be next operation + //which have to be send to server("e" parented off server version of "b"). serverOp = createInsertOperation("b", "a", 2); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); @@ -242,11 +357,33 @@ public: // CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin()); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + //Client receives confirmation about processing "b", it is the same operation as sent because + //it didn't have to be transformed, there aren't any operations to send so this function returns + //nothing serverOp = createInsertOperation("e", "b", 4); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + //Result: + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //e 4 + //d 5 + // + //Server operations: + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + //e 4 + //what gives 0abced on both sides } /*! @@ -263,6 +400,9 @@ public: CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.first)); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send WhiteboardInsertOperation::ref clientOp; clientOp = createInsertOperation("a", "0", 1); clientOp->setOrigin(WhiteboardOperation::Local); @@ -270,12 +410,17 @@ public: clientOp->setElement(aElement); checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. clientOp = createInsertOperation("b", "a", 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)); + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server serverOp = createInsertOperation("c", "0", 1); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -284,6 +429,9 @@ public: checkOperation(pairResult.first, "c", "b", 3, cElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives confirmation about processing "a", it had to be transformed against + //"c" and it is now parented off "c", returned value should be next operation + //which have to be send to server("b" parented off server version of "a"). serverOp = createInsertOperation("a", "c", 1); serverOp->setOrigin(WhiteboardOperation::Other); serverOp->setElement(aElement); @@ -292,6 +440,9 @@ public: // CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::Other, result->getOrigin()); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); + //Client receives new server operation, to add it to local history it should be transformed + //against result of previous transformation(but only with transformation of "b"), returned + //operation should be parented off "c", which was last local operation serverOp = createInsertOperation("d", "a", 3); serverOp->setOrigin(WhiteboardOperation::Other); WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); @@ -300,12 +451,34 @@ public: checkOperation(pairResult.first, "d", "c", 4, dElement); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + //Client receives confirmation about processing "b", it had to be transformed against + //"d" because both operations was parented off server version of "a". + //there aren't any operations to send so this function returns nothing. serverOp = createInsertOperation("b", "d", 2); serverOp->setElement(bElement); serverOp->setOrigin(WhiteboardOperation::Other); pairResult = client.handleServerOperationReceived(serverOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.first); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.second); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //a 1 + //d 3 + //b 2 + // + //what gives 0abcd on both sides + } WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent, int pos) { |