Avoid potential negative array index access to cached text.
[LibreOffice.git] / writerfilter / qa / cppunittests / dmapper / PropertyMap.cxx
blob2952f1f93302f4a2d8f0c1728db1a9d7946d2ace
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <test/unoapi_test.hxx>
12 #include <com/sun/star/text/XPageCursor.hpp>
13 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
14 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
15 #include <com/sun/star/beans/XPropertySet.hpp>
16 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
17 #include <com/sun/star/table/BorderLine2.hpp>
18 #include <com/sun/star/text/XTextDocument.hpp>
19 #include <com/sun/star/document/XFilter.hpp>
20 #include <com/sun/star/document/XImporter.hpp>
22 #include <unotools/streamwrap.hxx>
23 #include <comphelper/propertyvalue.hxx>
25 using namespace ::com::sun::star;
27 namespace
29 /// Tests for writerfilter/source/dmapper/PropertyMap.cxx.
30 class Test : public UnoApiTest
32 public:
33 Test()
34 : UnoApiTest("/writerfilter/qa/cppunittests/dmapper/data/")
39 CPPUNIT_TEST_FIXTURE(Test, testFloatingTableHeader)
41 loadFromFile(u"floating-table-header.docx");
42 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
43 uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
44 xModel->getCurrentController(), uno::UNO_QUERY);
45 uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(),
46 uno::UNO_QUERY);
47 xCursor->jumpToLastPage();
48 // Without the accompanying fix in place, this test would have failed with:
49 // - Expected: 1
50 // - Actual : 3
51 // i.e. a document which is 1 page in Word was imported as a 3 page one.
52 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xCursor->getPage());
55 // TODO - First Page Headers Support
56 CPPUNIT_TEST_FIXTURE(Test, testFollowPageTopMargin)
58 // Load a document with 2 pages: first page has larger top margin, second page has smaller top
59 // margin.
60 loadFromFile(u"follow-page-top-margin.docx");
61 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
62 uno::UNO_QUERY);
63 uno::Reference<container::XNameAccess> xStyleFamilies
64 = xStyleFamiliesSupplier->getStyleFamilies();
65 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
66 uno::UNO_QUERY);
67 uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
68 auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
70 // Without the accompanying fix in place, this test would have failed with:
71 // - Expected: 250
72 // - Actual : 1249
73 // i.e. the top margin on page 2 was too large.
74 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1249), nTopMargin);
77 CPPUNIT_TEST_FIXTURE(Test, testTableNegativeVerticalPos)
79 // Given a document with a table which has a negative vertical position (moves up to overlap
80 // with the header):
81 loadFromFile(u"table-negative-vertical-pos.docx");
83 // Then make sure we don't import that as a plain table, which can't have a negative top margin:
84 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
85 uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
86 // Without the accompanying fix in place, this test would have failed with:
87 // - Expected: 1
88 // - Actual : 0
89 // i.e. this was imported as a plain table, resulting in a 0 top margin (y pos too large).
90 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
93 CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorder)
95 // Given a document with a top margin and a border which has more spacing than the margin:
96 loadFromFile(u"negative-page-border.docx");
98 // Then make sure that the border distance is negative, so it can appear at the correct
99 // position:
100 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
101 uno::UNO_QUERY);
102 uno::Reference<container::XNameAccess> xStyleFamilies
103 = xStyleFamiliesSupplier->getStyleFamilies();
104 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
105 uno::UNO_QUERY);
106 uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
107 auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
108 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(501), nTopMargin);
109 auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
110 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
111 auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
112 // Without the accompanying fix in place, this test would have failed with:
113 // - Expected: -646
114 // - Actual : 0
115 // i.e. the border negative distance was lost.
116 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-646), nTopBorderDistance);
119 CPPUNIT_TEST_FIXTURE(Test, testNegativePageBorderNoMargin)
121 // Given a document with no top margin and a border which has spacing:
122 loadFromFile(u"negative-page-border-no-margin.docx");
124 // Then make sure that the border distance is negative, so it can appear at the correct
125 // position:
126 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
127 uno::UNO_QUERY);
128 uno::Reference<container::XNameAccess> xStyleFamilies
129 = xStyleFamiliesSupplier->getStyleFamilies();
130 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
131 uno::UNO_QUERY);
132 uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
133 auto nTopMargin = xStyle->getPropertyValue("TopMargin").get<sal_Int32>();
134 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), nTopMargin);
135 auto aTopBorder = xStyle->getPropertyValue("TopBorder").get<table::BorderLine2>();
136 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(159), aTopBorder.LineWidth);
137 auto nTopBorderDistance = xStyle->getPropertyValue("TopBorderDistance").get<sal_Int32>();
138 // Without the accompanying fix in place, this test would have failed with:
139 // - Expected: -1147
140 // - Actual : 0
141 // i.e. the border negative distance was lost.
142 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1147), nTopBorderDistance);
145 CPPUNIT_TEST_FIXTURE(Test, testPasteHeaderDisable)
147 // Given an empty document with a turned on header:
148 mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
149 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent,
150 uno::UNO_QUERY);
151 uno::Reference<container::XNameAccess> xStyleFamilies
152 = xStyleFamiliesSupplier->getStyleFamilies();
153 uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName("PageStyles"),
154 uno::UNO_QUERY);
155 uno::Reference<beans::XPropertySet> xStyle(xStyleFamily->getByName("Standard"), uno::UNO_QUERY);
156 xStyle->setPropertyValue("HeaderIsOn", uno::Any(true));
158 // When pasting RTF content:
159 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
160 uno::Reference<text::XTextRange> xText = xTextDocument->getText();
161 uno::Reference<text::XTextRange> xBodyEnd = xText->getEnd();
162 uno::Reference<document::XFilter> xFilter(
163 m_xSFactory->createInstance("com.sun.star.comp.Writer.RtfFilter"), uno::UNO_QUERY);
164 uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY);
165 xImporter->setTargetDocument(mxComponent);
166 std::unique_ptr<SvStream> pStream(new SvMemoryStream);
167 pStream->WriteOString("{\\rtf1 paste}");
168 pStream->Seek(0);
169 uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(std::move(pStream)));
170 uno::Sequence aDescriptor{ comphelper::makePropertyValue("InputStream", xStream),
171 comphelper::makePropertyValue("InsertMode", true),
172 comphelper::makePropertyValue("TextInsertModeRange", xBodyEnd) };
173 CPPUNIT_ASSERT(xFilter->filter(aDescriptor));
175 // Then make sure the header stays on:
176 CPPUNIT_ASSERT(xStyle->getPropertyValue("HeaderIsOn").get<bool>());
180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */