Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
4 : : *
5 : : * The contents of this file are subject to the Mozilla Public License Version
6 : : * 1.1 (the "License"); you may not use this file except in compliance with
7 : : * the License. You may obtain a copy of the License at
8 : : * http://www.mozilla.org/MPL/
9 : : *
10 : : * Software distributed under the License is distributed on an "AS IS" basis,
11 : : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : : * for the specific language governing rights and limitations under the
13 : : * License.
14 : : *
15 : : * The Initial Developer of the Original Code is
16 : : * Thorsten Behrens <tbehrens@novell.com>
17 : : * Portions created by the Initial Developer are Copyright (C) 2011 the
18 : : * Initial Developer. All Rights Reserved.
19 : : *
20 : : * Contributor(s):
21 : : * Thorsten Behrens <tbehrens@novell.com>
22 : : * Caolán McNamara <caolanm@redhat.com>
23 : : *
24 : : * Alternatively, the contents of this file may be used under the terms of
25 : : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
26 : : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
27 : : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
28 : : * instead of those above.
29 : : */
30 : :
31 : : #include <sal/config.h>
32 : : #include <test/bootstrapfixture.hxx>
33 : :
34 : : #include <rtl/strbuf.hxx>
35 : : #include <osl/file.hxx>
36 : :
37 : : #include <tools/urlobj.hxx>
38 : : #include <unotools/tempfile.hxx>
39 : :
40 : : #include <editeng/langitem.hxx>
41 : : #include <editeng/charhiddenitem.hxx>
42 : :
43 : : #include <sfx2/app.hxx>
44 : : #include <sfx2/docfilt.hxx>
45 : : #include <sfx2/docfile.hxx>
46 : : #include <sfx2/sfxmodelfactory.hxx>
47 : :
48 : : #include "breakit.hxx"
49 : : #include "doc.hxx"
50 : : #include "docsh.hxx"
51 : : #include "docstat.hxx"
52 : : #include "docufld.hxx"
53 : : #include "fmtanchr.hxx"
54 : : #include "init.hxx"
55 : : #include "ndtxt.hxx"
56 : : #include "shellio.hxx"
57 : : #include "shellres.hxx"
58 : : #include "swcrsr.hxx"
59 : : #include "swscanner.hxx"
60 : : #include "swmodule.hxx"
61 : : #include "swtypes.hxx"
62 : : #include "fmtftn.hxx"
63 : : #include "fmtrfmrk.hxx"
64 : : #include "fmtfld.hxx"
65 : : #include "redline.hxx"
66 : : #include "docary.hxx"
67 : : #include "modeltoviewhelper.hxx"
68 : : #include "scriptinfo.hxx"
69 : :
70 : 60 : SO2_DECL_REF(SwDocShell)
71 [ + - ][ + - ]: 144 : SO2_IMPL_REF(SwDocShell)
[ - + ][ + + ]
[ + - ][ + - ]
72 : :
73 : : using namespace ::com::sun::star;
74 : :
75 : : /* Implementation of Swdoc-Test class */
76 : :
77 [ + - ][ - + ]: 72 : class SwDocTest : public test::BootstrapFixture
78 : : {
79 : : public:
80 : : virtual void setUp();
81 : : virtual void tearDown();
82 : :
83 : : void randomTest();
84 : : void testPageDescName();
85 : : void testFileNameFields();
86 : : void testDocStat();
87 : : void testModelToViewHelper();
88 : : void testSwScanner();
89 : : void testUserPerceivedCharCount();
90 : : void testGraphicAnchorDeletion();
91 : :
92 [ + - ][ + - ]: 6 : CPPUNIT_TEST_SUITE(SwDocTest);
[ + - ][ + - ]
[ # # ]
93 [ + - ][ + - ]: 3 : CPPUNIT_TEST(randomTest);
[ + - ][ + - ]
[ + - ][ + - ]
94 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testPageDescName);
[ + - ][ + - ]
[ + - ][ + - ]
95 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testFileNameFields);
[ + - ][ + - ]
[ + - ][ + - ]
96 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testDocStat);
[ + - ][ + - ]
[ + - ][ + - ]
97 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testModelToViewHelper);
[ + - ][ + - ]
[ + - ][ + - ]
98 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testSwScanner);
[ + - ][ + - ]
[ + - ][ + - ]
99 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testUserPerceivedCharCount);
[ + - ][ + - ]
[ + - ][ + - ]
100 [ + - ][ + - ]: 3 : CPPUNIT_TEST(testGraphicAnchorDeletion);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
101 [ + - ][ + - ]: 6 : CPPUNIT_TEST_SUITE_END();
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
102 : :
103 : : private:
104 : : SwDoc *m_pDoc;
105 : : SwDocShellRef m_xDocShRef;
106 : : };
107 : :
108 : 3 : void SwDocTest::testPageDescName()
109 : : {
110 [ + - ]: 3 : ShellResource aShellResources;
111 : :
112 [ + - ]: 3 : std::vector<rtl::OUString> aResults;
113 : :
114 : : //These names must be unique for each different combination, otherwise
115 : : //duplicate page description names may exist, which will causes lookup
116 : : //by name to be incorrect, and so the corresponding export to .odt
117 [ + - ][ + - ]: 3 : aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::NORMAL_PAGE));
[ + - ][ + - ]
118 [ + - ][ + - ]: 3 : aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FIRST_PAGE));
[ + - ][ + - ]
119 [ + - ][ + - ]: 3 : aResults.push_back(aShellResources.GetPageDescName(1, ShellResource::FOLLOW_PAGE));
[ + - ][ + - ]
120 : :
121 [ + - ]: 3 : std::sort(aResults.begin(), aResults.end());
122 [ + - ][ + - ]: 3 : aResults.erase(std::unique(aResults.begin(), aResults.end()), aResults.end());
123 : :
124 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("GetPageDescName results must be unique", aResults.size() == 3);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
125 : 3 : }
126 : :
127 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=32463
128 : 3 : void SwDocTest::testFileNameFields()
129 : : {
130 : : //Here's a file name with some chars in it that will be %% encoded, when expanding
131 : : //SwFileNameFields we want to restore the original readable filename
132 [ + - ][ + - ]: 3 : utl::TempFile aTempFile(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("demo [name]")));
[ + - ][ + - ]
133 : 3 : aTempFile.EnableKillingFile();
134 : :
135 [ + - ][ + - ]: 3 : INetURLObject aTempFileURL(aTempFile.GetURL());
[ + - ][ + - ]
136 [ + - ][ + - ]: 3 : String sFileURL = aTempFileURL.GetMainURL(INetURLObject::NO_DECODE);
137 [ + - ]: 3 : SfxMedium aDstMed(sFileURL, STREAM_STD_READWRITE);
138 : :
139 : : SfxFilter aFilter(
140 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text")),
141 : : rtl::OUString(), 0, 0, rtl::OUString(), 0, rtl::OUString(),
142 [ + - ][ + - ]: 3 : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TEXT")), rtl::OUString() );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
143 [ + - ]: 3 : aDstMed.SetFilter(&aFilter);
144 : :
145 [ + - ]: 3 : m_xDocShRef->DoSaveAs(aDstMed);
146 [ + - ]: 3 : m_xDocShRef->DoSaveCompleted(&aDstMed);
147 : :
148 [ + - ]: 3 : const INetURLObject &rUrlObj = m_xDocShRef->GetMedium()->GetURLObject();
149 : :
150 [ + - ]: 3 : SwFileNameFieldType aNameField(m_pDoc);
151 : :
152 : : {
153 [ + - ][ + - ]: 3 : rtl::OUString sResult(aNameField.Expand(FF_NAME));
[ + - ]
154 : : rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT,
155 [ + - ]: 3 : true,INetURLObject::DECODE_WITH_CHARSET));
156 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
157 : : }
158 : :
159 : : {
160 [ + - ][ + - ]: 3 : rtl::OUString sResult(aNameField.Expand(FF_PATHNAME));
[ + - ]
161 [ + - ]: 3 : rtl::OUString sExpected(rUrlObj.GetFull());
162 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
163 : : }
164 : :
165 : : {
166 [ + - ][ + - ]: 3 : rtl::OUString sResult(aNameField.Expand(FF_PATH));
[ + - ]
167 [ + - ]: 3 : INetURLObject aTemp(rUrlObj);
168 [ + - ]: 3 : aTemp.removeSegment();
169 [ + - ]: 3 : rtl::OUString sExpected(aTemp.PathToFileName());
170 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
171 : : }
172 : :
173 : : {
174 [ + - ][ + - ]: 3 : rtl::OUString sResult(aNameField.Expand(FF_NAME_NOEXT));
[ + - ]
175 : : rtl::OUString sExpected(rUrlObj.getName(INetURLObject::LAST_SEGMENT,
176 [ + - ]: 3 : true,INetURLObject::DECODE_WITH_CHARSET));
177 : : //Chop off .tmp
178 : 3 : sExpected = sExpected.copy(0, sExpected.getLength() - 4);
179 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected Readable FileName", sResult == sExpected);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
180 : : }
181 : :
182 [ + - ][ + - ]: 3 : m_xDocShRef->DoInitNew(0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
183 : 3 : }
184 : :
185 : : //See http://lists.freedesktop.org/archives/libreoffice/2011-August/016666.html
186 : : //Remove unnecessary parameter to IDocumentStatistics::UpdateDocStat for
187 : : //motivation
188 : 3 : void SwDocTest::testDocStat()
189 : : {
190 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
191 : :
192 [ + - ][ + - ]: 3 : SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
193 [ + - ]: 3 : SwPaM aPaM(aIdx);
194 : :
195 [ + - ]: 3 : rtl::OUString sText(RTL_CONSTASCII_USTRINGPARAM("Hello World"));
196 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, sText);
[ + - ]
197 : :
198 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should still be non-updated 0 count", m_pDoc->GetDocStat().nChar == 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
199 : :
200 [ + - ]: 3 : SwDocStat aDocStat = m_pDoc->GetUpdatedDocStat();
201 : 3 : sal_uLong nLen = static_cast<sal_uLong>(sText.getLength());
202 : :
203 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should now have updated count", aDocStat.nChar == nLen);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
204 : :
205 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("And cache is updated too", m_pDoc->GetDocStat().nChar == nLen);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
206 : 3 : }
207 : :
208 : : //For UI character counts we should follow UAX#29 and display the user
209 : : //perceived characters, not the number of codepoints, nor the number of code
210 : : //units http://unicode.org/reports/tr29/
211 : 3 : void SwDocTest::testUserPerceivedCharCount()
212 : : {
213 [ + - ]: 3 : SwBreakIt *pBreakIter = SwBreakIt::Get();
214 : :
215 : : //Grapheme example, two different unicode code-points perceived by the user as a single
216 : : //glyph
217 : 3 : const sal_Unicode ALEF_QAMATS [] = { 0x05D0, 0x05B8 };
218 : 3 : ::rtl::OUString sALEF_QAMATS(ALEF_QAMATS, SAL_N_ELEMENTS(ALEF_QAMATS));
219 [ + - ]: 3 : sal_Int32 nGraphemeCount = pBreakIter->getGraphemeCount(sALEF_QAMATS);
220 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Grapheme Count should be 1", nGraphemeCount == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
221 : :
222 : : //Surrogate pair example, one single unicode code-point (U+1D11E)
223 : : //represented as two code units in UTF-16
224 : 3 : const sal_Unicode GCLEF[] = { 0xD834, 0xDD1E };
225 : 3 : ::rtl::OUString sGCLEF(GCLEF, SAL_N_ELEMENTS(GCLEF));
226 [ + - ]: 3 : sal_Int32 nCount = pBreakIter->getGraphemeCount(sGCLEF);
227 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Surrogate Pair should be counted as single character", nCount == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
228 : 3 : }
229 : :
230 : 3 : void SwDocTest::testModelToViewHelper()
231 : : {
232 [ + - ][ + - ]: 3 : SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
233 [ + - ]: 3 : SwPaM aPaM(aIdx);
234 : :
235 : : {
236 [ + - ]: 3 : SwFmtFtn aFtn;
237 [ + - ][ + - ]: 3 : aFtn.SetNumStr(rtl::OUString("foo"));
[ + - ]
238 : :
239 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
240 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString("AAAAA BBBBB "));
[ + - ]
241 : 3 : SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode();
242 : 3 : xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex();
243 [ + - ]: 3 : pTxtNode->InsertItem(aFtn, nPos, nPos);
244 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(" CCCCC "));
[ + - ]
245 : 3 : nPos = aPaM.GetPoint()->nContent.GetIndex();
246 [ + - ]: 3 : pTxtNode->InsertItem(aFtn, nPos, nPos);
247 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(" DDDDD"));
[ + - ]
248 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTxtNode->GetTxt().Len() == (4*5) + 5 + 2);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
249 : :
250 : : //set start of selection to first B
251 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 6);
252 [ + - ]: 3 : aPaM.SetMark();
253 : : //set end of selection to last C
254 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 14);
255 : : //set character attribute hidden on range
256 [ + - ]: 3 : SvxCharHiddenItem aHidden(true, RES_CHRATR_HIDDEN);
257 [ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, aHidden, 0 );
258 : :
259 : : //turn on red-lining and show changes
260 [ + - ]: 3 : m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT);
261 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
262 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode()));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
263 : :
264 : : //set start of selection to last A
265 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 4);
266 [ + - ]: 3 : aPaM.SetMark();
267 : : //set end of selection to second last B
268 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 9);
269 [ + - ]: 3 : m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api
270 : :
271 : : {
272 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, PASSTHROUGH);
273 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
274 [ + - ]: 3 : rtl::OUString sModelText = pTxtNode->GetTxt();
275 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == sModelText);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
276 : : }
277 : :
278 : : {
279 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS);
280 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
281 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == "AAAAA BBBBB foo CCCCC foo DDDDD");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
282 : : }
283 : :
284 : : {
285 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE);
286 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
287 : 3 : rtl::OUStringBuffer aBuffer;
288 [ + - ]: 3 : aBuffer.append("AAAAA CCCCC ");
289 [ + - ]: 3 : aBuffer.append(CH_TXTATR_BREAKWORD);
290 [ + - ]: 3 : aBuffer.append(" DDDDD");
291 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
292 : : }
293 : :
294 : : {
295 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEREDLINED);
296 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
297 : 3 : rtl::OUStringBuffer aBuffer;
298 [ + - ]: 3 : aBuffer.append("AAAABB ");
299 [ + - ]: 3 : aBuffer.append(CH_TXTATR_BREAKWORD);
300 [ + - ]: 3 : aBuffer.append(" CCCCC ");
301 [ + - ]: 3 : aBuffer.append(CH_TXTATR_BREAKWORD);
302 [ + - ]: 3 : aBuffer.append(" DDDDD");
303 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
304 : : }
305 : :
306 : : {
307 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE);
308 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
309 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == "AAAAA CCCCC foo DDDDD");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
310 : : }
311 : :
312 : : {
313 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEREDLINED);
314 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
315 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == "AAAABB foo CCCCC foo DDDDD");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
316 : : }
317 : :
318 : : {
319 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, HIDEINVISIBLE | HIDEREDLINED);
320 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
321 : 3 : rtl::OUStringBuffer aBuffer;
322 [ + - ]: 3 : aBuffer.append("AAAACCCCC ");
323 [ + - ]: 3 : aBuffer.append(CH_TXTATR_BREAKWORD);
324 [ + - ]: 3 : aBuffer.append(" DDDDD");
325 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == aBuffer.makeStringAndClear());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
326 : : }
327 : :
328 : : {
329 [ + - ]: 3 : ModelToViewHelper aModelToViewHelper(*pTxtNode, EXPANDFIELDS | HIDEINVISIBLE | HIDEREDLINED);
330 : 3 : rtl::OUString sViewText = aModelToViewHelper.getViewText();
331 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sViewText == "AAAACCCCC foo DDDDD");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
332 [ + - ][ + - ]: 3 : }
333 [ + - ][ + - ]: 3 : }
334 : 3 : }
335 : :
336 : 3 : void SwDocTest::testSwScanner()
337 : : {
338 [ + - ][ + - ]: 3 : SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
339 [ + - ]: 3 : SwPaM aPaM(aIdx);
340 : :
341 : 3 : SwTxtNode* pTxtNode = aPaM.GetNode()->GetTxtNode();
342 : :
343 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Has Text Node", pTxtNode);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
344 : :
345 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=40449
346 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=39365
347 : : //Use a temporary rtl::OUString as the arg, as that's the trouble behind
348 : : //fdo#40449 and fdo#39365
349 : : {
350 : : SwScanner aScanner(*pTxtNode,
351 : : rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Hello World")),
352 : : 0, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, 0,
353 [ + - ][ + - ]: 3 : RTL_CONSTASCII_LENGTH("Hello World"));
[ + - ]
354 : :
355 [ + - ]: 3 : bool bFirstOk = aScanner.NextWord();
356 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("First Token", bFirstOk);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
357 : 3 : const rtl::OUString &rHello = aScanner.GetWord();
358 [ + - ][ + - ]: 6 : CPPUNIT_ASSERT_MESSAGE("Should be Hello",
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
359 [ + - ]: 3 : rHello.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Hello")));
360 : :
361 [ + - ]: 3 : bool bSecondOk = aScanner.NextWord();
362 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Second Token", bSecondOk);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
363 : 3 : const rtl::OUString &rWorld = aScanner.GetWord();
364 [ + - ][ + - ]: 6 : CPPUNIT_ASSERT_MESSAGE("Should be World",
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
365 [ + - ]: 6 : rWorld.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("World")));
366 : : }
367 : :
368 : : //See https://www.libreoffice.org/bugzilla/show_bug.cgi?id=45271
369 : : {
370 : 3 : const sal_Unicode IDEOGRAPHICFULLSTOP_D[] = { 0x3002, 'D' };
371 : :
372 : : m_pDoc->InsertString(aPaM, rtl::OUString(IDEOGRAPHICFULLSTOP_D,
373 [ + - ][ + - ]: 3 : SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D)));
[ + - ]
374 : :
375 [ + - ]: 3 : SvxLanguageItem aCJKLangItem( LANGUAGE_CHINESE_SIMPLIFIED, RES_CHRATR_CJK_LANGUAGE );
376 [ + - ]: 3 : SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
377 [ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 );
378 [ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 );
379 : :
380 [ + - ]: 3 : SwDocStat aDocStat;
381 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
382 [ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(IDEOGRAPHICFULLSTOP_D));
383 : :
384 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nChar == 2);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
385 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 2", aDocStat.nCharExcludingSpaces == 2);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
386 : : }
387 : : {
388 : : const sal_Unicode test[] =
389 : : {
390 : : 0x3053, 0x306E, 0x65E5, 0x672C, 0x8A9E, 0x306F, 0x6B63, 0x3057,
391 : : 0x304F, 0x6570, 0x3048, 0x3089, 0x308C, 0x308B, 0x3067, 0x3057,
392 : : 0x3087, 0x3046, 0x304B, 0x3002, 0x0041, 0x006E, 0x0064, 0x0020,
393 : : 0x006C, 0x0065, 0x0074, 0x0027, 0x0073, 0x0020, 0x0074, 0x0068,
394 : : 0x0072, 0x006F, 0x0077, 0x0020, 0x0073, 0x006F, 0x006D, 0x0065,
395 : : 0x0020, 0x0045, 0x006E, 0x0067, 0x006C, 0x0069, 0x0073, 0x0068,
396 : : 0x0020, 0x0069, 0x006E, 0x0020, 0x0074, 0x006F, 0x0020, 0x006D,
397 : : 0x0061, 0x006B, 0x0065, 0x0020, 0x0069, 0x0074, 0x0020, 0x0069,
398 : : 0x006E, 0x0074, 0x0065, 0x0072, 0x0065, 0x0073, 0x0074, 0x0069,
399 : : 0x006E, 0x0067, 0x002E, 0x0020, 0x0020, 0x305D, 0x3057, 0x3066,
400 : : 0x3001, 0x307E, 0x305F, 0x65E5, 0x672C, 0x8A9E, 0x3000, 0x3000,
401 : : 0x3067, 0x3082, 0x4ECA, 0x56DE, 0x306F, 0x7A7A, 0x767D, 0x3092,
402 : : 0x3000, 0x3000, 0x5165, 0x308C, 0x307E, 0x3057, 0x305F, 0x3002,
403 : : 0x0020, 0x0020, 0x0053, 0x006F, 0x0020, 0x0068, 0x006F, 0x0077,
404 : : 0x0020, 0x0064, 0x006F, 0x0065, 0x0073, 0x0020, 0x0074, 0x0068,
405 : : 0x0069, 0x0073, 0x0020, 0x0064, 0x006F, 0x003F, 0x0020, 0x0020
406 : 3 : };
407 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
408 : : m_pDoc->InsertString(aPaM, rtl::OUString(test,
409 [ + - ][ + - ]: 3 : SAL_N_ELEMENTS(test)));
[ + - ]
410 : :
411 [ + - ]: 3 : SvxLanguageItem aCJKLangItem( LANGUAGE_JAPANESE, RES_CHRATR_CJK_LANGUAGE );
412 [ + - ]: 3 : SvxLanguageItem aWestLangItem( LANGUAGE_ENGLISH_US, RES_CHRATR_LANGUAGE );
413 [ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, aCJKLangItem, 0 );
414 [ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, aWestLangItem, 0 );
415 : :
416 [ + - ]: 3 : SwDocStat aDocStat;
417 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
418 [ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(test));
419 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("58 words", aDocStat.nWord == 58);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
420 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("43 Asian characters and Korean syllables", aDocStat.nAsianWord == 43);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
421 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("105 non-whitespace chars", aDocStat.nCharExcludingSpaces == 105);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
422 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("128 characters", aDocStat.nChar == 128);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
423 : : }
424 : :
425 : : //See https://issues.apache.org/ooo/show_bug.cgi?id=89042
426 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=53399
427 : : {
428 [ + - ]: 3 : SwDocStat aDocStat;
429 : :
430 : : const sal_Unicode aShouldBeThree[] = {
431 : : 0x0053, 0x0068, 0x006F, 0x0075, 0x006C, 0x0064, 0x0020,
432 : : 0x2018, 0x0062, 0x0065, 0x0020, 0x0074, 0x0068, 0x0072,
433 : : 0x0065, 0x0065, 0x2019
434 : 3 : };
435 : :
436 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
437 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeThree, SAL_N_ELEMENTS(aShouldBeThree)));
[ + - ]
438 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
439 [ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeThree));
440 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 3", aDocStat.nWord == 3);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
441 : :
442 : : const sal_Unicode aShouldBeFive[] = {
443 : : // f r e n c h space
444 : : 0x0046, 0x0072, 0x0065, 0x006E, 0x0063, 0x0068, 0x0020,
445 : : // << nbsp s a v o i
446 : : 0x00AB, 0x00A0, 0x0073, 0x0061, 0x0076, 0x006F, 0x0069,
447 : : // r nnbsp c a l c u
448 : : 0x0072, 0x202f, 0x0063, 0x0061, 0x006C, 0x0063, 0x0075,
449 : : // l e r idspace >>
450 : : 0x006C, 0x0065, 0x0072, 0x3000, 0x00BB
451 : 3 : };
452 : :
453 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
454 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(aShouldBeFive, SAL_N_ELEMENTS(aShouldBeFive)));
[ + - ]
455 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
456 [ + - ]: 3 : aDocStat.Reset();
457 [ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, SAL_N_ELEMENTS(aShouldBeFive));
458 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 5", aDocStat.nWord == 5);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
459 : : }
460 : :
461 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=49629
462 : : {
463 [ + - ]: 3 : SwDocStat aDocStat;
464 : :
465 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
466 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString("Apple"));
[ + - ]
467 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
468 : 3 : xub_StrLen nPos = aPaM.GetPoint()->nContent.GetIndex();
469 [ + - ]: 3 : SwFmtFtn aFtn;
470 [ + - ][ + - ]: 3 : aFtn.SetNumStr(rtl::OUString("banana"));
[ + - ]
471 [ + - ]: 3 : SwTxtAttr* pTA = pTxtNode->InsertItem(aFtn, nPos, nPos);
472 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTA);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
473 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTxtNode->Len() == 6); //Apple + 0x02
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
474 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
475 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(aDocStat.nWord == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
476 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("footnote should be expanded", aDocStat.nChar == 11);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
477 : :
478 : 3 : xub_StrLen nNextPos = aPaM.GetPoint()->nContent.GetIndex();
479 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(nNextPos == nPos+1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
480 [ + - ][ + - ]: 3 : SwFmtRefMark aRef(rtl::OUString("refmark"));
[ + - ]
481 [ + - ]: 3 : pTA = pTxtNode->InsertItem(aRef, nNextPos, nNextPos);
482 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTA);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
483 : :
484 [ + - ]: 3 : aDocStat.Reset();
485 [ + - ]: 3 : pTxtNode->SetWordCountDirty(true);
486 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
487 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(aDocStat.nWord == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
488 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("refmark anchor should not be counted", aDocStat.nChar == 11);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
489 : :
490 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
491 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString("Apple"));
[ + - ]
492 : :
493 [ + - ]: 3 : DateTime aDate(DateTime::SYSTEM);
494 : : SwPostItField aPostIt(
495 [ + - ]: 3 : (SwPostItFieldType*)m_pDoc->GetSysFldType(RES_POSTITFLD), rtl::OUString("An Author"),
496 [ + - ][ + - ]: 6 : rtl::OUString("Some Text"), rtl::OUString("Initials"), OUString("Name"), aDate );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
497 [ + - ][ + - ]: 3 : m_pDoc->InsertPoolItem(aPaM, SwFmtFld(aPostIt), 0);
[ + - ]
498 : :
499 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString("Apple"));
[ + - ]
500 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
501 [ + - ]: 3 : aDocStat.Reset();
502 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
503 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(aDocStat.nWord == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
504 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("postit anchor should effectively not exist", aDocStat.nChar == 10);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
505 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTxtNode->Len() == 11);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
506 : :
507 [ + - ][ + - ]: 3 : aDocStat.Reset();
[ + - ][ + - ]
508 : : }
509 : :
510 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=46757
511 : : {
512 [ + - ]: 3 : SwDocStat aDocStat;
513 : :
514 : 3 : const char aString[] = "Lorem ipsum";
515 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
516 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(aString));
[ + - ]
517 : 3 : pTxtNode = aPaM.GetNode()->GetTxtNode();
518 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len());
519 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(2));
[ + - ][ + - ]
[ + - ]
520 : :
521 : : //turn on red-lining and show changes
522 [ + - ]: 3 : m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE|nsRedlineMode_t::REDLINE_SHOW_INSERT);
523 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlining should be on", m_pDoc->IsRedlineOn());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
524 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlines should be visible", IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode()));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
525 : :
526 : : //delete everything except the first word
527 [ + - ]: 3 : aPaM.SetMark(); //set start of selection to current pos
528 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), 5); //set end of selection to fifth char of current node
529 [ + - ]: 3 : m_pDoc->DeleteAndJoin(aPaM); //redline-aware deletion api
530 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("real underlying text should be the same", pTxtNode->GetTxt().EqualsAscii(aString));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
531 : :
532 [ + - ]: 3 : aDocStat.Reset();
533 [ + - ]: 3 : pTxtNode->SetWordCountDirty(true);
534 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text
535 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(1));
[ + - ][ + - ]
[ + - ]
536 : :
537 [ + - ]: 3 : pTxtNode->SetWordCountDirty(true);
538 : :
539 : : //keep red-lining on but hide changes
540 [ + - ]: 3 : m_pDoc->SetRedlineMode(nsRedlineMode_t::REDLINE_ON);
541 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlining should be still on", m_pDoc->IsRedlineOn());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
542 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("redlines should be invisible", !IDocumentRedlineAccess::IsShowChanges(m_pDoc->GetRedlineMode()));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
543 : :
544 [ + - ]: 3 : aDocStat.Reset();
545 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //but word-counting the text should only count the non-deleted text
546 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(1));
[ + - ][ + - ]
[ + - ]
547 : :
548 [ + - ]: 3 : rtl::OUString sLorem = pTxtNode->GetTxt();
549 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sLorem == "Lorem");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
550 : :
551 [ + - ]: 3 : const SwRedlineTbl& rTbl = m_pDoc->GetRedlineTbl();
552 : :
553 [ + - ]: 3 : SwNodes& rNds = m_pDoc->GetNodes();
554 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(rTbl.size() == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
555 : :
556 [ + - ]: 3 : SwNodeIndex* pNodeIdx = rTbl[0]->GetContentIdx();
557 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pNodeIdx);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
558 : :
559 [ + - ]: 3 : pTxtNode = rNds[ pNodeIdx->GetIndex() + 1 ]->GetTxtNode(); //first deleted txtnode
560 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(pTxtNode);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
561 : :
562 [ + - ]: 3 : rtl::OUString sIpsum = pTxtNode->GetTxt();
563 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT(sIpsum == " ipsum");
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
564 : :
565 [ + - ]: 3 : aDocStat.Reset();
566 [ + - ][ + - ]: 3 : pTxtNode->CountWords(aDocStat, 0, pTxtNode->Len()); //word-counting the text should only count the non-deleted text, and this whole chunk should be ignored
567 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_EQUAL(aDocStat.nWord, static_cast<sal_uLong>(0));
[ + - ][ + - ]
[ + - ]
568 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_EQUAL(aDocStat.nChar, static_cast<sal_uLong>(0));
[ + - ][ + - ]
[ + - ]
569 [ + - ][ + - ]: 3 : }
570 : 3 : }
571 : :
572 : : //See https://bugs.freedesktop.org/show_bug.cgi?id=40599
573 : 3 : void SwDocTest::testGraphicAnchorDeletion()
574 : : {
575 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected initial 0 count", m_pDoc->GetDocStat().nChar == 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
576 : :
577 [ + - ][ + - ]: 3 : SwNodeIndex aIdx(m_pDoc->GetNodes().GetEndOfContent(), -1);
578 [ + - ]: 3 : SwPaM aPaM(aIdx);
579 : :
580 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 1")));
[ + - ][ + - ]
581 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
582 : :
583 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("graphic anchor>><<graphic anchor")));
[ + - ][ + - ]
584 [ + - ]: 3 : SwNodeIndex nPara2 = aPaM.GetPoint()->nNode;
585 [ + - ]: 3 : m_pDoc->AppendTxtNode(*aPaM.GetPoint());
586 : :
587 [ + - ][ + - ]: 3 : m_pDoc->InsertString(aPaM, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Paragraph 3")));
[ + - ][ + - ]
588 : :
589 [ + - ]: 3 : aPaM.GetPoint()->nNode = nPara2;
590 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>>"));
591 : :
592 : : //Insert a graphic at X of >>X<< in paragraph 2
593 [ + - ]: 3 : SfxItemSet aFlySet(m_pDoc->GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
594 [ + - ]: 3 : SwFmtAnchor aAnchor(FLY_AS_CHAR);
595 [ + - ]: 3 : aAnchor.SetAnchor(aPaM.GetPoint());
596 [ + - ]: 3 : aFlySet.Put(aAnchor);
597 [ + - ][ + - ]: 3 : SwFlyFrmFmt *pFrame = m_pDoc->Insert(aPaM, rtl::OUString(), rtl::OUString(), NULL, &aFlySet, NULL, NULL);
[ + - ][ + - ]
[ + - ]
598 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Expected frame", pFrame != NULL);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
599 : :
600 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 1 graphic", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 1);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
601 : :
602 : : //Delete >X<
603 [ + - ]: 3 : aPaM.GetPoint()->nNode = nPara2;
604 : 6 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(),
605 [ + - ][ + - ]: 6 : RTL_CONSTASCII_LENGTH("graphic anchor>><")+1);
606 [ + - ]: 3 : aPaM.SetMark();
607 [ + - ]: 3 : aPaM.GetPoint()->nNode = nPara2;
608 [ + - ][ + - ]: 3 : aPaM.GetPoint()->nContent.Assign(aPaM.GetCntntNode(), RTL_CONSTASCII_LENGTH("graphic anchor>"));
609 [ + - ]: 3 : m_pDoc->DeleteRange(aPaM);
610 : :
611 : : #ifdef DEBUG_AS_HTML
612 : : {
613 : : SvFileStream aPasteDebug(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
614 : : "cppunitDEBUG.html")), STREAM_WRITE|STREAM_TRUNC);
615 : : WriterRef xWrt;
616 : : GetHTMLWriter( String(), String(), xWrt );
617 : : SwWriter aDbgWrt( aPasteDebug, *m_pDoc );
618 : : aDbgWrt.Write( xWrt );
619 : : }
620 : : #endif
621 : :
622 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("Should be 0 graphics", m_pDoc->GetFlyCount(FLYCNTTYPE_GRF) == 0);
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
623 : :
624 : : //Now, if instead we swap FLY_AS_CHAR (inline graphic) to FLY_AT_CHAR (anchored to character)
625 : : //and repeat the above, graphic is *not* deleted, i.e. it belongs to the paragraph, not the
626 : : //range to which its anchored, which is annoying.
627 : 3 : }
628 : :
629 : : static int
630 : 109532 : getRand(int modulus)
631 : : {
632 [ - + ]: 109532 : if (modulus <= 0)
633 : 0 : return 0;
634 : 109532 : return rand() % modulus;
635 : : }
636 : :
637 : : static rtl::OUString
638 : 12103 : getRandString()
639 : : {
640 : 12103 : rtl::OUString aText("AAAAA BBBB CCC DD E \n");
641 : 12103 : int s = getRand(aText.getLength());
642 : 12103 : int j = getRand(aText.getLength() - s);
643 : 12103 : rtl::OUString aRet(aText.copy(s, j));
644 [ + + ]: 12103 : if (!getRand(5))
645 : 2468 : aRet += rtl::OUString(sal_Unicode('\n'));
646 : : // fprintf (stderr, "rand string '%s'\n", OUStringToOString(aRet, RTL_TEXTENCODING_UTF8).getStr());
647 : 12103 : return aRet;
648 : : }
649 : :
650 : : static SwPosition
651 : 55730 : getRandomPosition(SwDoc *pDoc, int /* nOffset */)
652 : : {
653 [ + - ][ + - ]: 55730 : const SwPosition aPos(pDoc->GetNodes().GetEndOfContent());
654 : 55730 : sal_uLong nNodes = aPos.nNode.GetNode().GetIndex() - aPos.nNode.GetNode().StartOfSectionIndex();
655 : 55730 : sal_uLong n = (rand() * nNodes) / RAND_MAX;
656 [ + - ]: 55730 : SwPaM pam(aPos);
657 [ + + ]: 83542 : for (sal_uLong i = 0; i < n; ++i) {
658 [ + - ]: 27812 : pam.Move(fnMoveBackward, fnGoNode);
659 : : }
660 [ + - ][ + - ]: 55730 : return *pam.GetPoint();
[ + - ]
661 : : }
662 : :
663 : 3 : void SwDocTest::randomTest()
664 : : {
665 [ + - ][ + - ]: 3 : CPPUNIT_ASSERT_MESSAGE("SwDoc::IsRedlineOn()", !m_pDoc->IsRedlineOn());
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
666 : : RedlineMode_t modes[] = {
667 : : nsRedlineMode_t::REDLINE_ON,
668 : : nsRedlineMode_t::REDLINE_SHOW_MASK,
669 : : nsRedlineMode_t::REDLINE_NONE,
670 : : nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_MASK,
671 : : nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE,
672 : : nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_IGNORE | nsRedlineMode_t::REDLINE_SHOW_MASK,
673 : : nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT,
674 : : nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_DELETE
675 : 3 : };
676 : : static const char *authors[] = {
677 : : "Jim", "Bob", "JimBobina", "Helga", "Gertrude", "Spagna", "Hurtleweed"
678 : : };
679 : :
680 [ + + ]: 27 : for( sal_uInt16 rlm = 0; rlm < SAL_N_ELEMENTS(modes); rlm++ )
681 : : {
682 [ + - ]: 24 : m_pDoc->ClearDoc();
683 : :
684 : : // setup redlining
685 [ + - ]: 24 : m_pDoc->SetRedlineMode(modes[rlm]);
686 [ + - ][ + - ]: 24 : SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[0]));
[ + - ][ + - ]
687 : :
688 [ + + ]: 48024 : for( int i = 0; i < 2000; i++ )
689 : : {
690 [ + - ][ + - ]: 48000 : SwPaM aPam(m_pDoc->GetNodes());
[ + - ][ + - ]
691 [ + - ][ + - ]: 48000 : SwCursor aCrs(getRandomPosition(m_pDoc, i/20), 0, false);
[ + - ]
692 [ + - ]: 48000 : aCrs.SetMark();
693 : :
694 [ + + ][ + + : 48000 : switch (getRand (i < 50 ? 3 : 6)) {
+ + + +
- ]
695 : : // insert ops first
696 : : case 0: {
697 [ + - ][ + - ]: 8183 : if (!m_pDoc->InsertString(aCrs, getRandString())) {
[ + - ][ + - ]
698 : : // fprintf (stderr, "failed to insert string !\n");
699 : : }
700 : 8183 : break;
701 : : }
702 : : case 1:
703 : 8193 : break;
704 : : case 2: { // switch author
705 : 8338 : int a = getRand(SAL_N_ELEMENTS(authors));
706 [ + - ][ + - ]: 8338 : SW_MOD()->SetRedlineAuthor(rtl::OUString::createFromAscii(authors[a]));
[ + - ][ + - ]
707 : 8338 : break;
708 : : }
709 : :
710 : : // movement / deletion ops later
711 : : case 3: // deletion
712 [ + + + + ]: 7821 : switch (getRand(6)) {
713 : : case 0:
714 [ + - ]: 1246 : m_pDoc->DelFullPara(aCrs);
715 : 1246 : break;
716 : : case 1:
717 [ + - ]: 1321 : m_pDoc->DeleteRange(aCrs);
718 : 1321 : break;
719 : : case 2:
720 [ + - ]: 1334 : m_pDoc->DeleteAndJoin(aCrs, !!getRand(1));
721 : 1334 : break;
722 : : case 3:
723 : : default:
724 [ + - ][ + - ]: 3920 : m_pDoc->Overwrite(aCrs, getRandString());
[ + - ][ + - ]
725 : 3920 : break;
726 : : }
727 : 7821 : break;
728 : : case 4: { // movement
729 : : IDocumentContentOperations::SwMoveFlags nFlags =
730 : : (IDocumentContentOperations::SwMoveFlags)
731 : 7730 : (getRand(1) ? // FIXME: puterb this more ?
732 : : IDocumentContentOperations::DOC_MOVEDEFAULT :
733 : : IDocumentContentOperations::DOC_MOVEALLFLYS |
734 : : IDocumentContentOperations::DOC_CREATEUNDOOBJ |
735 : : IDocumentContentOperations::DOC_MOVEREDLINES |
736 [ - + ]: 7730 : IDocumentContentOperations::DOC_NO_DELFRMS);
737 [ + - ]: 7730 : SwPosition aTo(getRandomPosition(m_pDoc, i/10));
738 [ + - ]: 7730 : m_pDoc->MoveRange(aCrs, aTo, nFlags);
739 [ + - ]: 7730 : break;
740 : : }
741 : :
742 : : case 5:
743 : 7735 : break;
744 : :
745 : : // undo / redo ?
746 : : default:
747 : 0 : break;
748 : : }
749 [ + - ][ + - ]: 48000 : }
750 : :
751 : : // Debug / verify the produced document has real content
752 : : #if 0
753 : : rtl::OStringBuffer aBuffer("nodes-");
754 : : aBuffer.append(sal_Int32(rlm));
755 : : aBuffer.append(".xml");
756 : :
757 : : xmlTextWriterPtr writer;
758 : : writer = xmlNewTextWriterFilename( aBuffer.makeStringAndClear().getStr(), 0 );
759 : : xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
760 : : m_pDoc->dumpAsXml(writer);
761 : : xmlTextWriterEndDocument( writer );
762 : : xmlFreeTextWriter( writer );
763 : : #endif
764 : : }
765 : 3 : }
766 : :
767 : 24 : void SwDocTest::setUp()
768 : : {
769 : 24 : BootstrapFixture::setUp();
770 : :
771 : 24 : SwGlobals::ensure();
772 [ + - ]: 24 : m_pDoc = new SwDoc;
773 [ + - ]: 24 : m_xDocShRef = new SwDocShell(m_pDoc, SFX_CREATE_MODE_EMBEDDED);
774 : 24 : m_xDocShRef->DoInitNew(0);
775 : 24 : }
776 : :
777 : 24 : void SwDocTest::tearDown()
778 : : {
779 : 24 : m_xDocShRef.Clear();
780 [ + - ]: 24 : delete m_pDoc;
781 : :
782 : 24 : BootstrapFixture::tearDown();
783 : 24 : }
784 : :
785 : 3 : CPPUNIT_TEST_SUITE_REGISTRATION(SwDocTest);
786 : :
787 [ + - ][ + - ]: 12 : CPPUNIT_PLUGIN_IMPLEMENT();
[ + - ][ + - ]
[ + - ][ # # ]
788 : :
789 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|