libreoffice-online/test/UnitCursor.cpp
Miklos Vajna fe04d685db Convert cursor tests to a new-style one
So that they are in-process, which means it's easier to debug when they
fail.

Change-Id: I0fb1e798875c479e0aeb5f709ef630def5349126
2019-12-02 09:11:39 +01:00

410 lines
15 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <memory>
#include <ostream>
#include <set>
#include <string>
#include <Poco/Exception.h>
#include <Poco/RegularExpression.h>
#include <Poco/URI.h>
#include <cppunit/TestAssert.h>
#include <Unit.hpp>
#include <helpers.hpp>
class LOOLWebSocket;
namespace
{
void getCursor(const std::string& message, int& cursorX, int& cursorY, int& cursorWidth,
int& cursorHeight)
{
Poco::JSON::Parser parser;
const Poco::Dynamic::Var result = parser.parse(message);
const auto& command = result.extract<Poco::JSON::Object::Ptr>();
std::string text = command->get("commandName").toString();
CPPUNIT_ASSERT_EQUAL(std::string(".uno:CellCursor"), text);
text = command->get("commandValues").toString();
CPPUNIT_ASSERT(!text.empty());
std::vector<std::string> position(LOOLProtocol::tokenize(text, ','));
cursorX = std::stoi(position[0]);
cursorY = std::stoi(position[1]);
cursorWidth = std::stoi(position[2]);
cursorHeight = std::stoi(position[3]);
CPPUNIT_ASSERT(cursorX >= 0);
CPPUNIT_ASSERT(cursorY >= 0);
CPPUNIT_ASSERT(cursorWidth >= 0);
CPPUNIT_ASSERT(cursorHeight >= 0);
}
void limitCursor(const std::function<void(const std::shared_ptr<LOOLWebSocket>& socket, int cursorX,
int cursorY, int cursorWidth, int cursorHeight,
int docWidth, int docHeight)>& keyhandler,
const std::function<void(int docWidth, int docHeight, int newWidth,
int newHeight)>& checkhandler,
const std::string& testname)
{
int docSheet = -1;
int docSheets = 0;
int docHeight = 0;
int docWidth = 0;
int docViewId = -1;
int newSheet = -1;
int newSheets = 0;
int newHeight = 0;
int newWidth = 0;
int cursorX = 0;
int cursorY = 0;
int cursorWidth = 0;
int cursorHeight = 0;
std::string response;
Poco::URI uri(helpers::getTestServerURI());
std::shared_ptr<LOOLWebSocket> socket
= helpers::loadDocAndGetSocket("empty.ods", uri, testname);
// check document size
helpers::sendTextFrame(socket, "status", testname);
response = helpers::assertResponseString(socket, "status:", testname);
helpers::parseDocSize(response.substr(7), "spreadsheet", docSheet, docSheets, docWidth,
docHeight, docViewId);
// Send an arrow key to initialize the CellCursor, otherwise we get "EMPTY".
helpers::sendTextFrame(socket, "key type=input char=0 key=1027", testname);
std::string text;
Poco::format(text,
"commandvalues "
"command=.uno:CellCursor?outputHeight=%d&outputWidth=%d&tileHeight=%d&tileWidth=%"
"d",
256, 256, 3840, 3840);
helpers::sendTextFrame(socket, text, testname);
const auto cursor = helpers::getResponseString(socket, "commandvalues:", testname);
getCursor(cursor.substr(14), cursorX, cursorY, cursorWidth, cursorHeight);
// move cursor
keyhandler(socket, cursorX, cursorY, cursorWidth, cursorHeight, docWidth, docHeight);
// filter messages, and expect to receive new document size
response = helpers::assertResponseString(socket, "status:", testname);
helpers::parseDocSize(response.substr(7), "spreadsheet", newSheet, newSheets, newWidth,
newHeight, docViewId);
CPPUNIT_ASSERT_EQUAL(docSheets, newSheets);
CPPUNIT_ASSERT_EQUAL(docSheet, newSheet);
// check new document size
checkhandler(docWidth, docHeight, newWidth, newHeight);
}
}
/// Test suite for cursor handling.
class UnitCursor : public UnitWSD
{
TestResult testMaxColumn();
TestResult testMaxRow();
TestResult testInsertAnnotationWriter();
TestResult testEditAnnotationWriter();
TestResult testInsertAnnotationCalc();
public:
void invokeTest() override;
};
UnitBase::TestResult UnitCursor::testMaxColumn()
{
try
{
limitCursor(
// move cursor to last column
[](const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY,
int cursorWidth, int cursorHeight, int docWidth, int docHeight) {
CPPUNIT_ASSERT(cursorX >= 0);
CPPUNIT_ASSERT(cursorY >= 0);
CPPUNIT_ASSERT(cursorWidth >= 0);
CPPUNIT_ASSERT(cursorHeight >= 0);
CPPUNIT_ASSERT(docWidth >= 0);
CPPUNIT_ASSERT(docHeight >= 0);
const std::string text = "key type=input char=0 key=1027";
while (cursorX <= docWidth)
{
helpers::sendTextFrame(socket, text);
cursorX += cursorWidth;
}
},
// check new document width
[](int docWidth, int docHeight, int newWidth, int newHeight) {
CPPUNIT_ASSERT_EQUAL(docHeight, newHeight);
CPPUNIT_ASSERT(newWidth > docWidth);
},
"maxColumn");
}
catch (const Poco::Exception& exc)
{
CPPUNIT_FAIL(exc.displayText());
}
return TestResult::Ok;
}
UnitBase::TestResult UnitCursor::testMaxRow()
{
try
{
limitCursor(
// move cursor to last row
[](const std::shared_ptr<LOOLWebSocket>& socket, int cursorX, int cursorY,
int cursorWidth, int cursorHeight, int docWidth, int docHeight) {
CPPUNIT_ASSERT(cursorX >= 0);
CPPUNIT_ASSERT(cursorY >= 0);
CPPUNIT_ASSERT(cursorWidth >= 0);
CPPUNIT_ASSERT(cursorHeight >= 0);
CPPUNIT_ASSERT(docWidth >= 0);
CPPUNIT_ASSERT(docHeight >= 0);
const std::string text = "key type=input char=0 key=1024";
while (cursorY <= docHeight)
{
helpers::sendTextFrame(socket, text);
cursorY += cursorHeight;
}
},
// check new document height
[](int docWidth, int docHeight, int newWidth, int newHeight) {
CPPUNIT_ASSERT_EQUAL(docWidth, newWidth);
CPPUNIT_ASSERT(newHeight > docHeight);
},
"maxRow");
}
catch (const Poco::Exception& exc)
{
CPPUNIT_FAIL(exc.displayText());
}
return TestResult::Ok;
}
UnitBase::TestResult UnitCursor::testInsertAnnotationWriter()
{
const char* testname = "insertAnnotationWriter ";
std::string documentPath, documentURL;
helpers::getDocumentPathAndURL("hello.odt", documentPath, documentURL, testname);
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL);
Poco::URI uri(helpers::getTestServerURI());
std::shared_ptr<LOOLWebSocket> socket
= helpers::loadDocAndGetSocket(uri, documentURL, testname);
// Insert comment.
helpers::sendTextFrame(socket, "uno .uno:InsertAnnotation", testname);
helpers::assertResponseString(socket, "invalidatetiles:", testname);
// Paste some text.
helpers::sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nxxx yyy zzzz",
testname);
// Read it back.
std::string res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: xxx yyy zzzz"), res);
// Can we edit the comment?
helpers::sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\naaa bbb ccc",
testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res);
// Confirm that the text is in the comment and not doc body.
// Click in the body.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0",
testname);
// Read body text.
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res);
// Confirm that the comment is still intact.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(
socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res);
// Can we still edit the comment?
helpers::sendTextFrame(
socket,
"paste mimetype=text/plain;charset=utf-8\nand now for something completely different",
testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(
std::string("textselectioncontent: and now for something completely different"), res);
// Close and reopen the same document and test again.
socket->shutdown();
// Make sure the document is fully unloaded.
// testNoExtraLoolKitsLeft();
TST_LOG("Reloading ");
socket = helpers::loadDocAndGetSocket(uri, documentURL, testname);
// Confirm that the text is in the comment and not doc body.
// Click in the body.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0",
testname);
// Read body text.
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res);
// Confirm that the comment is still intact.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(
socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(
std::string("textselectioncontent: and now for something completely different"), res);
// Can we still edit the comment?
helpers::sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nblah blah xyz",
testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: blah blah xyz"), res);
return TestResult::Ok;
}
UnitBase::TestResult UnitCursor::testEditAnnotationWriter()
{
const char* testname = "editAnnotationWriter ";
std::string documentPath, documentURL;
helpers::getDocumentPathAndURL("with_comment.odt", documentPath, documentURL, testname);
Poco::URI uri(helpers::getTestServerURI());
std::shared_ptr<LOOLWebSocket> socket
= helpers::loadDocAndGetSocket(uri, documentURL, testname);
// Click in the body.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0",
testname);
// Read body text.
std::string res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res);
// Confirm that the comment is intact.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(
socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: blah blah xyz"), res);
// Can we still edit the comment?
helpers::sendTextFrame(
socket,
"paste mimetype=text/plain;charset=utf-8\nand now for something completely different",
testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(
std::string("textselectioncontent: and now for something completely different"), res);
// const int kitcount = getLoolKitProcessCount();
// Close and reopen the same document and test again.
TST_LOG("Closing connection after pasting.");
socket->shutdown();
TST_LOG("Reloading ");
socket = helpers::loadDocAndGetSocket(uri, documentURL, testname);
// Should have no new instances.
// CPPUNIT_ASSERT_EQUAL(kitcount, countLoolKitProcesses(kitcount));
// Confirm that the text is in the comment and not doc body.
// Click in the body.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=1600 y=1600 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(socket, "mouse type=buttonup x=1600 y=1600 count=1 buttons=1 modifier=0",
testname);
// Read body text.
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: Hello world"), res);
// Confirm that the comment is still intact.
helpers::sendTextFrame(
socket, "mouse type=buttondown x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
helpers::sendTextFrame(
socket, "mouse type=buttonup x=13855 y=1893 count=1 buttons=1 modifier=0", testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(
std::string("textselectioncontent: and now for something completely different"), res);
// Can we still edit the comment?
helpers::sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\nnew text different",
testname);
res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: new text different"), res);
return TestResult::Ok;
}
UnitBase::TestResult UnitCursor::testInsertAnnotationCalc()
{
const char* testname = "insertAnnotationCalc ";
Poco::URI uri(helpers::getTestServerURI());
std::shared_ptr<LOOLWebSocket> socket
= helpers::loadDocAndGetSocket("setclientpart.ods", uri, testname);
// Insert comment.
helpers::sendTextFrame(socket, "uno .uno:InsertAnnotation", testname);
// Paste some text.
helpers::sendTextFrame(socket, "paste mimetype=text/plain;charset=utf-8\naaa bbb ccc",
testname);
// Read it back.
std::string res = helpers::getAllText(socket, testname);
CPPUNIT_ASSERT_EQUAL(std::string("textselectioncontent: aaa bbb ccc"), res);
return TestResult::Ok;
}
void UnitCursor::invokeTest()
{
UnitBase::TestResult result = testMaxColumn();
if (result != TestResult::Ok)
exitTest(result);
result = testMaxRow();
if (result != TestResult::Ok)
exitTest(result);
// result = testInsertAnnotationWriter();
// if (result != TestResult::Ok)
// exitTest(result);
// result = testEditAnnotationWriter();
// if (result != TestResult::Ok)
// exitTest(result);
// FIXME result = testInsertAnnotationCalc();
// if (result != TestResult::Ok)
// exitTest(result);
exitTest(TestResult::Ok);
}
UnitBase* unit_create_wsd(void) { return new UnitCursor(); }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */