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/style/XStyleFamiliesSupplier.hpp>
30 : #include <com/sun/star/text/XTextDocument.hpp>
31 : #include <com/sun/star/text/XTextRange.hpp>
32 :
33 : #include <test/bootstrapfixture.hxx>
34 : #include <unotest/macros_test.hxx>
35 : #include <rtl/ustrbuf.hxx>
36 :
37 : #include <unotxdoc.hxx>
38 : #include <docsh.hxx>
39 : #include <doc.hxx>
40 : #include <rootfrm.hxx>
41 :
42 : #include <libxml/xmlwriter.h>
43 : #include <libxml/xpath.h>
44 :
45 : using namespace com::sun::star;
46 :
47 : #define DEFAULT_STYLE "Default Style"
48 :
49 : /// Base class for filter tests loading or roundtriping a document, then asserting the document model.
50 : class SwModelTestBase : public test::BootstrapFixture, public unotest::MacrosTest
51 : {
52 : public:
53 16 : SwModelTestBase()
54 16 : : mpXmlBuffer(0)
55 : {
56 16 : }
57 :
58 16 : ~SwModelTestBase()
59 32 : {
60 16 : if (mpXmlBuffer)
61 10 : xmlBufferFree(mpXmlBuffer);
62 16 : }
63 :
64 16 : virtual void setUp()
65 : {
66 16 : test::BootstrapFixture::setUp();
67 :
68 16 : mxDesktop.set(getMultiServiceFactory()->createInstance("com.sun.star.frame.Desktop"), uno::UNO_QUERY);
69 16 : CPPUNIT_ASSERT(mxDesktop.is());
70 16 : }
71 :
72 16 : virtual void tearDown()
73 : {
74 16 : if (mxComponent.is())
75 16 : mxComponent->dispose();
76 :
77 16 : test::BootstrapFixture::tearDown();
78 16 : }
79 :
80 : private:
81 10 : void dumpLayout()
82 : {
83 : // create the xml writer
84 10 : mpXmlBuffer = xmlBufferCreate();
85 10 : xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(mpXmlBuffer, 0);
86 10 : xmlTextWriterStartDocument(pXmlWriter, NULL, NULL, NULL);
87 :
88 : // create the dump
89 10 : SwXTextDocument* pTxtDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
90 10 : SwDoc* pDoc = pTxtDoc->GetDocShell()->GetDoc();
91 10 : SwRootFrm* pLayout = pDoc->GetCurrentLayout();
92 10 : pLayout->dumpAsXml(pXmlWriter);
93 :
94 : // delete xml writer
95 10 : xmlTextWriterEndDocument(pXmlWriter);
96 10 : xmlFreeTextWriter(pXmlWriter);
97 10 : }
98 :
99 :
100 : protected:
101 : /// Get the length of the whole document.
102 18 : int getLength()
103 : {
104 18 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
105 18 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
106 18 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
107 18 : OUStringBuffer aBuf;
108 56 : while (xParaEnum->hasMoreElements())
109 : {
110 20 : uno::Reference<container::XEnumerationAccess> xRangeEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
111 20 : uno::Reference<container::XEnumeration> xRangeEnum = xRangeEnumAccess->createEnumeration();
112 68 : while (xRangeEnum->hasMoreElements())
113 : {
114 28 : uno::Reference<text::XTextRange> xRange(xRangeEnum->nextElement(), uno::UNO_QUERY);
115 28 : aBuf.append(xRange->getString());
116 28 : }
117 20 : }
118 18 : return aBuf.getLength();
119 : }
120 :
121 : /// Get a family of styles, see com.sun.star.style.StyleFamilies for possible values.
122 30 : uno::Reference<container::XNameAccess> getStyles(OUString aFamily)
123 : {
124 30 : uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(mxComponent, uno::UNO_QUERY);
125 30 : uno::Reference<container::XNameAccess> xStyleFamilies(xStyleFamiliesSupplier->getStyleFamilies(), uno::UNO_QUERY);
126 30 : uno::Reference<container::XNameAccess> xStyleFamily(xStyleFamilies->getByName(aFamily), uno::UNO_QUERY);
127 30 : return xStyleFamily;
128 : }
129 :
130 : /**
131 : * Extract a value from the layout dump using an XPath expression and an attribute name.
132 : *
133 : * If the attribute is omitted, the text of the node is returned.
134 : */
135 102 : OUString parseDump(rtl::OString aXPath, rtl::OString aAttribute = OString())
136 : {
137 102 : if (!mpXmlBuffer)
138 10 : dumpLayout();
139 :
140 102 : xmlDocPtr pXmlDoc = xmlParseMemory((const char*)xmlBufferContent(mpXmlBuffer), xmlBufferLength(mpXmlBuffer));;
141 :
142 102 : xmlXPathContextPtr pXmlXpathCtx = xmlXPathNewContext(pXmlDoc);
143 102 : xmlXPathObjectPtr pXmlXpathObj = xmlXPathEvalExpression(BAD_CAST(aXPath.getStr()), pXmlXpathCtx);
144 102 : xmlNodeSetPtr pXmlNodes = pXmlXpathObj->nodesetval;
145 102 : CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlNodes));
146 102 : xmlNodePtr pXmlNode = pXmlNodes->nodeTab[0];
147 102 : OUString aRet;
148 102 : if (aAttribute.getLength())
149 4 : aRet = OUString::createFromAscii((const char*)xmlGetProp(pXmlNode, BAD_CAST(aAttribute.getStr())));
150 : else
151 98 : aRet = OUString::createFromAscii((const char*)XML_GET_CONTENT(pXmlNode));
152 :
153 102 : xmlFreeDoc(pXmlDoc);
154 :
155 102 : return aRet;
156 : }
157 :
158 : template< typename T >
159 96 : T getProperty( uno::Any obj, const OUString& name ) const
160 : {
161 96 : uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
162 96 : T data = T();
163 96 : properties->getPropertyValue( name ) >>= data;
164 96 : return data;
165 : }
166 :
167 : template< typename T >
168 630 : T getProperty( uno::Reference< uno::XInterface > obj, const OUString& name ) const
169 : {
170 630 : uno::Reference< beans::XPropertySet > properties( obj, uno::UNO_QUERY );
171 630 : T data = T();
172 630 : properties->getPropertyValue( name ) >>= data;
173 630 : return data;
174 : }
175 :
176 : /// Get number of paragraphs of the document.
177 2 : int getParagraphs()
178 : {
179 2 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
180 2 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
181 2 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
182 2 : int nRet = 0;
183 8 : while (xParaEnum->hasMoreElements())
184 : {
185 4 : xParaEnum->nextElement();
186 4 : nRet++;
187 : }
188 2 : return nRet;
189 : }
190 :
191 : // Get paragraph (counted from 1), optionally check it contains the given text.
192 300 : uno::Reference< text::XTextRange > getParagraph( int number, OUString content = OUString() ) const
193 : {
194 300 : uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
195 300 : uno::Reference<container::XEnumerationAccess> paraEnumAccess(textDocument->getText(), uno::UNO_QUERY);
196 300 : uno::Reference<container::XEnumeration> paraEnum = paraEnumAccess->createEnumeration();
197 494 : for( int i = 1;
198 : i < number;
199 : ++i )
200 194 : paraEnum->nextElement();
201 300 : uno::Reference< text::XTextRange > paragraph( paraEnum->nextElement(), uno::UNO_QUERY );
202 300 : if( !content.isEmpty())
203 20 : CPPUNIT_ASSERT_EQUAL( content, paragraph->getString());
204 300 : return paragraph;
205 : }
206 :
207 : /// Get run (counted from 1) of a paragraph, optionally check it contains the given text.
208 292 : uno::Reference<text::XTextRange> getRun(uno::Reference<text::XTextRange> xParagraph, int number, OUString content = OUString()) const
209 : {
210 292 : uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParagraph, uno::UNO_QUERY);
211 292 : uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
212 612 : for (int i = 1; i < number; ++i)
213 320 : xRunEnum->nextElement();
214 292 : uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
215 292 : if( !content.isEmpty())
216 30 : CPPUNIT_ASSERT_EQUAL( content, xRun->getString());
217 292 : return xRun;
218 : }
219 :
220 : /// Get math formula string of a run.
221 218 : OUString getFormula(uno::Reference<text::XTextRange> xRun) const
222 : {
223 218 : uno::Reference<container::XContentEnumerationAccess> xContentEnumAccess(xRun, uno::UNO_QUERY);
224 218 : uno::Reference<container::XEnumeration> xContentEnum(xContentEnumAccess->createContentEnumeration(""), uno::UNO_QUERY);
225 218 : uno::Reference<beans::XPropertySet> xFormula(xContentEnum->nextElement(), uno::UNO_QUERY);
226 218 : return getProperty<OUString>(getProperty< uno::Reference<beans::XPropertySet> >(xFormula, "Model"), "Formula");
227 : }
228 :
229 : uno::Reference<lang::XComponent> mxComponent;
230 : xmlBufferPtr mpXmlBuffer;
231 :
232 : template< typename T >
233 : struct MethodEntry
234 : {
235 : const char* pName;
236 : void (T::*pMethod)();
237 : };
238 : };
239 :
240 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|