/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * 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/.
*/
static LibreOfficeKitDocumentType getDocumentTypeFromName(constchar* pName)
{
CPPUNIT_ASSERT_MESSAGE("Document name must be valid.", pName != nullptr);
const std::string name(pName);
CPPUNIT_ASSERT_MESSAGE("Document name must include extension.", name.size() > 4);
constauto it = name.rfind('.'); if (it != std::string::npos)
{ const std::string ext = name.substr(it);
if (ext == ".ods") return LOK_DOCTYPE_SPREADSHEET;
if (ext == ".odp") return LOK_DOCTYPE_PRESENTATION;
}
CPPUNIT_ASSERT_MESSAGE("Document name must include extension.", it != std::string::npos); return LOK_DOCTYPE_TEXT;
}
class DesktopLOKTest : public UnoApiTest
{ public:
DesktopLOKTest() : UnoApiTest(u"/desktop/qa/data/"_ustr),
m_nSelectionBeforeSearchResult(0),
m_nSelectionAfterSearchResult(0),
m_bModified(false),
m_nTrackChanges(0)
{
}
~DesktopLOKTest();
boost::property_tree::ptree aValues = aTree.get_child("commandValues");
CPPUNIT_ASSERT( !aValues.empty() ); for (constauto& rPair : aValues)
{ // check that we have font sizes available for each font
CPPUNIT_ASSERT( !rPair.second.empty());
}
free(pJSON);
}
int nId0 = pDocument->m_pDocumentClass->getView(pDocument); int nId1 = pDocument->m_pDocumentClass->createView(pDocument);
CPPUNIT_ASSERT_EQUAL(2, pDocument->m_pDocumentClass->getViewsCount(pDocument));
// Make sure the created view is the active one, then switch to the old // one.
CPPUNIT_ASSERT_EQUAL(nId1, pDocument->m_pDocumentClass->getView(pDocument));
pDocument->m_pDocumentClass->setView(pDocument, nId0);
CPPUNIT_ASSERT_EQUAL(nId0, pDocument->m_pDocumentClass->getView(pDocument));
void DesktopLOKTest::testGetPartPageRectangles()
{ // Test that we get as many page rectangles as expected: blank document is // one page.
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); char* pRectangles = pDocument->pClass->getPartPageRectangles(pDocument);
OUString sRectangles = OUString::fromUtf8(pRectangles);
std::vector<OUString> aRectangles;
sal_Int32 nIndex = 0; do
{
OUString aRectangle = sRectangles.getToken(0, ';', nIndex); if (!aRectangle.isEmpty())
aRectangles.push_back(aRectangle);
} while (nIndex >= 0);
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aRectangles.size());
std::vector<OString> aSelections;
sal_Int32 nIndex = 0; do
{
OString aToken = m_aTextSelection.getToken(0, ';', nIndex);
aSelections.push_back(aToken);
} while (nIndex >= 0); // This was 1, find-all only found one match.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), aSelections.size()); // Make sure that we get exactly as many rectangle lists as matches.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), m_aSearchResultSelection.size()); // Result is on the first sheet.
CPPUNIT_ASSERT_EQUAL(0, m_aSearchResultPart[0]);
}
// This was 1, make sure that we get no notifications about selection changes during search.
CPPUNIT_ASSERT_EQUAL(0, m_nSelectionBeforeSearchResult); // But we do get the selection afterwards.
CPPUNIT_ASSERT(m_nSelectionAfterSearchResult > 0);
}
void DesktopLOKTest::testPaintTile()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); int nCanvasWidth = 100; int nCanvasHeight = 300;
sal_Int32 nStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, nCanvasWidth);
std::vector<unsignedchar> aBuffer(nStride * nCanvasHeight); int nTilePosX = 0; int nTilePosY = 0; int nTileWidth = 1000; int nTileHeight = 3000;
// This used to crash: paintTile() implementation did not handle // nCanvasWidth != nCanvasHeight correctly, as usually both are just always // 256.
pDocument->pClass->paintTile(pDocument, aBuffer.data(), nCanvasWidth, nCanvasHeight, nTilePosX, nTilePosY, nTileWidth, nTileHeight);
void DesktopLOKTest::testSaveAsJsonOptions()
{ // Given a document with 3 pages:
LibLODocument_Impl* pDocument = loadDoc("3page.odg");
// When exporting that document to PDF, skipping the first page:
OString aOptions("{\"PageRange\":{\"type\":\"string\",\"value\":\"2-\"}}"_ostr);
CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, maTempFile.GetURL().toUtf8().getStr(), "pdf", aOptions.getStr()));
std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); if (!pPDFium) return;
// Then make sure the resulting PDF has 2 pages:
std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument
= parsePDFExport(); // Without the accompanying fix in place, this test would have failed with: // - Expected: 2 // - Actual : 3 // i.e. FilterOptions was ignored.
CPPUNIT_ASSERT_EQUAL(2, pPdfDocument->getPageCount());
}
// textt/plain should be rejected.
CPPUNIT_ASSERT(!pDocument->pClass->paste(pDocument, "textt/plain;charset=utf-8", aText.getStr(), aText.getLength())); // Writer is expected to support text/html.
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/html", aText.getStr(), aText.getLength()));
// Overwrite doc contents with a HTML paste.
pDocument->pClass->postUnoCommand(pDocument, ".uno:SelectAll", nullptr, false);
Scheduler::ProcessEventsToIdle();
OString aComment("foo baz"_ostr);
CPPUNIT_ASSERT(pDocument->pClass->paste(pDocument, "text/html", aComment.getStr(), aComment.getLength()));
// Check if we have a comment.
uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xParagraphEnumerationAccess(xTextDocument->getText(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xParagraphEnumeration = xParagraphEnumerationAccess->createEnumeration();
uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphEnumeration->nextElement(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xTextPortionEnumeration = xParagraph->createEnumeration();
uno::Reference<beans::XPropertySet> xTextPortion(xTextPortionEnumeration->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"Text"_ustr, xTextPortion->getPropertyValue(u"TextPortionType"_ustr).get<OUString>()); // Without the accompanying fix in place, this test would have failed, as we had a comment // between "foo" and "baz".
CPPUNIT_ASSERT(!xTextPortionEnumeration->hasMoreElements());
}
uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); // This was 0, JPEG was not handled as a format for clipboard paste.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); // This was text::TextContentAnchorType_AT_PARAGRAPH.
CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER, xShape->getPropertyValue(u"AnchorType"_ustr).get<text::TextContentAnchorType>());
// Delete the pasted picture, and paste again with a custom anchor type.
uno::Reference<lang::XComponent>(xShape, uno::UNO_QUERY_THROW)->dispose();
uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence(
{
{"AnchorType", uno::Any(static_cast<sal_uInt16>(text::TextContentAnchorType_AT_CHARACTER))},
}));
dispatchCommand(mxComponent, u".uno:Paste"_ustr, aPropertyValues);
xShape.set(xDrawPage->getByIndex(0), uno::UNO_QUERY); // This was text::TextContentAnchorType_AS_CHARACTER, AnchorType argument was ignored.
CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER, xShape->getPropertyValue(u"AnchorType"_ustr).get<text::TextContentAnchorType>());
}
void DesktopLOKTest::testUndoWriter()
{ // Load a Writer document and press a key.
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYINPUT, 't', 0);
pDocument->pClass->postKeyEvent(pDocument, LOK_KEYEVENT_KEYUP, 't', 0);
Scheduler::ProcessEventsToIdle(); // Get undo info.
boost::property_tree::ptree aTree; char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, ".uno:Undo");
std::stringstream aStream(pJSON);
free(pJSON);
CPPUNIT_ASSERT(!aStream.str().empty());
boost::property_tree::read_json(aStream, aTree); // Make sure that pressing a key creates exactly one undo action.
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aTree.get_child("actions").size());
}
void DesktopLOKTest::testRowColumnHeaders()
{ /* * Payload example: * * { * "rows": [ * { * "size": "254.987250637468", * "text": "1" * }, * { * "size": "509.974501274936", * "text": "2" * } * ], * "columns": [ * { * "size": "1274.93625318734", * "text": "A" * }, * { * "size": "2549.87250637468", * "text": "B" * } * ] * } * * "size" defines the bottom/right boundary of a row/column in twips (size between 0 and boundary) * "text" has the header label in UTF-8
*/
LibLODocument_Impl* pDocument = loadDoc("search.ods");
// the postUnoCommand() is supposed to be async, let's test it safely // [no idea if it is async in reality - most probably we are operating // under some solar mutex or something anyway ;-) - but...]
TimeValue aTimeValue = { 2 , 0 }; // 2 seconds max
// nothing is triggered when we have no callback yet, we just time out on // the condition var.
m_aCommandResultCondition.reset();
pDocument->pClass->postUnoCommand(pDocument, ".uno:Bold", nullptr, true);
Scheduler::ProcessEventsToIdle();
m_aCommandResultCondition.wait(aTimeValue);
CPPUNIT_ASSERT(m_aCommandResult.isEmpty());
// but we get some real values when the callback is set up
pDocument->pClass->registerCallback(pDocument, &DesktopLOKTest::callback, this);
// Insert a comment at the beginning of the document and wait till the main // loop grabs the focus, so characters end up in the annotation window.
TimeValue const aTimeValue = {2 , 0}; // 2 seconds max
m_aCommandResultCondition.reset();
pDocument->pClass->postUnoCommand(pDocument, ".uno:InsertAnnotation", nullptr, true);
Scheduler::ProcessEventsToIdle();
m_aCommandResultCondition.wait(aTimeValue);
CPPUNIT_ASSERT(!m_aCommandResult.isEmpty());
xToolkit->reschedule();
// Test that we have a comment.
uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xParagraphEnumerationAccess(xTextDocument->getText(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xParagraphEnumeration = xParagraphEnumerationAccess->createEnumeration();
uno::Reference<container::XEnumerationAccess> xParagraph(xParagraphEnumeration->nextElement(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xTextPortionEnumeration = xParagraph->createEnumeration();
uno::Reference<beans::XPropertySet> xTextPortion(xTextPortionEnumeration->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(u"Annotation"_ustr, xTextPortion->getPropertyValue(u"TextPortionType"_ustr).get<OUString>());
// Test that the typed characters ended up in the right window. auto xTextField = xTextPortion->getPropertyValue(u"TextField"_ustr).get< uno::Reference<beans::XPropertySet> >(); // This was empty, typed characters ended up in the body text.
CPPUNIT_ASSERT_EQUAL(u"test"_ustr, xTextField->getPropertyValue(u"Content"_ustr).get<OUString>());
}
/* * Check if selection data is correct
*/ // Values in twips int row5 = 1150; int col1 = 1100; intconst col2 = 2200; intconst col3 = 3300; int col4 = 4400; int col5 = 5500;
// Selected text should get deselected and copying should give us // content of only one cell, now
{ char* pUsedMimeType = nullptr; char* pCopiedContent = pDocument->pClass->getTextSelection(pDocument, nullptr, &pUsedMimeType);
std::vector<long> aExpected = { 8 };
std::istringstream iss(pCopiedContent); for (constlong nIndex : aExpected)
{
std::string token;
iss >> token;
CPPUNIT_ASSERT_EQUAL(nIndex, strtol(token.c_str(), nullptr, 10));
}
void verifyContextMenuStructure(boost::property_tree::ptree& aRoot)
{ for (constauto& aItemPair: aRoot)
{ // This is an array, so no key
CPPUNIT_ASSERT_EQUAL(aItemPair.first, std::string(""));
// tests for calc specific context menu // Cut is enabled
{
boost::optional<boost::property_tree::ptree> aMenuItem = getContextMenuItem(aMenu.get(), ".uno:Cut");
CPPUNIT_ASSERT(aMenuItem);
// these are radio buttons
boost::optional<boost::property_tree::ptree&> aChecktypeToPage = aMenuItemToPage.get().get_child_optional("checktype");
CPPUNIT_ASSERT(aChecktypeToPage);
CPPUNIT_ASSERT_EQUAL(aChecktypeToPage.get().data(), std::string("radio"));
// tests for writer specific context menu // Cut is disabled
{
boost::optional<boost::property_tree::ptree> aMenuItem = getContextMenuItem(aMenu.get(), ".uno:Cut");
CPPUNIT_ASSERT(aMenuItem);
// random point where we don't hit an underlying comment or text box
Point aRandomPoint(10, 1150);
pDocument->pClass->postMouseEvent(pDocument,
LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
aRandomPoint.X(), aRandomPoint.Y(),
1, 4, 0);
Scheduler::ProcessEventsToIdle();
// tests for impress specific context menu // Cut is disabled
{
boost::optional<boost::property_tree::ptree> aMenuItem = getContextMenuItem(aMenu.get(), ".uno:Cut");
CPPUNIT_ASSERT(aMenuItem);
handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""_ostr); // 0
handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"_ostr); // Superseded.
handler->queue(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, ""_ostr); // Should be dropped.
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "15, 25, 15, 10"_ostr); // 1
handler->queue(LOK_CALLBACK_TEXT_SELECTION, "15, 25, 15, 10"_ostr); // Should be dropped.
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.17Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.