Line data Source code
1 : /*
2 : * Version: MPL 1.1 / GPLv3+ / LGPLv3+
3 : *
4 : * The contents of this file are subject to the Mozilla Public License Version
5 : * 1.1 (the "License"); you may not use this file except in compliance with
6 : * the License. You may obtain a copy of the License at
7 : * http://www.mozilla.org/MPL/
8 : *
9 : * Software distributed under the License is distributed on an "AS IS" basis,
10 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 : * for the specific language governing rights and limitations under the
12 : * License.
13 : *
14 : * The Initial Developer of the Original Code is
15 : * Miklos Vajna <vmiklos@suse.cz> (SUSE, Inc.)
16 : * Portions created by the Initial Developer are Copyright (C) 2012 the
17 : * Initial Developer. All Rights Reserved.
18 : *
19 : * Contributor(s):
20 : *
21 : * Alternatively, the contents of this file may be used under the terms of
22 : * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
23 : * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
24 : * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
25 : * instead of those above.
26 : */
27 :
28 : #include <com/sun/star/container/XContentEnumerationAccess.hpp>
29 : #include <com/sun/star/frame/Desktop.hpp>
30 : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
31 : #include <com/sun/star/text/XTextDocument.hpp>
32 : #include <com/sun/star/text/XTextRange.hpp>
33 :
34 : #include <test/bootstrapfixture.hxx>
35 : #include <unotest/macros_test.hxx>
36 : #include <rtl/ustrbuf.hxx>
37 : #include <comphelper/processfactory.hxx>
38 : #include <unotools/tempfile.hxx>
39 :
40 : #include <unotxdoc.hxx>
41 : #include <docsh.hxx>
42 : #include <doc.hxx>
43 : #include <rootfrm.hxx>
44 :
45 : #include <libxml/xmlwriter.h>
46 : #include <libxml/xpath.h>
47 :
48 : using namespace com::sun::star;
49 :
50 : #define DEFAULT_STYLE "Default Style"
51 :
52 : /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
53 : class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest
54 : {
55 : public:
56 8 : SwModelTestBase()
57 8 : : mpXmlBuffer(0)
58 : {
59 8 : }
60 :
61 8 : ~SwModelTestBase()
62 16 : {
63 8 : if (mpXmlBuffer)
64 5 : xmlBufferFree(mpXmlBuffer);
65 8 : }
66 :
67 8 : virtual void setUp()
68 : {
69 8 : test::BootstrapFixture::setUp();
70 :
71 8 : mxDesktop.set( com::sun::star::frame::Desktop::create(comphelper::getComponentContext(getMultiServiceFactory())) );
72 8 : }
73 :
74 8 : virtual void tearDown()
75 : {
76 8 : if (mxComponent.is())
77 8 : mxComponent->dispose();
78 :
79 8 : test::BootstrapFixture::tearDown();
80 8 : }
81 :
82 : private:
83 5 : void dumpLayout()
84 : {
85 : // create the xml writer
86 5 : mpXmlBuffer = xmlBufferCreate();
87 5 : xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(mpXmlBuffer, 0);
88 5 : xmlTextWriterStartDocument(pXmlWriter, NULL, NULL, NULL);
89 :
90 : // create the dump
91 5 : SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
92 5 : SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
93 5 : SwRootFrm* pLayout = pDoc->GetCurrentLayout();
94 5 : pLayout->dumpAsXml(pXmlWriter);
95 :
96 : // delete xml writer
97 5 : xmlTextWriterEndDocument(pXmlWriter);
98 5 : xmlFreeTextWriter(pXmlWriter);
99 5 : }
100 :
101 :
102 : protected:
103 : /// Get the length of the whole document.
104 9 : int getLength()
105 : {
106 9 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
107 9 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
108 9 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
109 9 : OUStringBuffer aBuf;
110 28 : while (xParaEnum->hasMoreElements())
111 : {
112 10 : uno::Reference<container::XEnumerationAccess> xRangeEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
113 10 : uno::Reference<container::XEnumeration> xRangeEnum = xRangeEnumAccess->createEnumeration();
114 34 : while (xRangeEnum->hasMoreElements())
115 : {
116 14 : uno::Reference<text::XTextRange> xRange(xRangeEnum->nextElement(), uno::UNO_QUERY);
117 14 : aBuf.append(xRange->getString());
118 14 : }
119 10 : }
120 9 : return aBuf.getLength();
121 : }
122 :
123 : /// Get a family of styles, see com.sun.star.style.StyleFamilies for possible values.
124 18 : uno::Reference<container::XNameAccess> getStyles(OUString aFamily)
125 : {
126 18 : uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
127 18 : uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
128 18 : uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(aFamily), uno::UNO_QUERY);
129 18 : return xStyleFamily;
130 : }
131 :
132 : /**
133 : * Extract a value from the layout dump using an XPath expression and an attribute name.
134 : *
135 : * If the attribute is omitted, the text of the node is returned.
136 : */
137 51 : OUString parseDump(rtl::OString aXPath, rtl::OString aAttribute = OString())
138 : {
139 51 : if (!mpXmlBuffer)
140 5 : dumpLayout();
141 :
142 51 : xmlDocPtr pXmlDoc = xmlParseMemory((const char*)xmlBufferContent(mpXmlBuffer), xmlBufferLength(mpXmlBuffer));;
143 :
144 51 : xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
145 51 : xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(aXPath.getStr()), pXmlXpathCtx);
146 51 : xmlNodeSetPtr pXmlNodes = pXmlXpathObj->nodesetval;
147 51 : CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlNodes));
148 51 : xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
149 51 : OUString aRet;
150 51 : if (aAttribute.getLength())
151 2 : aRet = OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(aAttribute.getStr())));
152 : else
153 49 : aRet = OUString::createFromAscii((const char*)XML_GET_CONTENT(pXmlNode));
154 :
155 51 : xmlFreeDoc(pXmlDoc);
156 :
157 51 : return aRet;
158 : }
159 :
160 : template< typename T >
161 48 : T getProperty( uno::Any obj, const OUString& name ) const
162 : {
163 48 : uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
164 48 : T data = T();
165 48 : properties->getPropertyValue( name ) >>= data;
166 48 : return data;
167 : }
168 :
169 : template< typename T >
170 322 : T getProperty( uno::Reference< uno::XInterface > obj, const OUString& name ) const
171 : {
172 322 : uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
173 322 : T data = T();
174 322 : properties->getPropertyValue( name ) >>= data;
175 322 : return data;
176 : }
177 :
178 : /// Get number of paragraphs of the document.
179 1 : int getParagraphs()
180 : {
181 1 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
182 1 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
183 1 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
184 1 : int nRet = 0;
185 4 : while (xParaEnum->hasMoreElements())
186 : {
187 2 : xParaEnum->nextElement();
188 2 : nRet++;
189 : }
190 1 : return nRet;
191 : }
192 :
193 : // Get paragraph (counted from 1), optionally check it contains the given text.
194 150 : uno::Reference< text::XTextRange > getParagraph( int number, OUString content = OUString() ) const
195 : {
196 150 : uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
197 150 : uno::Reference<container::XEnumerationAccess> paraEnumAccess(textDocument->getText(), uno::UNO_QUERY);
198 150 : uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
199 246 : for( int i = 1;
200 : i < number;
201 : ++i )
202 96 : paraEnum->nextElement();
203 150 : uno::Reference< text::XTextRange > paragraph( paraEnum->nextElement(), uno::UNO_QUERY );
204 150 : if( !content.isEmpty())
205 9 : CPPUNIT_ASSERT_EQUAL( content, paragraph->getString());
206 150 : return paragraph;
207 : }
208 :
209 : /// Get run (counted from 1) of a paragraph, optionally check it contains the given text.
210 147 : uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, OUString content = OUString()) const
211 : {
212 147 : uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY);
213 147 : uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
214 307 : for (int i = 1; i < number; ++i)
215 160 : xRunEnum->nextElement();
216 147 : uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
217 147 : if( !content.isEmpty())
218 15 : CPPUNIT_ASSERT_EQUAL( content, xRun->getString());
219 147 : return xRun;
220 : }
221 :
222 : /// Get math formula string of a run.
223 110 : OUString getFormula(uno::Reference<text::XTextRange> xRun) const
224 : {
225 110 : uno::Reference<container::XContentEnumerationAccess> xContentEnumAccess(xRun, uno::UNO_QUERY);
226 110 : uno::Reference<container::XEnumeration> xContentEnum(xContentEnumAccess->createContentEnumeration(""), uno::UNO_QUERY);
227 110 : uno::Reference<beans::XPropertySet> xFormula(xContentEnum->nextElement(), uno::UNO_QUERY);
228 110 : return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
229 : }
230 :
231 8 : void header()
232 : {
233 8 : fprintf(stderr, "File tested,Execution Time (ms)\n");
234 8 : }
235 :
236 185 : void load(const char* pDir, const char* pName)
237 : {
238 : // Output name early, so in the case of a hang, the name of the hanging input file is visible.
239 185 : fprintf(stderr, "%s,", pName);
240 185 : m_nStartTime = osl_getGlobalTimer();
241 185 : mxComponent = loadFromDesktop(getURLFromSrc(pDir) + OUString::createFromAscii(pName));
242 185 : }
243 :
244 59 : void reload(OUString aFilter)
245 : {
246 59 : uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
247 59 : uno::Sequence<beans::PropertyValue> aArgs(1);
248 59 : aArgs[0].Name = "FilterName";
249 59 : aArgs[0].Value <<= aFilter;
250 59 : utl::TempFile aTempFile;
251 59 : aTempFile.EnableKillingFile();
252 59 : xStorable->storeToURL(aTempFile.GetURL(), aArgs);
253 59 : uno::Reference<lang::XComponent> xComponent(xStorable, uno::UNO_QUERY);
254 59 : xComponent->dispose();
255 59 : mxComponent = loadFromDesktop(aTempFile.GetURL());
256 59 : }
257 :
258 185 : void finish()
259 : {
260 185 : sal_uInt32 nEndTime = osl_getGlobalTimer();
261 185 : fprintf(stderr, "%" SAL_PRIuUINT32"\n", nEndTime - m_nStartTime);
262 185 : }
263 :
264 : uno::Reference<lang::XComponent> mxComponent;
265 : xmlBufferPtr mpXmlBuffer;
266 :
267 : template< typename T >
268 : struct MethodEntry
269 : {
270 : const char* pName;
271 : void (T::*pMethod)();
272 : };
273 : sal_uInt32 m_nStartTime;
274 : };
275 :
276 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|