399 lines
16 KiB
C++
399 lines
16 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* This file is part of OpenOffice.org.
|
|
*
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
* only, as published by the Free Software Foundation.
|
|
*
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License version 3 for more details
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
* <http://www.openoffice.org/license.html>
|
|
* for a copy of the LGPLv3 License.
|
|
*
|
|
************************************************************************/
|
|
|
|
// autogenerated file with codegen.pl
|
|
|
|
#include <testshl/simpleheader.hxx>
|
|
|
|
#include <rtl/ref.hxx>
|
|
#include <osl/file.hxx>
|
|
#include <osl/process.h>
|
|
#include <comphelper/seqstream.hxx>
|
|
#include <comphelper/sequence.hxx>
|
|
#include <cppuhelper/compbase1.hxx>
|
|
#include <cppuhelper/bootstrap.hxx>
|
|
#include <cppuhelper/basemutex.hxx>
|
|
|
|
#include <com/sun/star/xml/sax/FastToken.hpp>
|
|
#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
|
|
#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
|
|
|
|
#include "../source/dom/documentbuilder.hxx"
|
|
|
|
|
|
using namespace ::DOM;
|
|
using namespace ::comphelper;
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace
|
|
{
|
|
|
|
// valid xml
|
|
static const char validTestFile[] =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
|
|
<office:document-content \
|
|
xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
|
|
xmlns:xlink=\"http://www.w3.org/1999/xlink\" \
|
|
office:version=\"1.0\"> \
|
|
<office:scripts/> \
|
|
<xlink:test/> \
|
|
<office:automatic-styles teststyle=\"test\"/> \
|
|
<moretest/> \
|
|
some text öäü \
|
|
</office:document-content> \
|
|
";
|
|
|
|
// generates a warning: unsupported xml version, unknown xml:space
|
|
// value
|
|
static const char warningTestFile[] =
|
|
"<?xml version=\"47-11.0\" encoding=\"UTF-8\"?> \
|
|
<office:document-content \
|
|
xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
|
|
xml:space=\"blafasl\" \
|
|
office:version=\"1.0\"> \
|
|
<office:scripts/> \
|
|
<office:automatic-styles/> \
|
|
</office:document-content> \
|
|
";
|
|
|
|
// <?xml not at start of file
|
|
static const char errorTestFile[] =
|
|
" <?xml version=\"1.0\" encoding=\"UTF-8\"?> \
|
|
<office:document-content \
|
|
xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" \
|
|
office:version=\"1.0\"> \
|
|
<office:scripts/> \
|
|
<office:automatic-styles/> \
|
|
</office:document-content> \
|
|
";
|
|
|
|
// plain empty
|
|
static const char fatalTestFile[] = "";
|
|
|
|
struct ErrorHandler
|
|
: public ::cppu::WeakImplHelper1< xml::sax::XErrorHandler >
|
|
{
|
|
sal_uInt32 mnErrCount;
|
|
sal_uInt32 mnFatalCount;
|
|
sal_uInt32 mnWarnCount;
|
|
|
|
bool noErrors() const { return !mnErrCount && !mnFatalCount && !mnWarnCount; }
|
|
|
|
ErrorHandler() : mnErrCount(0), mnFatalCount(0), mnWarnCount(0)
|
|
{}
|
|
|
|
virtual void SAL_CALL error( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
++mnErrCount;
|
|
}
|
|
|
|
virtual void SAL_CALL fatalError( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
++mnFatalCount;
|
|
}
|
|
|
|
virtual void SAL_CALL warning( const uno::Any& ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
++mnWarnCount;
|
|
}
|
|
};
|
|
|
|
struct DocumentHandler
|
|
: public ::cppu::WeakImplHelper1< xml::sax::XFastDocumentHandler >
|
|
{
|
|
// XFastContextHandler
|
|
virtual void SAL_CALL startFastElement( ::sal_Int32 Element, const uno::Reference< xml::sax::XFastAttributeList >& Attribs ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
OSL_TRACE("Seen element: %c with namespace 0x%x",
|
|
Element & 0xFFFF, Element & 0xFFFF0000);
|
|
}
|
|
|
|
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)
|
|
{
|
|
}
|
|
|
|
virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
virtual void SAL_CALL endUnknownElement( const ::rtl::OUString& Namespace, const ::rtl::OUString& Name ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
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)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
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)
|
|
{
|
|
return this;
|
|
}
|
|
|
|
virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
// XFastDocumentHandler
|
|
virtual void SAL_CALL startDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
virtual void SAL_CALL endDocument( ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
|
|
virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException)
|
|
{
|
|
}
|
|
};
|
|
|
|
struct TokenHandler
|
|
: public ::cppu::WeakImplHelper1< xml::sax::XFastTokenHandler >
|
|
{
|
|
virtual ::sal_Int32 SAL_CALL getToken( const ::rtl::OUString& Identifier ) throw (uno::RuntimeException)
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getToken() unexpected call",
|
|
false );
|
|
return -1;
|
|
}
|
|
|
|
virtual ::rtl::OUString SAL_CALL getIdentifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getIdentifier() unexpected call",
|
|
false );
|
|
return rtl::OUString();
|
|
}
|
|
|
|
virtual ::sal_Int32 SAL_CALL getTokenFromUTF8( const uno::Sequence< ::sal_Int8 >& Identifier ) throw (uno::RuntimeException)
|
|
{
|
|
OSL_TRACE("getTokenFromUTF8() %s", (const char*)Identifier.getConstArray());
|
|
return Identifier.getLength() ? Identifier[0] : 0;
|
|
}
|
|
|
|
virtual uno::Sequence< ::sal_Int8 > SAL_CALL getUTF8Identifier( ::sal_Int32 Token ) throw (uno::RuntimeException)
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "TokenHandler::getUTF8Identifier() unexpected call",
|
|
false );
|
|
return uno::Sequence<sal_Int8>();
|
|
}
|
|
};
|
|
|
|
struct BasicTest : public CppUnit::TestFixture
|
|
{
|
|
rtl::Reference<CDocumentBuilder> mxDomBuilder;
|
|
rtl::Reference<ErrorHandler> mxErrHandler;
|
|
rtl::Reference<SequenceInputStream> mxValidInStream;
|
|
rtl::Reference<SequenceInputStream> mxWarningInStream;
|
|
rtl::Reference<SequenceInputStream> mxErrorInStream;
|
|
rtl::Reference<SequenceInputStream> mxFatalInStream;
|
|
|
|
void setUp()
|
|
{
|
|
// luckily, DOM builder doesn't use service fac, so we need
|
|
// not bootstrap uno here
|
|
mxErrHandler.set( new ErrorHandler() );
|
|
mxDomBuilder.set( new CDocumentBuilder(Reference< XMultiServiceFactory >() ));
|
|
mxValidInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
|
|
sizeof(validTestFile)/sizeof(*validTestFile))) );
|
|
mxWarningInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)warningTestFile,
|
|
sizeof(warningTestFile)/sizeof(*warningTestFile))) );
|
|
mxErrorInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)errorTestFile,
|
|
sizeof(errorTestFile)/sizeof(*errorTestFile))) );
|
|
mxFatalInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)fatalTestFile,
|
|
sizeof(fatalTestFile)/sizeof(*fatalTestFile))) );
|
|
mxDomBuilder->setErrorHandler(mxErrHandler.get());
|
|
}
|
|
|
|
void validInputTest()
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #1",
|
|
mxDomBuilder->parse(
|
|
uno::Reference<io::XInputStream>(
|
|
mxValidInStream.get())).is() );
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
|
|
mxErrHandler->noErrors() );
|
|
}
|
|
|
|
void warningInputTest()
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #2",
|
|
mxDomBuilder->parse(
|
|
uno::Reference<io::XInputStream>(
|
|
mxWarningInStream.get())).is() );
|
|
CPPUNIT_ASSERT_MESSAGE( "No parse warnings in unclean input file",
|
|
mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
|
|
}
|
|
|
|
void errorInputTest()
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument #3",
|
|
mxDomBuilder->parse(
|
|
uno::Reference<io::XInputStream>(
|
|
mxErrorInStream.get())).is() );
|
|
CPPUNIT_ASSERT_MESSAGE( "No parse errors in unclean input file",
|
|
!mxErrHandler->mnWarnCount && mxErrHandler->mnErrCount && !mxErrHandler->mnFatalCount );
|
|
}
|
|
|
|
void fatalInputTest()
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE( "Broken input file resulted in XDocument",
|
|
!mxDomBuilder->parse(
|
|
uno::Reference<io::XInputStream>(
|
|
mxFatalInStream.get())).is() );
|
|
CPPUNIT_ASSERT_MESSAGE( "No fatal parse errors in unclean input file",
|
|
!mxErrHandler->mnWarnCount && !mxErrHandler->mnErrCount && mxErrHandler->mnFatalCount );
|
|
};
|
|
|
|
// Change the following lines only, if you add, remove or rename
|
|
// member functions of the current class,
|
|
// because these macros are need by auto register mechanism.
|
|
CPPUNIT_TEST_SUITE(BasicTest);
|
|
CPPUNIT_TEST(validInputTest);
|
|
CPPUNIT_TEST(warningInputTest);
|
|
CPPUNIT_TEST(errorInputTest);
|
|
CPPUNIT_TEST(fatalInputTest);
|
|
CPPUNIT_TEST_SUITE_END();
|
|
};
|
|
|
|
struct SerializerTest : public CppUnit::TestFixture
|
|
{
|
|
SerializerTest() : mbUnoInitialized(false) {}
|
|
|
|
uno::Reference<uno::XComponentContext> mxCtx;
|
|
rtl::Reference<CDocumentBuilder> mxDomBuilder;
|
|
rtl::Reference<ErrorHandler> mxErrHandler;
|
|
rtl::Reference<SequenceInputStream> mxInStream;
|
|
rtl::Reference<DocumentHandler> mxHandler;
|
|
rtl::Reference<TokenHandler> mxTokHandler;
|
|
uno::Sequence< beans::Pair< rtl::OUString, sal_Int32 > > maRegisteredNamespaces;
|
|
bool mbUnoInitialized;
|
|
|
|
void setUp()
|
|
{
|
|
// need working typelib, bootstrap UNO now
|
|
if( !mbUnoInitialized )
|
|
{
|
|
const char* pArgs( getForwardString() );
|
|
CPPUNIT_ASSERT_MESSAGE("Test file parameter", pArgs);
|
|
|
|
const rtl::OUString sBaseDir=rtl::OUString::createFromAscii(pArgs);
|
|
|
|
// bootstrap UNO
|
|
try
|
|
{
|
|
::rtl::OUString aIniUrl;
|
|
CPPUNIT_ASSERT_MESSAGE(
|
|
"Converting ini file to URL",
|
|
osl_getFileURLFromSystemPath(
|
|
(sBaseDir+rtl::OUString::createFromAscii("unoxml_unittest_test.ini")).pData,
|
|
&aIniUrl.pData ) == osl_File_E_None );
|
|
|
|
mxCtx = ::cppu::defaultBootstrap_InitialComponentContext(aIniUrl);
|
|
CPPUNIT_ASSERT_MESSAGE("Getting component context", mxCtx.is());
|
|
}
|
|
catch( uno::Exception& )
|
|
{
|
|
CPPUNIT_ASSERT_MESSAGE("Bootstrapping UNO", false);
|
|
}
|
|
|
|
mbUnoInitialized = true;
|
|
}
|
|
|
|
mxErrHandler.set( new ErrorHandler() );
|
|
mxDomBuilder.set( new CDocumentBuilder(
|
|
uno::Reference< lang::XMultiServiceFactory >(
|
|
mxCtx->getServiceManager(),
|
|
uno::UNO_QUERY )));
|
|
mxInStream.set( new SequenceInputStream(ByteSequence((sal_Int8*)validTestFile,
|
|
sizeof(validTestFile)/sizeof(*validTestFile))) );
|
|
mxDomBuilder->setErrorHandler(mxErrHandler.get());
|
|
|
|
mxHandler.set( new DocumentHandler() );
|
|
mxTokHandler.set( new TokenHandler() );
|
|
|
|
maRegisteredNamespaces.realloc(2);
|
|
maRegisteredNamespaces[0] = beans::make_Pair(
|
|
rtl::OUString(
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
"urn:oasis:names:tc:opendocument:xmlns:office:1.0") ),
|
|
xml::sax::FastToken::NAMESPACE);
|
|
maRegisteredNamespaces[1] = beans::make_Pair(
|
|
rtl::OUString(
|
|
RTL_CONSTASCII_USTRINGPARAM(
|
|
"http://www.w3.org/1999/xlink") ),
|
|
2*xml::sax::FastToken::NAMESPACE);
|
|
}
|
|
|
|
void serializerTest ()
|
|
{
|
|
uno::Reference< xml::dom::XDocument > xDoc=
|
|
mxDomBuilder->parse(
|
|
uno::Reference<io::XInputStream>(
|
|
mxInStream.get()));
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file did not result in XDocument",
|
|
xDoc.is() );
|
|
CPPUNIT_ASSERT_MESSAGE( "Valid input file resulted in parse errors",
|
|
mxErrHandler->noErrors() );
|
|
|
|
uno::Reference< xml::sax::XSAXSerializable > xSaxSerializer(
|
|
xDoc, uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_MESSAGE( "XSAXSerializable not supported",
|
|
xSaxSerializer.is() );
|
|
|
|
uno::Reference< xml::sax::XFastSAXSerializable > xFastSaxSerializer(
|
|
xDoc, uno::UNO_QUERY);
|
|
CPPUNIT_ASSERT_MESSAGE( "XFastSAXSerializable not supported",
|
|
xSaxSerializer.is() );
|
|
|
|
xFastSaxSerializer->fastSerialize( mxHandler.get(),
|
|
mxTokHandler.get(),
|
|
uno::Sequence< beans::StringPair >(),
|
|
maRegisteredNamespaces );
|
|
}
|
|
|
|
// Change the following lines only, if you add, remove or rename
|
|
// member functions of the current class,
|
|
// because these macros are need by auto register mechanism.
|
|
|
|
CPPUNIT_TEST_SUITE(SerializerTest);
|
|
CPPUNIT_TEST(serializerTest);
|
|
CPPUNIT_TEST_SUITE_END();
|
|
};
|
|
|
|
// -----------------------------------------------------------------------------
|
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(BasicTest, "BasicTest");
|
|
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(SerializerTest, "SerializerTest");
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// this macro creates an empty function, which will called by the RegisterAllFunctions()
|
|
// to let the user the possibility to also register some functions by hand.
|
|
NOADDITIONAL;
|
|
|