1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // autogenerated file with codegen.pl 25 26 #include "gtest/gtest.h" 27 28 #include <rtl/ref.hxx> 29 #include <osl/file.hxx> 30 #include <osl/process.h> 31 #include <comphelper/seqstream.hxx> 32 #include <comphelper/sequence.hxx> 33 #include <cppuhelper/compbase1.hxx> 34 #include <cppuhelper/bootstrap.hxx> 35 #include <cppuhelper/basemutex.hxx> 36 37 #include <com/sun/star/xml/sax/FastToken.hpp> 38 #include <com/sun/star/xml/sax/XSAXSerializable.hpp> 39 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp> 40 41 #include <cstdlib> 42 43 #include "../source/dom/documentbuilder.hxx" 44 45 46 using namespace ::DOM; 47 using namespace ::comphelper; 48 using namespace ::com::sun::star; 49 50 namespace 51 { 52 53 // valid xml 54 static const char validTestFile[] = 55 "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \ 56 <office:document-content \ 57 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 58 xmlns:xlink=\"http://www.w3.org/1999/xlink\" \ 59 office:version=\"1.0\"> \ 60 <office:scripts/> \ 61 <xlink:test/> \ 62 <office:automatic-styles teststyle=\"test\"/> \ 63 <moretest/> \ 64 some text öäü \ 65 </office:document-content> \ 66 "; 67 68 // generates a warning: unsupported xml version, unknown xml:space 69 // value 70 static const char warningTestFile[] = 71 "<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \ 72 <office:document-content \ 73 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 74 xml:space=\"blafasl\" \ 75 office:version=\"1.0\"> \ 76 <office:scripts/> \ 77 <office:automatic-styles/> \ 78 </office:document-content> \ 79 "; 80 81 // <?xml not at start of file 82 static const char errorTestFile[] = 83 " <?xml version=\"1.0\" encoding=\"UTF-8\"?> \ 84 <office:document-content \ 85 xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \ 86 office:version=\"1.0\"> \ 87 <office:scripts/> \ 88 <office:automatic-styles/> \ 89 </office:document-content> \ 90 "; 91 92 // plain empty 93 static const char fatalTestFile[] = ""; 94 95 struct ErrorHandler 96 : public ::cppu::WeakImplHelper1< xml::sax::XErrorHandler > 97 { 98 sal_uInt32 mnErrCount; 99 sal_uInt32 mnFatalCount; 100 sal_uInt32 mnWarnCount; 101 102 bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; } 103 104 ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0) 105 {} 106 107 virtual void SAL_CALL error( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 108 { 109 ++mnErrCount; 110 } 111 112 virtual void SAL_CALL fatalError( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 113 { 114 ++mnFatalCount; 115 } 116 117 virtual void SAL_CALL warning( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException) 118 { 119 ++mnWarnCount; 120 } 121 }; 122 123 struct DocumentHandler 124 : public ::cppu::WeakImplHelper1< xml::sax::XFastDocumentHandler > 125 { 126 // XFastContextHandler 127 virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 128 { 129 OSL_TRACE("Seen element: %c with namespace 0x%x", 130 Element & 0xFFFF, Element & 0xFFFF0000); 131 } 132 133 virtual void SAL_CALL startUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 134 { 135 } 136 137 virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (xml::sax::SAXException, uno::RuntimeException) 138 { 139 } 140 141 virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (xml::sax::SAXException, uno::RuntimeException) 142 { 143 } 144 145 virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 146 { 147 return this; 148 } 149 150 virtual uno::Reference< xml::sax::XFastContextHandler > SAL_CALL createUnknownChildContext( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException) 151 { 152 return this; 153 } 154 155 virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException) 156 { 157 } 158 159 // XFastDocumentHandler 160 virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 161 { 162 } 163 164 virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException) 165 { 166 } 167 168 virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException) 169 { 170 } 171 }; 172 173 struct TokenHandler 174 : public ::cppu::WeakImplHelper1< xml::sax::XFastTokenHandler > 175 { 176 virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (uno::RuntimeException) 177 { 178 EXPECT_TRUE( false ) << "TokenHandler::getToken() unexpected call"; 179 return -1; 180 } 181 182 virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (uno::RuntimeException) 183 { 184 EXPECT_TRUE( false ) << "TokenHandler::getIdentifier() unexpected call"; 185 return rtl::OUString(); 186 } 187 188 virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const uno::Sequence< ::sal_Int8 >& Identifier ) throw (uno::RuntimeException) 189 { 190 OSL_TRACE("getTokenFromUTF8() %s", (const char*)Identifier.getConstArray()); 191 return Identifier.getLength() ? Identifier[0] : 0; 192 } 193 194 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (uno::RuntimeException) 195 { 196 EXPECT_TRUE( false) << "TokenHandler::getUTF8Identifier() unexpected call"; 197 return uno::Sequence<sal_Int8>(); 198 } 199 }; 200 201 struct BasicTest : public ::testing::Test 202 { 203 rtl::Reference<CDocumentBuilder> mxDomBuilder; 204 rtl::Reference<ErrorHandler> mxErrHandler; 205 rtl::Reference<SequenceInputStream> mxValidInStream; 206 rtl::Reference<SequenceInputStream> mxWarningInStream; 207 rtl::Reference<SequenceInputStream> mxErrorInStream; 208 rtl::Reference<SequenceInputStream> mxFatalInStream; 209 210 void SetUp() 211 { 212 // luckily, DOM builder doesn't use service fac, so we need 213 // not bootstrap uno here 214 mxErrHandler.set( new ErrorHandler() ); 215 mxDomBuilder.set( new CDocumentBuilder(Reference< XMultiServiceFactory >() )); 216 mxValidInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile, 217 sizeof(validTestFile)/sizeof(*validTestFile))) ); 218 mxWarningInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)warningTestFile, 219 sizeof(warningTestFile)/sizeof(*warningTestFile))) ); 220 mxErrorInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)errorTestFile, 221 sizeof(errorTestFile)/sizeof(*errorTestFile))) ); 222 mxFatalInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)fatalTestFile, 223 sizeof(fatalTestFile)/sizeof(*fatalTestFile))) ); 224 mxDomBuilder->setErrorHandler(mxErrHandler.get()); 225 } 226 }; 227 228 TEST_F(BasicTest, validInputTest) 229 { 230 ASSERT_TRUE( mxDomBuilder->parse( 231 uno::Reference<io::XInputStream>( 232 mxValidInStream.get())).is() ) << "Valid input file did not result in XDocument #1"; 233 ASSERT_TRUE( mxErrHandler->noErrors() ) << "Valid input file resulted in parse errors"; 234 } 235 236 TEST_F(BasicTest, warningInputTest) 237 { 238 ASSERT_TRUE( mxDomBuilder->parse( 239 uno::Reference<io::XInputStream>( 240 mxWarningInStream.get())).is() ) << "Valid input file did not result in XDocument #2"; 241 ASSERT_TRUE( mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount ) 242 << "No parse warnings in unclean input file"; 243 } 244 245 TEST_F(BasicTest, errorInputTest) 246 { 247 ASSERT_TRUE( mxDomBuilder->parse( 248 uno::Reference<io::XInputStream>( 249 mxErrorInStream.get())).is() ) << "Valid input file did not result in XDocument #3"; 250 ASSERT_TRUE( !mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount ) 251 << "No parse errors in unclean input file"; 252 } 253 254 TEST_F(BasicTest, fatalInputTest) 255 { 256 ASSERT_TRUE( !mxDomBuilder->parse( 257 uno::Reference<io::XInputStream>( 258 mxFatalInStream.get())).is() ) << "Broken input file resulted in XDocument"; 259 ASSERT_TRUE( !mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount ) 260 << "No fatal parse errors in unclean input file"; 261 }; 262 263 264 struct SerializerTest : public ::testing::Test 265 { 266 SerializerTest() : mbUnoInitialized(false) {} 267 268 uno::Reference<uno::XComponentContext> mxCtx; 269 rtl::Reference<CDocumentBuilder> mxDomBuilder; 270 rtl::Reference<ErrorHandler> mxErrHandler; 271 rtl::Reference<SequenceInputStream> mxInStream; 272 rtl::Reference<DocumentHandler> mxHandler; 273 rtl::Reference<TokenHandler> mxTokHandler; 274 uno::Sequence< beans::Pair< rtl::OUString, sal_Int32 > > maRegisteredNamespaces; 275 bool mbUnoInitialized; 276 277 void SetUp() 278 { 279 // need working typelib, bootstrap UNO now 280 if( !mbUnoInitialized ) 281 { 282 const char* pArgs( getenv("UNOXML_DOMTEST_FORWARD") ); 283 ASSERT_TRUE(pArgs) << "Test file parameter"; 284 285 const rtl::OUString sBaseDir=rtl::OUString::createFromAscii(pArgs); 286 287 // bootstrap UNO 288 try 289 { 290 ::rtl::OUString aIniUrl; 291 ASSERT_TRUE( 292 osl_getFileURLFromSystemPath( 293 (sBaseDir+rtl::OUString::createFromAscii("unoxml_unittest_test.ini")).pData, 294 &aIniUrl.pData ) == osl_File_E_None ) << "Converting ini file to URL"; 295 296 mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl); 297 ASSERT_TRUE(mxCtx.is()) << "Getting component context"; 298 } 299 catch( uno::Exception& ) 300 { 301 ASSERT_TRUE(false) << "Bootstrapping UNO"; 302 } 303 304 mbUnoInitialized = true; 305 } 306 307 mxErrHandler.set( new ErrorHandler() ); 308 mxDomBuilder.set( new CDocumentBuilder( 309 uno::Reference< lang::XMultiServiceFactory >( 310 mxCtx->getServiceManager(), 311 uno::UNO_QUERY ))); 312 mxInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile, 313 sizeof(validTestFile)/sizeof(*validTestFile))) ); 314 mxDomBuilder->setErrorHandler(mxErrHandler.get()); 315 316 mxHandler.set( new DocumentHandler() ); 317 mxTokHandler.set( new TokenHandler() ); 318 319 maRegisteredNamespaces.realloc(2); 320 maRegisteredNamespaces[0] = beans::make_Pair( 321 rtl::OUString( 322 RTL_CONSTASCII_USTRINGPARAM( 323 "urn:oasis:names:tc:opendocument:xmlns:office:1.0") ), 324 xml::sax::FastToken::NAMESPACE); 325 maRegisteredNamespaces[1] = beans::make_Pair( 326 rtl::OUString( 327 RTL_CONSTASCII_USTRINGPARAM( 328 "http://www.w3.org/1999/xlink") ), 329 2*xml::sax::FastToken::NAMESPACE); 330 } 331 }; 332 333 TEST_F(SerializerTest, serializerTest) 334 { 335 uno::Reference< xml::dom::XDocument > xDoc= 336 mxDomBuilder->parse( 337 uno::Reference<io::XInputStream>( 338 mxInStream.get())); 339 ASSERT_TRUE( xDoc.is() ) << "Valid input file did not result in XDocument"; 340 ASSERT_TRUE( mxErrHandler->noErrors() ) << "Valid input file resulted in parse errors"; 341 342 uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer( 343 xDoc, uno::UNO_QUERY); 344 ASSERT_TRUE( xSaxSerializer.is() ) << "XSAXSerializable not supported"; 345 346 uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer( 347 xDoc, uno::UNO_QUERY); 348 ASSERT_TRUE( xSaxSerializer.is() ) << "XFastSAXSerializable not supported"; 349 350 xFastSaxSerializer->fastSerialize( mxHandler.get(), 351 mxTokHandler.get(), 352 uno::Sequence< beans::StringPair >(), 353 maRegisteredNamespaces ); 354 } 355 356 } 357 358 359 int main(int argc, char **argv) 360 { 361 ::testing::InitGoogleTest(&argc, argv); 362 return RUN_ALL_TESTS(); 363 } 364