summaryrefslogtreecommitdiffstats
path: root/lib/kofficecore/tests
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /lib/kofficecore/tests
downloadkoffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz
koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'lib/kofficecore/tests')
-rw-r--r--lib/kofficecore/tests/Makefile.am40
-rw-r--r--lib/kofficecore/tests/filter_graph.cpp115
-rw-r--r--lib/kofficecore/tests/filterchain_test.cpp107
-rw-r--r--lib/kofficecore/tests/kodomtest.cpp129
-rw-r--r--lib/kofficecore/tests/kogenstylestest.cpp270
-rw-r--r--lib/kofficecore/tests/kooasissettingstest.cpp106
-rw-r--r--lib/kofficecore/tests/kooasisstoretest.cpp58
-rw-r--r--lib/kofficecore/tests/kopointtest.cpp89
-rw-r--r--lib/kofficecore/tests/korecttest.cpp53
-rw-r--r--lib/kofficecore/tests/koxmlreadertest.cpp2074
-rw-r--r--lib/kofficecore/tests/priorityqueue_test.cpp87
11 files changed, 3128 insertions, 0 deletions
diff --git a/lib/kofficecore/tests/Makefile.am b/lib/kofficecore/tests/Makefile.am
new file mode 100644
index 00000000..3cc6827a
--- /dev/null
+++ b/lib/kofficecore/tests/Makefile.am
@@ -0,0 +1,40 @@
+####### General stuff
+
+INCLUDES= -I$(srcdir)/.. $(KSTORE_INCLUDES) $(all_includes)
+
+####### Files
+
+check_PROGRAMS = priorityqueue_test filterchain_test filter_graph kogenstylestest \
+ kodomtest kooasissettingstest kooasisstoretest kopointtest korecttest
+
+TESTS = kogenstylestest kodomtest kooasissettingstest kooasisstoretest kopointtest korecttest
+
+priorityqueue_test_SOURCES = priorityqueue_test.cpp
+priorityqueue_test_LDADD = ../libkofficecore.la
+
+filterchain_test_SOURCES = filterchain_test.cpp
+filterchain_test_LDADD = ../libkofficecore.la
+
+filter_graph_SOURCES = filter_graph.cpp
+filter_graph_LDADD = ../libkofficecore.la
+
+kogenstylestest_SOURCES = kogenstylestest.cpp
+kogenstylestest_LDADD = ../libkofficecore.la
+
+kodomtest_SOURCES = kodomtest.cpp
+kodomtest_LDADD = ../libkofficecore.la
+
+kooasissettingstest_SOURCES = kooasissettingstest.cpp
+kooasissettingstest_LDADD = ../libkofficecore.la
+
+kooasisstoretest_SOURCES = kooasisstoretest.cpp
+kooasisstoretest_LDADD = ../libkofficecore.la
+
+kopointtest_SOURCES = kopointtest.cpp
+kopointtest_LDADD = ../libkofficecore.la
+
+korecttest_SOURCES = korecttest.cpp
+korecttest_LDADD = ../libkofficecore.la
+
+dot:
+ dot -Tpng -o graph.png graph.dot
diff --git a/lib/kofficecore/tests/filter_graph.cpp b/lib/kofficecore/tests/filter_graph.cpp
new file mode 100644
index 00000000..22323355
--- /dev/null
+++ b/lib/kofficecore/tests/filter_graph.cpp
@@ -0,0 +1,115 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <qfile.h>
+#include <KoQueryTrader.h>
+#include <KoFilterManager.h>
+#include <kinstance.h>
+#include <kdebug.h>
+
+int main( int /*argc*/, char ** /*argv*/ )
+{
+ KInstance instance( "filter_graph" ); // we need an instance when using the trader
+
+ QCString output = "digraph filters {\n";
+
+ // The following code is shamelessly copied over from KOffice::Graph::buildGraph
+ // It wasn't feasible to do some serious changes in the lib for that tiny bit
+ // of duplicated code in a test file.
+
+ QValueList<QString> vertices; // to keep track of already inserted values, not performance critical
+
+ // Make sure that all available parts are added to the graph
+ QValueList<KoDocumentEntry> parts( KoDocumentEntry::query() );
+ QValueList<KoDocumentEntry>::ConstIterator partIt( parts.begin() );
+ QValueList<KoDocumentEntry>::ConstIterator partEnd( parts.end() );
+
+ while ( partIt != partEnd ) {
+ //kdDebug() << ( *partIt ).service()->desktopEntryName() << endl;
+ QStringList nativeMimeTypes = ( *partIt ).service()->property( "X-KDE-ExtraNativeMimeTypes" ).toStringList();
+ nativeMimeTypes += ( *partIt ).service()->property( "X-KDE-NativeMimeType" ).toString();
+ QStringList::ConstIterator it = nativeMimeTypes.begin();
+ QStringList::ConstIterator end = nativeMimeTypes.end();
+ for ( ; it != end; ++it ) {
+ QString key = *it;
+ //kdDebug() << " " << key << endl;
+ if ( !key.isEmpty() ) {
+ output += " \"";
+ output += key.latin1();
+ output += "\" [shape=box, style=filled, fillcolor=lightblue];\n";
+ if ( vertices.find( key ) == vertices.end() )
+ vertices.append( key );
+ }
+ }
+ ++partIt;
+ }
+
+ QValueList<KoFilterEntry::Ptr> filters( KoFilterEntry::query() ); // no constraint here - we want *all* :)
+ QValueList<KoFilterEntry::Ptr>::ConstIterator it = filters.begin();
+ QValueList<KoFilterEntry::Ptr>::ConstIterator end = filters.end();
+
+ for ( ; it != end; ++it ) {
+ kdDebug() << "import " << ( *it )->import << " export " << ( *it )->export_ << endl;
+ // First add the "starting points"
+ QStringList::ConstIterator importIt = ( *it )->import.begin();
+ QStringList::ConstIterator importEnd = ( *it )->import.end();
+ for ( ; importIt != importEnd; ++importIt ) {
+ // already there?
+ if ( vertices.find( *importIt ) == vertices.end() ) {
+ vertices.append( *importIt );
+ output += " \"";
+ output += ( *importIt ).latin1();
+ output += "\";\n";
+ }
+ }
+
+ QStringList::ConstIterator exportIt = ( *it )->export_.begin();
+ QStringList::ConstIterator exportEnd = ( *it )->export_.end();
+
+ for ( ; exportIt != exportEnd; ++exportIt ) {
+ // First make sure the export vertex is in place
+ if ( vertices.find( *exportIt ) == vertices.end() ) {
+ output += " \"";
+ output += ( *exportIt ).latin1();
+ output += "\";\n";
+ vertices.append( *exportIt );
+ }
+ // Then create the appropriate edges
+ importIt = ( *it )->import.begin();
+ for ( ; importIt != importEnd; ++importIt ) {
+ output += " \"";
+ output += ( *importIt ).latin1();
+ output += "\" -> \"";
+ output += ( *exportIt ).latin1();
+ if ( KoFilterManager::filterAvailable( *it ) )
+ output += "\";\n";
+ else
+ output += "\" [style=dotted];\n";
+ }
+ }
+ }
+
+ output += "}\n";
+
+ QFile f( "graph.dot" );
+ if ( f.open( IO_WriteOnly ) )
+ f.writeBlock( output.data(), output.size() - 1 );
+ f.close();
+ return 0;
+}
diff --git a/lib/kofficecore/tests/filterchain_test.cpp b/lib/kofficecore/tests/filterchain_test.cpp
new file mode 100644
index 00000000..23f620a1
--- /dev/null
+++ b/lib/kofficecore/tests/filterchain_test.cpp
@@ -0,0 +1,107 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoFilterChain.h>
+#include <KoFilterManager.h>
+#include <kinstance.h>
+#include <kdebug.h>
+
+int main( int /*argc*/, char ** /*argv*/ )
+{
+ KInstance instance( "filterchain_test" ); // we need an instance when using the trader
+ KOffice::Graph g( "application/x-kspread" );
+ g.dump();
+ g.setSourceMimeType( "application/x-kword" );
+ g.dump();
+
+ KoFilterManager *manager = new KoFilterManager( 0 );
+ kdDebug() << "Trying to build some filter chains..." << endl;
+ QCString mimeType( "foo/bar" );
+ KoFilterChain::Ptr chain = g.chain( manager, mimeType );
+ if ( !chain )
+ kdDebug() << "Chain for 'foo/bar' is not available, OK" << endl;
+ else {
+ kdError() << "Chain for 'foo/bar' is available!" << endl;
+ chain->dump();
+ }
+
+ mimeType = "application/x-krita";
+ chain = g.chain( manager, mimeType );
+ if ( !chain )
+ kdDebug() << "Chain for 'application/x-krita' is not available, OK" << endl;
+ else {
+ kdError() << "Chain 'application/x-krita' is available!" << endl;
+ chain->dump();
+ }
+
+ mimeType = "text/x-csv";
+ chain = g.chain( manager, mimeType );
+ if ( !chain )
+ kdError() << "Chain for 'text/x-csv' is not available!" << endl;
+ else {
+ kdDebug() << "Chain for 'text/x-csv' is available, OK" << endl;
+ chain->dump();
+ }
+
+ // Try to find the closest KOffice part
+ mimeType = "";
+ chain = g.chain( manager, mimeType );
+ if ( !chain )
+ kdDebug() << "It was already a KOffice part, OK" << endl;
+ else
+ kdError() << "We really got a chain? ugh :}" << endl;
+
+ g.setSourceMimeType( "text/x-csv" );
+ mimeType = "";
+ chain = g.chain( manager, mimeType );
+ if ( !chain )
+ kdError() << "Hmm... why didn't we find a chain?" << endl;
+ else {
+ kdDebug() << "Chain for 'text/x-csv' -> closest part is available ("
+ << mimeType << "), OK" << endl;
+ chain->dump();
+ }
+
+ kdDebug() << "Checking mimeFilter() for Import:" << endl;
+ QStringList list = KoFilterManager::mimeFilter( "application/x-kword", KoFilterManager::Import );
+ QStringList::ConstIterator it = list.begin();
+ QStringList::ConstIterator end = list.end();
+ for ( ; it != end; ++it )
+ kdDebug() << " " << *it << endl;
+ kdDebug() << " " << list.count() << " entries." << endl;
+
+ kdDebug() << "Checking mimeFilter() for Export:" << endl;
+ list = KoFilterManager::mimeFilter( "application/x-kword", KoFilterManager::Export );
+ it = list.begin();
+ end = list.end();
+ for ( ; it != end; ++it )
+ kdDebug() << " " << *it << endl;
+ kdDebug() << " " << list.count() << " entries." << endl;
+
+ kdDebug() << "Checking KoShell's mimeFilter():" << endl;
+ list = KoFilterManager::mimeFilter();
+ it = list.begin();
+ end = list.end();
+ for ( ; it != end; ++it )
+ kdDebug() << " " << *it << endl;
+ kdDebug() << " " << list.count() << " entries." << endl;
+
+ delete manager;
+ return 0;
+}
diff --git a/lib/kofficecore/tests/kodomtest.cpp b/lib/kofficecore/tests/kodomtest.cpp
new file mode 100644
index 00000000..c8e3c539
--- /dev/null
+++ b/lib/kofficecore/tests/kodomtest.cpp
@@ -0,0 +1,129 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 David Faure <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoDom.h"
+#include "KoXmlNS.h"
+
+#include <qapplication.h>
+#include <assert.h>
+
+//static void debugElemNS( const QDomElement& elem )
+//{
+// qDebug( "nodeName=%s tagName=%s localName=%s prefix=%s namespaceURI=%s", elem.nodeName().latin1(), elem.tagName().latin1(), elem.localName().latin1(), elem.prefix().latin1(), elem.namespaceURI().latin1() );
+//}
+
+void testQDom( const QDomDocument& doc )
+{
+ QDomElement docElem = doc.documentElement();
+ //debugElemNS( docElem );
+ assert( docElem.nodeName() == "o:document-content" );
+ assert( docElem.tagName() == "document-content" );
+ assert( docElem.localName() == "document-content" );
+ assert( docElem.prefix() == "o" );
+ assert( docElem.namespaceURI() == KoXmlNS::office );
+
+ // WARNING, elementsByTagNameNS is recursive!!!
+ QDomNodeList docElemChildren = docElem.elementsByTagNameNS( KoXmlNS::office, "body" );
+ assert( docElemChildren.length() == 1 );
+
+ QDomElement elem = docElemChildren.item( 0 ).toElement();
+ //debugElemNS( elem );
+ assert( elem.tagName() == "body" );
+ assert( elem.localName() == "body" );
+ assert( elem.prefix() == "o" );
+ assert( elem.namespaceURI() == KoXmlNS::office );
+
+ QDomNode n = elem.firstChild();
+ for ( ; !n.isNull() ; n = n.nextSibling() ) {
+ if ( !n.isElement() )
+ continue;
+ QDomElement e = n.toElement();
+ //debugElemNS( e );
+ assert( e.tagName() == "p" );
+ assert( e.localName() == "p" );
+ assert( e.prefix().isEmpty() );
+ assert( e.namespaceURI() == KoXmlNS::text );
+ }
+
+ qDebug("testQDom... ok");
+}
+
+void testKoDom( const QDomDocument& doc )
+{
+ QDomElement docElem = KoDom::namedItemNS( doc, KoXmlNS::office, "document-content" );
+ assert( !docElem.isNull() );
+ assert( docElem.localName() == "document-content" );
+ assert( docElem.namespaceURI() == KoXmlNS::office );
+
+ QDomElement body = KoDom::namedItemNS( docElem, KoXmlNS::office, "body" );
+ assert( !body.isNull() );
+ assert( body.localName() == "body" );
+ assert( body.namespaceURI() == KoXmlNS::office );
+
+ QDomElement p = KoDom::namedItemNS( body, KoXmlNS::text, "p" );
+ assert( !p.isNull() );
+ assert( p.localName() == "p" );
+ assert( p.namespaceURI() == KoXmlNS::text );
+
+ const QDomElement officeStyle = KoDom::namedItemNS( docElem, KoXmlNS::office, "styles" );
+ assert( !officeStyle.isNull() );
+
+ // Look for a non-existing element
+ QDomElement notexist = KoDom::namedItemNS( body, KoXmlNS::text, "notexist" );
+ assert( notexist.isNull() );
+
+ int count = 0;
+ QDomElement elem;
+ forEachElement( elem, body ) {
+ assert( elem.localName() == "p" );
+ assert( elem.namespaceURI() == KoXmlNS::text );
+ ++count;
+ }
+ assert( count == 2 );
+
+ // Attributes
+ // ### Qt bug: it doesn't work if using style-name instead of text:style-name in the XML
+ const QString styleName = p.attributeNS( KoXmlNS::text, "style-name", QString::null );
+ qDebug( "%s", styleName.latin1() );
+ assert( styleName == "L1" );
+
+ qDebug("testKoDom... ok");
+}
+
+int main( int argc, char** argv ) {
+ QApplication app( argc, argv, QApplication::Tty );
+
+ const QCString xml = QCString( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<o:document-content xmlns:o=\"" )
+ + KoXmlNS::office
+ + "\" xmlns=\"" + KoXmlNS::text
+ + "\" xmlns:text=\"" + KoXmlNS::text
+ + "\">\n"
+ "<o:body><p text:style-name=\"L1\">foobar</p><p>2nd</p></o:body><o:styles></o:styles>\n"
+ "</o:document-content>\n";
+ QDomDocument doc;
+ //QXmlSimpleReader reader;
+ //reader.setFeature( "http://xml.org/sax/features/namespaces", TRUE );
+ //reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", FALSE );
+ bool ok = doc.setContent( xml, true /* namespace processing */ );
+ assert( ok );
+
+ testQDom(doc);
+ testKoDom(doc);
+}
diff --git a/lib/kofficecore/tests/kogenstylestest.cpp b/lib/kofficecore/tests/kogenstylestest.cpp
new file mode 100644
index 00000000..ddfac1f6
--- /dev/null
+++ b/lib/kofficecore/tests/kogenstylestest.cpp
@@ -0,0 +1,270 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004-2006 David Faure <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoGenStyles.h>
+#include <KoXmlWriter.h>
+#include "../../store/tests/xmlwritertest.h"
+#include <kdebug.h>
+#include <assert.h>
+
+int testLookup()
+{
+ kdDebug() << k_funcinfo << endl;
+ KoGenStyles coll;
+
+ QMap<QString, QString> map1;
+ map1.insert( "map1key", "map1value" );
+ QMap<QString, QString> map2;
+ map2.insert( "map2key1", "map2value1" );
+ map2.insert( "map2key2", "map2value2" );
+
+ KoGenStyle first( KoGenStyle::STYLE_AUTO, "paragraph" );
+ first.addAttribute( "style:master-page-name", "Standard" );
+ first.addProperty( "style:page-number", "0" );
+ first.addProperty( "style:foobar", "2", KoGenStyle::TextType );
+ first.addStyleMap( map1 );
+ first.addStyleMap( map2 );
+
+ QString firstName = coll.lookup( first );
+ kdDebug() << "The first style got assigned the name " << firstName << endl;
+ assert( firstName == "A1" ); // it's fine if it's something else, but the koxmlwriter tests require a known name
+ assert( first.type() == KoGenStyle::STYLE_AUTO );
+
+ KoGenStyle second( KoGenStyle::STYLE_AUTO, "paragraph" );
+ second.addAttribute( "style:master-page-name", "Standard" );
+ second.addProperty( "style:page-number", "0" );
+ second.addProperty( "style:foobar", "2", KoGenStyle::TextType );
+ second.addStyleMap( map1 );
+ second.addStyleMap( map2 );
+
+ QString secondName = coll.lookup( second );
+ kdDebug() << "The second style got assigned the name " << secondName << endl;
+
+ assert( firstName == secondName ); // check that sharing works
+ assert( first == second ); // check that operator== works :)
+
+ const KoGenStyle* s = coll.style( firstName ); // check lookup of existing style
+ assert( s );
+ assert( *s == first );
+ s = coll.style( "foobarblah" ); // check lookup of non-existing style
+ assert( !s );
+
+ KoGenStyle third( KoGenStyle::STYLE_AUTO, "paragraph", secondName ); // inherited style
+ third.addProperty( "style:margin-left", "1.249cm" );
+ third.addProperty( "style:page-number", "0" ); // same as parent
+ third.addProperty( "style:foobar", "3", KoGenStyle::TextType ); // different from parent
+ assert( third.parentName() == secondName );
+
+ QString thirdName = coll.lookup( third, "P" );
+ kdDebug() << "The third style got assigned the name " << thirdName << endl;
+ assert( thirdName == "P1" );
+
+ KoGenStyle user( KoGenStyle::STYLE_USER, "paragraph" ); // differs from third since it doesn't inherit second, and has a different type
+ user.addProperty( "style:margin-left", "1.249cm" );
+
+ QString userStyleName = coll.lookup( user, "User", KoGenStyles::DontForceNumbering );
+ kdDebug() << "The user style got assigned the name " << userStyleName << endl;
+ assert( userStyleName == "User" );
+
+ KoGenStyle sameAsParent( KoGenStyle::STYLE_AUTO, "paragraph", secondName ); // inherited style
+ sameAsParent.addAttribute( "style:master-page-name", "Standard" );
+ sameAsParent.addProperty( "style:page-number", "0" );
+ sameAsParent.addProperty( "style:foobar", "2", KoGenStyle::TextType );
+ sameAsParent.addStyleMap( map1 );
+ sameAsParent.addStyleMap( map2 );
+ QString sapName = coll.lookup( sameAsParent, "foobar" );
+ kdDebug() << "The 'same as parent' style got assigned the name " << sapName << endl;
+
+ assert( sapName == secondName );
+ assert( coll.styles().count() == 3 );
+
+ // OK, now add a style marked as for styles.xml; it looks like the above style, but
+ // since it's marked for styles.xml it shouldn't be shared with it.
+ KoGenStyle headerStyle( KoGenStyle::STYLE_AUTO, "paragraph" );
+ headerStyle.addAttribute( "style:master-page-name", "Standard" );
+ headerStyle.addProperty( "style:page-number", "0" );
+ headerStyle.addProperty( "style:foobar", "2", KoGenStyle::TextType );
+ headerStyle.addStyleMap( map1 );
+ headerStyle.addStyleMap( map2 );
+ headerStyle.setAutoStyleInStylesDotXml( true );
+ QString headerStyleName = coll.lookup( headerStyle, "foobar" );
+
+ assert( coll.styles().count() == 4 );
+ assert( coll.styles( KoGenStyle::STYLE_AUTO ).count() == 2 );
+ assert( coll.styles( KoGenStyle::STYLE_USER ).count() == 1 );
+
+ QValueList<KoGenStyles::NamedStyle> stylesXmlStyles = coll.styles( KoGenStyle::STYLE_AUTO, true );
+ assert( stylesXmlStyles.count() == 1 );
+ KoGenStyles::NamedStyle firstStyle = stylesXmlStyles.first();
+ assert( firstStyle.name == headerStyleName );
+
+ TEST_BEGIN( 0, 0 );
+ first.writeStyle( &writer, coll, "style:style", firstName, "style:paragraph-properties" );
+ TEST_END( "XML for first/second style", "<r>\n <style:style style:name=\"A1\" style:family=\"paragraph\" style:master-page-name=\"Standard\">\n <style:paragraph-properties style:page-number=\"0\"/>\n <style:text-properties style:foobar=\"2\"/>\n <style:map map1key=\"map1value\"/>\n <style:map map2key1=\"map2value1\" map2key2=\"map2value2\"/>\n </style:style>\n</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ third.writeStyle( &writer, coll, "style:style", thirdName, "style:paragraph-properties" );
+ TEST_END( "XML for third style", "<r>\n <style:style style:name=\"P1\" style:parent-style-name=\"A1\" style:family=\"paragraph\">\n <style:paragraph-properties style:margin-left=\"1.249cm\"/>\n <style:text-properties style:foobar=\"3\"/>\n </style:style>\n</r>\n" );
+
+ coll.markStyleForStylesXml( firstName );
+ {
+ QValueList<KoGenStyles::NamedStyle> stylesXmlStyles = coll.styles( KoGenStyle::STYLE_AUTO, true );
+ assert( stylesXmlStyles.count() == 2 );
+ QValueList<KoGenStyles::NamedStyle> contentXmlStyles = coll.styles( KoGenStyle::STYLE_AUTO, false );
+ assert( contentXmlStyles.count() == 1 );
+ }
+
+ return 0;
+}
+
+int testDefaultStyle()
+{
+ kdDebug() << k_funcinfo << endl;
+ /* Create a default style,
+ * and then an auto style with exactly the same attributes
+ * -> the lookup gives the default style.
+ *
+ * Also checks how the default style gets written out to XML.
+ */
+ KoGenStyles coll;
+
+ KoGenStyle defaultStyle( KoGenStyle::STYLE_AUTO, "paragraph" );
+ defaultStyle.addAttribute( "style:master-page-name", "Standard" );
+ defaultStyle.addProperty( "myfont", "isBold" );
+ defaultStyle.setDefaultStyle( true );
+ QString defaultStyleName = coll.lookup( defaultStyle );
+ assert( !defaultStyleName.isEmpty() ); // whatever, but not empty
+ assert( defaultStyle.type() == KoGenStyle::STYLE_AUTO );
+ assert( defaultStyle.isDefaultStyle() );
+
+ KoGenStyle anotherStyle( KoGenStyle::STYLE_AUTO, "paragraph" );
+ anotherStyle.addAttribute( "style:master-page-name", "Standard" );
+ anotherStyle.addProperty( "myfont", "isBold" );
+ QString anotherStyleName = coll.lookup( anotherStyle );
+ assert( anotherStyleName == defaultStyleName );
+
+ assert( coll.styles().count() == 1 );
+
+ TEST_BEGIN( 0, 0 );
+ defaultStyle.writeStyle( &writer, coll, "style:default-style", defaultStyleName, "style:paragraph-properties" );
+ TEST_END( "XML for default style", "<r>\n <style:default-style style:family=\"paragraph\" style:master-page-name=\"Standard\">\n <style:paragraph-properties myfont=\"isBold\"/>\n </style:default-style>\n</r>\n" );
+
+ // The kspread case: not writing out all properties, only if they differ
+ // from the default style.
+ // KoGenStyles doesn't fetch info from the parent style when testing
+ // for equality, so KSpread uses isEmpty() to check for equality-to-parent.
+ KoGenStyle dataStyle( KoGenStyle::STYLE_AUTO, "paragraph", defaultStyleName );
+ assert( dataStyle.isEmpty() );
+ // and then it doesn't look up the auto style, but rather uses the parent style directly.
+
+ return 0;
+}
+
+int testUserStyles()
+{
+ kdDebug() << k_funcinfo << endl;
+ /* Two user styles with exactly the same attributes+properties will not get merged, since
+ * they don't have exactly the same attributes after all: the display-name obviously differs :)
+ */
+ KoGenStyles coll;
+
+ KoGenStyle user1( KoGenStyle::STYLE_USER, "paragraph" );
+ user1.addAttribute( "style:display-name", "User 1" );
+ user1.addProperty( "myfont", "isBold" );
+
+ QString user1StyleName = coll.lookup( user1, "User1", KoGenStyles::DontForceNumbering );
+ kdDebug() << "The user style got assigned the name " << user1StyleName << endl;
+ assert( user1StyleName == "User1" );
+
+ KoGenStyle user2( KoGenStyle::STYLE_USER, "paragraph" );
+ user2.addAttribute( "style:display-name", "User 2" );
+ user2.addProperty( "myfont", "isBold" );
+
+ QString user2StyleName = coll.lookup( user2, "User2", KoGenStyles::DontForceNumbering );
+ kdDebug() << "The user style got assigned the name " << user2StyleName << endl;
+ assert( user2StyleName == "User2" );
+
+ // And now, what if the data uses that style?
+ // This is like sameAsParent in the other test, but this time the
+ // parent is a STYLE_USER...
+ KoGenStyle dataStyle( KoGenStyle::STYLE_AUTO, "paragraph", user2StyleName );
+ dataStyle.addProperty( "myfont", "isBold" );
+
+ QString dataStyleName = coll.lookup( dataStyle, "DataStyle" );
+ kdDebug() << "The auto style got assigned the name " << dataStyleName << endl;
+ assert( dataStyleName == "User2" ); // it found the parent as equal
+
+ // Let's do the opposite test, just to make sure
+ KoGenStyle dataStyle2( KoGenStyle::STYLE_AUTO, "paragraph", user2StyleName );
+ dataStyle2.addProperty( "myfont", "isNotBold" );
+
+ QString dataStyle2Name = coll.lookup( dataStyle2, "DataStyle" );
+ kdDebug() << "The different auto style got assigned the name " << dataStyle2Name << endl;
+ assert( dataStyle2Name == "DataStyle1" );
+
+ assert( coll.styles().count() == 3 );
+
+ TEST_BEGIN( 0, 0 );
+ user1.writeStyle( &writer, coll, "style:style", user1StyleName, "style:paragraph-properties" );
+ TEST_END( "XML for user style 1", "<r>\n <style:style style:name=\"User1\" style:display-name=\"User 1\" style:family=\"paragraph\">\n <style:paragraph-properties myfont=\"isBold\"/>\n </style:style>\n</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ user2.writeStyle( &writer, coll, "style:style", user2StyleName, "style:paragraph-properties" );
+ TEST_END( "XML for user style 2", "<r>\n <style:style style:name=\"User2\" style:display-name=\"User 2\" style:family=\"paragraph\">\n <style:paragraph-properties myfont=\"isBold\"/>\n </style:style>\n</r>\n" );
+
+ return 0;
+}
+
+int testStylesDotXml()
+{
+ kdDebug() << k_funcinfo << endl;
+ KoGenStyles coll;
+
+ // Check that an autostyle-in-style.xml and an autostyle-in-content.xml
+ // don't get the same name. It confuses KoGenStyle's named-based maps.
+ KoGenStyle headerStyle( KoGenStyle::STYLE_AUTO, "paragraph" );
+ headerStyle.addAttribute( "style:master-page-name", "Standard" );
+ headerStyle.addProperty( "style:page-number", "0" );
+ headerStyle.setAutoStyleInStylesDotXml( true );
+ QString headerStyleName = coll.lookup( headerStyle, "P" );
+ assert( headerStyleName == "P1" );
+
+ //coll.dump();
+
+ KoGenStyle first( KoGenStyle::STYLE_AUTO, "paragraph" );
+ first.addAttribute( "style:master-page-name", "Standard" );
+ QString firstName = coll.lookup( first, "P" );
+ kdDebug() << "The auto style got assigned the name " << firstName << endl;
+ assert( firstName == "P2" ); // anything but not P1.
+ return 0;
+}
+
+int main( int, char** ) {
+ fprintf( stderr, "OK\n" );
+
+ if ( testLookup() )
+ return 1;
+ if ( testDefaultStyle() )
+ return 1;
+ if ( testUserStyles() )
+ return 1;
+ if ( testStylesDotXml() )
+ return 1;
+
+ return 0;
+}
diff --git a/lib/kofficecore/tests/kooasissettingstest.cpp b/lib/kofficecore/tests/kooasissettingstest.cpp
new file mode 100644
index 00000000..ef29536d
--- /dev/null
+++ b/lib/kofficecore/tests/kooasissettingstest.cpp
@@ -0,0 +1,106 @@
+/* This file is part of the KDE project
+ Copyright (C) 2004 David Faure <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoOasisSettings.h>
+#include <KoDom.h>
+#include <kdebug.h>
+#include <assert.h>
+
+void testSelectItemSet( KoOasisSettings& settings )
+{
+ KoOasisSettings::Items items = settings.itemSet( "notexist" );
+ assert( items.isNull() );
+ items = settings.itemSet( "view-settings" );
+ assert( !items.isNull() );
+ kdDebug() << "testSelectItemSet OK" << endl;
+}
+
+void testParseConfigItemString( KoOasisSettings& settings )
+{
+ KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
+ const QString unit = viewSettings.parseConfigItemString( "unit" );
+ qDebug( "%s", unit.latin1() );
+ assert( unit == "mm" );
+ kdDebug() << "testParseConfigItemString OK" << endl;
+}
+
+void testIndexedMap( KoOasisSettings& settings )
+{
+ KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
+ assert( !viewSettings.isNull() );
+ KoOasisSettings::IndexedMap viewMap = viewSettings.indexedMap( "Views" );
+ assert( !viewMap.isNull() );
+ KoOasisSettings::Items firstView = viewMap.entry( 0 );
+ assert( !firstView.isNull() );
+ const short zoomFactor = firstView.parseConfigItemShort( "ZoomFactor" );
+ assert( zoomFactor == 100 );
+ KoOasisSettings::Items secondView = viewMap.entry( 1 );
+ assert( secondView.isNull() );
+ kdDebug() << "testIndexedMap OK" << endl;
+}
+
+void testNamedMap( KoOasisSettings& settings )
+{
+ KoOasisSettings::Items viewSettings = settings.itemSet( "view-settings" );
+ assert( !viewSettings.isNull() );
+ KoOasisSettings::NamedMap viewMap = viewSettings.namedMap( "NamedMap" );
+ assert( !viewMap.isNull() );
+ KoOasisSettings::Items foo = viewMap.entry( "foo" );
+ assert( !foo.isNull() );
+ const int zoomFactor = foo.parseConfigItemShort( "ZoomFactor" );
+ assert( zoomFactor == 100 );
+ KoOasisSettings::Items secondView = viewMap.entry( "foobar" );
+ assert( secondView.isNull() );
+ kdDebug() << "testNamedMap OK" << endl;
+}
+
+int main( int, char** ) {
+
+ const QCString xml = "\
+<?xml version=\"1.0\" encoding=\"UTF-8\"?> \
+<office:document-settings xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"> \
+ <office:settings> \
+ <config:config-item-set config:name=\"view-settings\"> \
+ <config:config-item config:name=\"unit\" config:type=\"string\">mm</config:config-item> \
+ <config:config-item-map-indexed config:name=\"Views\"> \
+ <config:config-item-map-entry> \
+ <config:config-item config:name=\"ZoomFactor\" config:type=\"short\">100</config:config-item> \
+ </config:config-item-map-entry> \
+ </config:config-item-map-indexed> \
+ <config:config-item-map-named config:name=\"NamedMap\"> \
+ <config:config-item-map-entry config:name=\"foo\"> \
+ <config:config-item config:name=\"ZoomFactor\" config:type=\"int\">100</config:config-item> \
+ </config:config-item-map-entry> \
+ </config:config-item-map-named> \
+ </config:config-item-set> \
+ </office:settings> \
+</office:document-settings> \
+";
+
+ QDomDocument doc;
+ bool ok = doc.setContent( xml, true /* namespace processing */ );
+ assert( ok );
+
+ KoOasisSettings settings( doc );
+
+ testSelectItemSet( settings );
+ testParseConfigItemString( settings );
+ testIndexedMap( settings );
+ testNamedMap( settings );
+ return 0;
+}
diff --git a/lib/kofficecore/tests/kooasisstoretest.cpp b/lib/kofficecore/tests/kooasisstoretest.cpp
new file mode 100644
index 00000000..6750904b
--- /dev/null
+++ b/lib/kofficecore/tests/kooasisstoretest.cpp
@@ -0,0 +1,58 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 David Faure <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <KoOasisStore.h>
+#include <KoDom.h>
+#include <kdebug.h>
+#include <assert.h>
+
+void testMimeForPath( QDomDocument& doc )
+{
+ QString mime = KoOasisStore::mimeForPath( doc, "Object 1" );
+ kdDebug() << k_funcinfo << mime << endl;
+ assert( !mime.isNull() );
+ assert( !mime.isEmpty() );
+ assert( mime == "application/vnd.oasis.opendocument.text" );
+ kdDebug() << "testMimeForPath OK" << endl;
+}
+
+int main( int, char** ) {
+
+ const QCString xml = "\
+<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
+<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\">\n\
+ <manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.text\" manifest:full-path=\"/\"/>\n\
+ <manifest:file-entry manifest:media-type=\"text/xml\" manifest:full-path=\"content.xml\"/>\n\
+ <manifest:file-entry manifest:media-type=\"application/vnd.oasis.opendocument.text\" manifest:full-path=\"Object 1\"/>\n\
+</manifest:manifest> \
+";
+
+ QDomDocument doc;
+ QString errorMsg;
+ int errorLine, errorColumn;
+ bool ok = doc.setContent( xml, true /* namespace processing */, &errorMsg, &errorLine, &errorColumn );
+ if ( !ok ) {
+ kdError() << "Parsing error! Aborting!" << endl
+ << " In line: " << errorLine << ", column: " << errorColumn << endl
+ << " Error message: " << errorMsg << endl;
+ return 1;
+ }
+
+ testMimeForPath( doc );
+ return 0;
+}
diff --git a/lib/kofficecore/tests/kopointtest.cpp b/lib/kofficecore/tests/kopointtest.cpp
new file mode 100644
index 00000000..25286a5d
--- /dev/null
+++ b/lib/kofficecore/tests/kopointtest.cpp
@@ -0,0 +1,89 @@
+#include <KoPoint.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <stdlib.h>
+#include <math.h>
+
+bool check( QString txt, bool res, bool expected )
+{
+ if ( res == expected ) {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "ok" << endl;
+ } else {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "KO !" << endl;
+ exit( 1 );
+ }
+ return true;
+}
+
+bool check( QString txt, double res, double expected )
+{
+ if ( kAbs(res - expected) < 0.000001 ) {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "ok" << endl;
+ } else {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "KO !" << endl;
+ exit( 1 );
+ }
+ return true;
+}
+
+int main()
+{
+ KoPoint p0;
+ check( "KoPoint() is null", p0.isNull(), true );
+ KoPoint p1( 10.1, 20.2 );
+ check( "KoPoint(...) is not null", p1.isNull(), false );
+ check( "KoPoint::x()", p1.x(), 10.1 );
+ check( "KoPoint::y()", p1.y(), 20.2 );
+ p1.setX( 2.1 );
+ p1.setY( 3.2 );
+ check( "KoPoint::setX()", p1.x(), 2.1 );
+ check( "KoPoint::setY()", p1.y(), 3.2 );
+
+ KoPoint p2( QPoint( -30, -40 ) );
+ check( "KoPoint(const QPoint&)", p2.x(), -30.0 );
+ check( "KoPoint(const QPoint&)", p2.y(), -40.0 );
+ p2.rx() = 1.5;
+ p2.ry() = 2.5;
+ check( "KoPoint::rx()", p2.x(), 1.5 );
+ check( "KoPoint::ry()", p2.y(), 2.5 );
+ p2.setCoords( -1.6, -1.7 );
+ check( "KoPoint::setCoords(double, double)", p2.x(), -1.6 );
+ check( "KoPoint::setCoords(double, double)", p2.y(), -1.7 );
+
+ check( "KoPoint::operator==(const KoPoint&)", p1 == p1, true );
+ check( "KoPoint::operator!=(const KoPoint&)", p1 != p2, true );
+
+ KoPoint p4( 10.2, 20.2 );
+ KoPoint p5( 30.4, 40.4 );
+ p4 += p5;
+ check( "KoPoint::operator+=(const KoPoint&)", p4.x(), 40.6 );
+ check( "KoPoint::operator+=(const KoPoint&)", p4.y(), 60.6 );
+ p4 -= p5;
+ check( "KoPoint::operator-=(const KoPoint&)", p4.x(), 10.2 );
+ check( "KoPoint::operator-=(const KoPoint&)", p4.y(), 20.2 );
+ p4 *= 2.0;
+ check( "KoPoint::operator*=(double)", p4.x(), 20.4 );
+ check( "KoPoint::operator*=(double)", p4.y(), 40.4 );
+ p4 = p5;
+ check( "KoPoint::operator=(const KoPoint&)", p4.x(), 30.4 );
+ check( "KoPoint::operator=(const KoPoint&)", p4.y(), 40.4 );
+
+ // ### global operator+, operator- and operator*
+ // ### transform
+
+ KoPoint p6( 1.0, 2.0 );
+ check( "KoPoint::isNear()", p6.isNear( p6, 0 ), true );
+ check( "KoPoint::isNear()", p6.isNear( KoPoint( 2, 10 ), 1 ), false );
+ check( "KoPoint::isNear()", p6.isNear( KoPoint( 2, 1 ), 1 ), true );
+
+ KoPoint p7( 10, 10 );
+ check( "KoPoint::getAngle()",
+ fmod( KoPoint::getAngle( p7, p7 * -1 ) + 10*360.0, 360.0 ), 45.0 );
+ // ### ??? check( "KoPoint::getAngle()",
+ // fmod( KoPoint::getAngle( -1 * p7, p7 ) + 10*360.0, 360.0 ), 45.0 );
+ // can we define a behaviour ?
+ // ### check( "KoPoint::getAngle()", KoPoint::getAngle( p7, p7 ), ??? );
+
+ kdDebug() << endl << "Test OK !" << endl;
+}
+
diff --git a/lib/kofficecore/tests/korecttest.cpp b/lib/kofficecore/tests/korecttest.cpp
new file mode 100644
index 00000000..9c2cb8b0
--- /dev/null
+++ b/lib/kofficecore/tests/korecttest.cpp
@@ -0,0 +1,53 @@
+#include <KoRect.h>
+#include <stdio.h>
+#include <kapplication.h>
+#include <stdlib.h>
+#include <kdebug.h>
+#include <kglobal.h>
+
+bool check(QString txt, bool res, bool expected)
+{
+ if (res == expected) {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "ok" << endl;
+ }
+ else {
+ kdDebug() << txt << " : checking '" << res << "' against expected value '" << expected << "'... " << "KO !" << endl;
+ exit(1);
+ }
+ return true;
+}
+
+bool check(QString txt, QString a, QString b)
+{
+ if (a.isEmpty())
+ a = QString::null;
+ if (b.isEmpty())
+ b = QString::null;
+ if (a == b) {
+ kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "ok" << endl;
+ }
+ else {
+ kdDebug() << txt << " : checking '" << a << "' against expected value '" << b << "'... " << "KO !" << endl;
+ exit(1);
+ }
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ KApplication app(argc,argv,"korecttest",false,false);
+
+ KoRect emptyRect;
+ check( "KoRect() is null", emptyRect.isNull(), true );
+ check( "KoRect() is empty", emptyRect.isEmpty(), true );
+ KoRect rect( 1, 15, 250, 156.14 );
+ check( "KoRect(...) is not null", rect.isNull(), false );
+ check( "KoRect(...) is not empty", rect.isEmpty(), false );
+ KoRect unionRect = rect | emptyRect;
+ check( "Union is not null", unionRect.isNull(), false );
+ check( "Union is not empty", unionRect.isEmpty(), false );
+ kdDebug() << unionRect << endl;
+
+ printf("\nTest OK !\n");
+}
+
diff --git a/lib/kofficecore/tests/koxmlreadertest.cpp b/lib/kofficecore/tests/koxmlreadertest.cpp
new file mode 100644
index 00000000..213fe0db
--- /dev/null
+++ b/lib/kofficecore/tests/koxmlreadertest.cpp
@@ -0,0 +1,2074 @@
+/* This file is part of the KDE project
+ Copyright (C) 2005 Ariya Hidayat <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+*/
+
+// xmlreadertest.cpp - test KoXml classes
+// Ariya Hidayat, November 2005
+
+#include <qstring.h>
+#include <qcstring.h>
+#include <qbuffer.h>
+#include <qtextstream.h>
+#include <qdatetime.h>
+#include <qfile.h>
+
+#include "KoXmlReader.h"
+#include <qxml.h>
+
+#define CHECK(x,y) check(__FILE__,__LINE__,#x,x,y)
+
+static int testCount = 0;
+static int testFailed = 0;
+
+template<typename T>
+void check( const char *file, int line, const char* msg,
+const T& result, const T& expected )
+{
+ testCount++;
+ if( result != expected )
+ {
+ testFailed++;
+ QString message;
+ QTextStream ts( &message, IO_WriteOnly );
+ ts << msg;
+ ts << " Result:";
+ ts << result;
+ ts << ", ";
+ ts << "Expected:";
+ ts << expected;
+ printf( "%s [%d]: %s\n", file, line, message.latin1() );
+ }
+}
+
+void check( const char *file, int line, const char* msg, bool result,
+bool expected )
+{
+ testCount++;
+ if( result != expected )
+ {
+ testFailed++;
+ QString message;
+ QTextStream ts( &message, IO_WriteOnly );
+ ts << msg;
+ ts << " Result: ";
+ if( result ) ts << "True"; else ts << "False";
+ ts << ", ";
+ ts << "Expected: ";
+ if( expected ) ts << "True"; else ts << "False";
+ printf( "%s [%d]: %s\n", file, line, message.latin1() );
+ }
+}
+
+void testNode()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<earth>";
+ xmlstream << "<continents>";
+ xmlstream << "<asia/>";
+ xmlstream << "<africa/>";
+ xmlstream << "<europe/>";
+ xmlstream << "<america/>";
+ xmlstream << "<australia/>";
+ xmlstream << "<antartic/>";
+ xmlstream << "</continents>";
+ xmlstream << "<oceans>";
+ xmlstream << "<pacific/>";
+ xmlstream << "<atlantic/>";
+ xmlstream << "</oceans>";
+ xmlstream << "</earth>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // null node
+ KoXmlNode node1;
+ CHECK( node1.nodeName(), QString::null );
+ CHECK( node1.isNull(), true );
+ CHECK( node1.isElement(), false );
+ CHECK( node1.isElement(), false );
+ CHECK( node1.isDocument(), false );
+ CHECK( node1.ownerDocument().isNull(), false );
+ CHECK( node1.parentNode().isNull(), true );
+ CHECK( node1.hasChildNodes(), false );
+ CHECK( node1.firstChild().isNull(), true );
+ CHECK( node1.lastChild().isNull(), true );
+ CHECK( node1.previousSibling().isNull(), true );
+ CHECK( node1.nextSibling().isNull(), true );
+
+ // compare with another null node
+ KoXmlNode node2;
+ CHECK( node2.isNull(), true );
+ CHECK( node1==node2, true );
+ CHECK( node1!=node2, false );
+
+ // a node which is a document
+ KoXmlNode node3 = doc;
+ CHECK( node3.nodeName(), QString("#document") );
+ CHECK( node3.isNull(), false );
+ CHECK( node3.isElement(), false );
+ CHECK( node3.isText(), false );
+ CHECK( node3.isDocument(), true );
+ CHECK( node3.ownerDocument().isNull(), false );
+ CHECK( node3.ownerDocument()==doc, true );
+ CHECK( node3.toDocument()==doc, true );
+
+ // convert to document and the compare
+ KoXmlDocument doc2 = node3.toDocument();
+ CHECK( doc2.nodeName(), QString("#document") );
+ CHECK( doc2.isNull(), false );
+ CHECK( doc2.isDocument(), true );
+ CHECK( node3==doc2, true );
+
+ // a document is of course can't be converted to element
+ KoXmlElement invalidElement = node3.toElement();
+ CHECK( invalidElement.nodeName(), QString::null );
+ CHECK( invalidElement.isNull(), true );
+ CHECK( invalidElement.isElement(), true );
+ CHECK( invalidElement.isText(), false );
+ CHECK( invalidElement.isDocument(), false );
+
+ // clear() makes it a null node again
+ node3.clear();
+ CHECK( node3.isNull(), true );
+ CHECK( node3.nodeName(), QString::null );
+ CHECK( node3.isElement(), false );
+ CHECK( node3.isText(), false );
+ CHECK( node3.isDocument(), false );
+ CHECK( node3.ownerDocument().isNull(), false );
+ CHECK( node1==node3, true );
+ CHECK( node1!=node3, false );
+
+ // a node which is an element for <earth>
+ KoXmlNode node4 = doc.firstChild();
+ CHECK( node4.isNull(), false );
+ CHECK( node4.isElement(), true );
+ CHECK( node4.isText(), false );
+ CHECK( node4.isDocument(), false );
+ CHECK( node4.hasChildNodes(), true );
+ CHECK( node4.ownerDocument()==doc, true );
+ CHECK( node4.toElement()==doc.firstChild().toElement(), true );
+
+ // clear() makes it a null node again
+ node4.clear();
+ CHECK( node4.isNull(), true );
+ CHECK( node4.isElement(), false );
+ CHECK( node4.isText(), false );
+ CHECK( node4.isDocument(), false );
+ CHECK( node4==node1, true );
+ CHECK( node4!=node1, false );
+
+ // a node which is an element for <continents>
+ KoXmlNode node5 = doc.firstChild().firstChild();
+ CHECK( node5.nodeName(), QString("continents") );
+ CHECK( node5.isNull(), false );
+ CHECK( node5.isElement(), true );
+ CHECK( node5.isText(), false );
+ CHECK( node5.isDocument(), false );
+ CHECK( node5.hasChildNodes(), true );
+ CHECK( node5.ownerDocument()==doc, true );
+
+ // convert to element and the compare
+ KoXmlElement continentsElement = node5.toElement();
+ CHECK( node5==continentsElement, true );
+ CHECK( continentsElement.isNull(), false );
+ CHECK( continentsElement.isElement(), true );
+ CHECK( continentsElement.isText(), false );
+ CHECK( continentsElement.hasChildNodes(), true );
+ CHECK( continentsElement.ownerDocument()==doc, true );
+
+ // and it doesn't make sense to convert that node to document
+ // (instead a brand new document is created, i.e. not a null node)
+ KoXmlDocument invalidDoc = node5.toDocument();
+ CHECK( invalidDoc.isNull(), false );
+ CHECK( invalidDoc.isElement(), false );
+ CHECK( invalidDoc.isText(), false );
+ CHECK( invalidDoc.isDocument(), true );
+
+ // node for <europe> using namedItem() function
+ KoXmlNode europeNode = continentsElement.namedItem( QString("europe") );
+ CHECK( europeNode.nodeName(), QString("europe") );
+ CHECK( europeNode.isNull(), false );
+ CHECK( europeNode.isElement(), true );
+ CHECK( europeNode.isText(), false );
+ CHECK( europeNode.hasChildNodes(), false );
+ CHECK( europeNode.ownerDocument()==doc, true );
+
+ // search non-existing node
+ KoXmlNode fooNode = continentsElement.namedItem( QString("foobar") );
+ CHECK( fooNode.isNull(), true );
+ CHECK( fooNode.isElement(), false );
+ CHECK( fooNode.isText(), false );
+ CHECK( fooNode.isCDATASection(), false );
+}
+
+void testElement()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<html>";
+ xmlstream << "<body bgcolor=\"#000\">";
+ xmlstream << "<p>";
+ xmlstream << "Hello, world!";
+ xmlstream << "</p>";
+ xmlstream << "</body>";
+ xmlstream << "</html>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // element for <html>
+ KoXmlElement rootElement;
+ rootElement = doc.documentElement();
+ CHECK( rootElement.nodeName(), QString("html") );
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.isDocument(), false );
+ CHECK( rootElement.ownerDocument().isNull(), false );
+ CHECK( rootElement.ownerDocument()==doc, true );
+ CHECK( rootElement.parentNode().isNull(), false );
+ CHECK( rootElement.parentNode().toDocument()==doc, true );
+ CHECK( rootElement.hasChildNodes(), true );
+ CHECK( rootElement.tagName(), QString("html") );
+ CHECK( rootElement.prefix().isNull(), true );
+
+ // element for <body>
+ KoXmlElement bodyElement;
+ bodyElement = rootElement.firstChild().toElement();
+ CHECK( bodyElement.nodeName(), QString("body") );
+ CHECK( bodyElement.isNull(), false );
+ CHECK( bodyElement.isElement(), true );
+ CHECK( bodyElement.isDocument(), false );
+ CHECK( bodyElement.ownerDocument().isNull(), false );
+ CHECK( bodyElement.ownerDocument()==doc, true );
+ CHECK( bodyElement.parentNode().isNull(), false );
+ CHECK( bodyElement.parentNode()==rootElement, true );
+ CHECK( bodyElement.hasChildNodes(), true );
+ CHECK( bodyElement.tagName(), QString("body") );
+ CHECK( bodyElement.prefix().isNull(), true );
+ CHECK( bodyElement.hasAttribute("bgcolor"), true );
+ CHECK( bodyElement.attribute("bgcolor"), QString("#000") );
+
+ // a shared copy of <body>, will still have access to attribute bgcolor
+ KoXmlElement body2Element;
+ body2Element = bodyElement;
+ CHECK( body2Element.nodeName(), QString("body") );
+ CHECK( body2Element.isNull(), false );
+ CHECK( body2Element.isElement(), true );
+ CHECK( body2Element.isDocument(), false );
+ CHECK( body2Element.ownerDocument().isNull(), false );
+ CHECK( body2Element.ownerDocument()==doc, true );
+ CHECK( body2Element==bodyElement, true );
+ CHECK( body2Element!=bodyElement, false );
+ CHECK( body2Element.hasChildNodes(), true );
+ CHECK( body2Element.tagName(), QString("body") );
+ CHECK( body2Element.prefix().isNull(), true );
+ CHECK( body2Element.hasAttribute("bgcolor"), true );
+ CHECK( body2Element.attribute("bgcolor"), QString("#000") );
+
+ // empty element, by default constructor
+ KoXmlElement testElement;
+ CHECK( testElement.nodeName(), QString::null );
+ CHECK( testElement.isNull(), true );
+ CHECK( testElement.isElement(), true );
+ CHECK( testElement.isDocument(), false );
+ CHECK( testElement.ownerDocument().isNull(), false );
+ CHECK( testElement.ownerDocument()!=doc, true );
+ CHECK( testElement==rootElement, false );
+ CHECK( testElement!=rootElement, true );
+ CHECK( testElement.parentNode().isNull(), true );
+ CHECK( testElement.hasChildNodes(), false );
+
+ // check assignment operator
+ testElement = rootElement;
+ CHECK( testElement.nodeName(), QString("html") );
+ CHECK( testElement.isNull(), false );
+ CHECK( testElement.isElement(), true );
+ CHECK( testElement.isDocument(), false );
+ CHECK( testElement==rootElement, true );
+ CHECK( testElement!=rootElement, false );
+ CHECK( testElement.parentNode().isNull(), false );
+ CHECK( testElement.parentNode().toDocument()==doc, true );
+ CHECK( testElement.tagName(), QString("html") );
+ CHECK( testElement.prefix().isNull(), true );
+
+ // assigned from another empty element
+ testElement = KoXmlElement();
+ CHECK( testElement.isNull(), true );
+ CHECK( testElement!=rootElement, true );
+
+ // assigned from <body>
+ testElement = bodyElement;
+ CHECK( testElement.isNull(), false );
+ CHECK( testElement.isElement(), true );
+ CHECK( testElement.isDocument(), false );
+ CHECK( testElement.ownerDocument().isNull(), false );
+ CHECK( testElement.ownerDocument()==doc, true );
+ CHECK( testElement==bodyElement, true );
+ CHECK( testElement.parentNode().isNull(), false );
+ CHECK( testElement.tagName(), QString("body") );
+ CHECK( testElement.prefix().isNull(), true );
+ CHECK( testElement.hasChildNodes(), true );
+
+ // copy constructor
+ KoXmlElement dummyElement( rootElement );
+ CHECK( dummyElement.isNull(), false );
+ CHECK( dummyElement.isElement(), true );
+ CHECK( dummyElement.isDocument(), false );
+ CHECK( dummyElement.ownerDocument().isNull(), false );
+ CHECK( dummyElement.ownerDocument()==doc, true );
+ CHECK( dummyElement==rootElement, true );
+ CHECK( dummyElement.parentNode().isNull(), false );
+ CHECK( dummyElement.hasChildNodes(), true );
+ CHECK( dummyElement.tagName(), QString("html") );
+ CHECK( dummyElement.prefix().isNull(), true );
+
+ // clear() turns element to null node
+ dummyElement.clear();
+ CHECK( dummyElement.isNull(), true );
+ CHECK( dummyElement.isElement(), true );
+ CHECK( dummyElement.isDocument(), false );
+ CHECK( dummyElement.ownerDocument().isNull(), false );
+ CHECK( dummyElement.ownerDocument()==doc, false );
+ CHECK( dummyElement.hasChildNodes(), false );
+ CHECK( dummyElement==rootElement, false );
+ CHECK( dummyElement!=rootElement, true );
+
+ // check for plain null node converted to element
+ KoXmlNode dummyNode;
+ dummyElement = dummyNode.toElement();
+ CHECK( dummyElement.isNull(), true );
+ CHECK( dummyElement.isElement(), true );
+ CHECK( dummyElement.isDocument(), false );
+ CHECK( dummyElement.ownerDocument().isNull(), false );
+ CHECK( dummyElement.hasChildNodes(), false );
+ CHECK( dummyElement.ownerDocument()==doc, false );
+}
+
+void testAttributes()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<p>";
+ xmlstream << "<img src=\"foo.png\" width=\"300\" height=\"150\"/>";
+ xmlstream << "</p>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ KoXmlElement rootElement;
+ rootElement = doc.documentElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.parentNode().isNull(), false );
+ CHECK( rootElement.parentNode().toDocument()==doc, true );
+ CHECK( rootElement.tagName(), QString("p") );
+ CHECK( rootElement.prefix().isNull(), true );
+
+ KoXmlElement imgElement;
+ imgElement = rootElement.firstChild().toElement();
+ CHECK( imgElement.isNull(), false );
+ CHECK( imgElement.isElement(), true );
+ CHECK( imgElement.tagName(), QString("img") );
+ CHECK( imgElement.prefix().isNull(), true );
+ CHECK( imgElement.hasAttribute("src"), true );
+ CHECK( imgElement.hasAttribute("width"), true );
+ CHECK( imgElement.hasAttribute("height"), true );
+ CHECK( imgElement.hasAttribute("non-exist"), false );
+ CHECK( imgElement.hasAttribute("SRC"), false );
+ CHECK( imgElement.attribute("src"), QString("foo.png") );
+ CHECK( imgElement.attribute("width"), QString("300") );
+ CHECK( imgElement.attribute("width").toInt(), 300 );
+ CHECK( imgElement.attribute("height"), QString("150") );
+ CHECK( imgElement.attribute("height").toInt(), 150 );
+ CHECK( imgElement.attribute("border").isEmpty(), true );
+ CHECK( imgElement.attribute("border","0").toInt(), 0 );
+ CHECK( imgElement.attribute("border","-1").toInt(), -1 );
+}
+
+void testText()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<p>";
+ xmlstream << "Hello ";
+ xmlstream << "<b>world</b>";
+ xmlstream << "</p>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // element for <p>
+ KoXmlElement parElement;
+ parElement = doc.documentElement();
+ CHECK( parElement.isNull(), false );
+ CHECK( parElement.isElement(), true );
+ CHECK( parElement.isText(), false );
+ CHECK( parElement.isDocument(), false );
+ CHECK( parElement.ownerDocument().isNull(), false );
+ CHECK( parElement.ownerDocument()==doc, true );
+ CHECK( parElement.parentNode().isNull(), false );
+ CHECK( parElement.parentNode().toDocument()==doc, true );
+ CHECK( parElement.hasChildNodes(), true );
+ CHECK( parElement.tagName(), QString("p") );
+ CHECK( parElement.prefix().isNull(), true );
+ CHECK( parElement.text(), QString("Hello world") );
+
+ // node for "Hello"
+ KoXmlNode helloNode;
+ helloNode = parElement.firstChild();
+ CHECK( helloNode.nodeName(), QString("#text") );
+ CHECK( helloNode.isNull(), false );
+ CHECK( helloNode.isElement(), false );
+ CHECK( helloNode.isText(), true );
+ CHECK( helloNode.isDocument(), false );
+
+ // "Hello" text
+ KoXmlText helloText;
+ helloText = helloNode.toText();
+ CHECK( helloText.nodeName(), QString("#text") );
+ CHECK( helloText.isNull(), false );
+ CHECK( helloText.isElement(), false );
+ CHECK( helloText.isText(), true );
+ CHECK( helloText.isDocument(), false );
+ CHECK( helloText.data(), QString("Hello ") );
+
+ // shared copy of the text
+ KoXmlText hello2Text;
+ hello2Text = helloText;
+ CHECK( hello2Text.isNull(), false );
+ CHECK( hello2Text.isElement(), false );
+ CHECK( hello2Text.isText(), true );
+ CHECK( hello2Text.isDocument(), false );
+ CHECK( hello2Text.data(), QString("Hello ") );
+
+ // element for <b>
+ KoXmlElement boldElement;
+ boldElement = helloNode.nextSibling().toElement();
+ CHECK( boldElement.isNull(), false );
+ CHECK( boldElement.isElement(), true );
+ CHECK( boldElement.isText(), false );
+ CHECK( boldElement.isDocument(), false );
+ CHECK( boldElement.ownerDocument().isNull(), false );
+ CHECK( boldElement.ownerDocument()==doc, true );
+ CHECK( boldElement.parentNode().isNull(), false );
+ CHECK( boldElement.hasChildNodes(), true );
+ CHECK( boldElement.tagName(), QString("b") );
+ CHECK( boldElement.prefix().isNull(), true );
+
+ // "world" text
+ KoXmlText worldText;
+ worldText = boldElement.firstChild().toText();
+ CHECK( worldText.isNull(), false );
+ CHECK( worldText.isElement(), false );
+ CHECK( worldText.isText(), true );
+ CHECK( worldText.isDocument(), false );
+ CHECK( worldText.data(), QString("world") );
+}
+
+void testCDATA()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<p>";
+ xmlstream << "Hello ";
+ xmlstream << "<![CDATA[world]]>";
+ xmlstream << "</p>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // element for <p>
+ KoXmlElement parElement;
+ parElement = doc.documentElement();
+ CHECK( parElement.isNull(), false );
+ CHECK( parElement.isElement(), true );
+ CHECK( parElement.isText(), false );
+ CHECK( parElement.isDocument(), false );
+ CHECK( parElement.ownerDocument().isNull(), false );
+ CHECK( parElement.ownerDocument()==doc, true );
+ CHECK( parElement.parentNode().isNull(), false );
+ CHECK( parElement.parentNode().toDocument()==doc, true );
+ CHECK( parElement.hasChildNodes(), true );
+ CHECK( parElement.tagName(), QString("p") );
+ CHECK( parElement.prefix().isNull(), true );
+ CHECK( parElement.text(), QString("Hello world") );
+
+ // node for "Hello"
+ KoXmlNode helloNode;
+ helloNode = parElement.firstChild();
+ CHECK( helloNode.isNull(), false );
+ CHECK( helloNode.isElement(), false );
+ CHECK( helloNode.isText(), true );
+ CHECK( helloNode.isDocument(), false );
+
+ // "Hello" text
+ KoXmlText helloText;
+ helloText = helloNode.toText();
+ CHECK( helloText.isNull(), false );
+ CHECK( helloText.isElement(), false );
+ CHECK( helloText.isText(), true );
+ CHECK( helloText.isDocument(), false );
+ CHECK( helloText.data(), QString("Hello ") );
+
+ // node for CDATA "world!"
+ // Note: isText() is also true for CDATA
+ KoXmlNode worldNode;
+ worldNode = helloNode.nextSibling();
+ CHECK( worldNode.nodeName(), QString("#cdata-section") );
+ CHECK( worldNode.isNull(), false );
+ CHECK( worldNode.isElement(), false );
+ CHECK( worldNode.isText(), true );
+ CHECK( worldNode.isCDATASection(), true );
+ CHECK( worldNode.isDocument(), false );
+
+ // CDATA section for "world!"
+ // Note: isText() is also true for CDATA
+ KoXmlCDATASection worldCDATA;
+ worldCDATA = worldNode.toCDATASection();
+ CHECK( worldCDATA.nodeName(), QString("#cdata-section") );
+ CHECK( worldCDATA.isNull(), false );
+ CHECK( worldCDATA.isElement(), false );
+ CHECK( worldCDATA.isText(), true );
+ CHECK( worldCDATA.isCDATASection(), true );
+ CHECK( worldCDATA.isDocument(), false );
+ CHECK( worldCDATA.data(), QString("world") );
+}
+
+void testDocument()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<koffice>";
+ xmlstream << " <kword/>\n";
+ xmlstream << " <kpresenter/>\n";
+ xmlstream << " <krita/>\n";
+ xmlstream << "</koffice>";
+
+ KoXmlDocument doc;
+
+ // empty document
+ CHECK( doc.nodeName(), QString("#document") );
+ CHECK( doc.isNull(), false );
+ CHECK( doc.isElement(), false );
+ CHECK( doc.isDocument(), true );
+ CHECK( doc.parentNode().isNull(), true );
+ CHECK( doc.firstChild().isNull(), true );
+ CHECK( doc.lastChild().isNull(), true );
+ CHECK( doc.previousSibling().isNull(), true );
+ CHECK( doc.nextSibling().isNull(), true );
+
+ // now give something as the content
+ CHECK( doc.setContent(&xmldevice,&errorMsg,&errorLine,&errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // this document has something already
+ CHECK( doc.nodeName(), QString("#document") );
+ CHECK( doc.isNull(), false );
+ CHECK( doc.isElement(), false );
+ CHECK( doc.isDocument(), true );
+ CHECK( doc.parentNode().isNull(), true );
+ CHECK( doc.firstChild().isNull(), false );
+ CHECK( doc.lastChild().isNull(), false );
+ CHECK( doc.previousSibling().isNull(), true );
+ CHECK( doc.nextSibling().isNull(), true );
+
+ // make sure its children are fine
+ KoXmlElement rootElement;
+ rootElement = doc.firstChild().toElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.isDocument(), false );
+ CHECK( rootElement.parentNode().isNull(), false );
+ CHECK( rootElement.parentNode().toDocument()==doc, true );
+ rootElement = doc.lastChild().toElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.isDocument(), false );
+ CHECK( rootElement.parentNode().isNull(), false );
+ CHECK( rootElement.parentNode().toDocument()==doc, true );
+
+ // clear() converts it into null node
+ doc.clear();
+ CHECK( doc.nodeName(), QString::null );
+ CHECK( doc.isNull(), true );
+ CHECK( doc.isElement(), false );
+ CHECK( doc.isDocument(), true );
+ CHECK( doc.parentNode().isNull(), true );
+ CHECK( doc.firstChild().isNull(), true );
+ CHECK( doc.lastChild().isNull(), true );
+ CHECK( doc.previousSibling().isNull(), true );
+ CHECK( doc.nextSibling().isNull(), true );
+
+ // assigned from another empty document
+ doc = KoXmlDocument();
+ CHECK( doc.nodeName(), QString("#document") );
+ CHECK( doc.isNull(), false );
+ CHECK( doc.isElement(), false );
+ CHECK( doc.isDocument(), true );
+ CHECK( doc.parentNode().isNull(), true );
+}
+
+void testNamespace()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // taken from example in Qt documentation (xml.html)
+ xmlstream << "<document xmlns:book = \"http://trolltech.com/fnord/book/\"";
+ xmlstream << " xmlns = \"http://trolltech.com/fnord/\" >";
+ xmlstream << "<book>";
+ xmlstream << " <book:title>Practical XML</book:title>";
+ xmlstream << " <book:author xmlns:fnord = \"http://trolltech.com/fnord/\"";
+ xmlstream << " title=\"Ms\"";
+ xmlstream << " fnord:title=\"Goddess\"";
+ xmlstream << " name=\"Eris Kallisti\"/>";
+ xmlstream << " <chapter>";
+ xmlstream << " <title>A Namespace Called fnord</title>";
+ xmlstream << " </chapter>";
+ xmlstream << "</book>";
+ xmlstream << "</document>";
+
+ KoXmlDocument doc;
+ KoXmlElement rootElement;
+ KoXmlElement bookElement;
+ KoXmlElement bookTitleElement;
+ KoXmlElement bookAuthorElement;
+
+ // ------------- first without any namespace processing -----------
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ rootElement = doc.documentElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.tagName(), QString("document") );
+ CHECK( rootElement.prefix().isNull(), true );
+
+ bookElement = rootElement.firstChild().toElement();
+ CHECK( bookElement.isNull(), false );
+ CHECK( bookElement.isElement(), true );
+ CHECK( bookElement.tagName(), QString("book") );
+ CHECK( bookElement.prefix().isNull(), true );
+ CHECK( bookElement.localName(), QString::null );
+
+ bookTitleElement = bookElement.firstChild().toElement();
+ CHECK( bookTitleElement.isNull(), false );
+ CHECK( bookTitleElement.isElement(), true );
+ CHECK( bookTitleElement.tagName(), QString("book:title") );
+ CHECK( bookTitleElement.prefix().isNull(), true );
+ CHECK( bookTitleElement.localName(), QString::null );
+
+ bookAuthorElement = bookTitleElement.nextSibling().toElement();
+ CHECK( bookAuthorElement.isNull(), false );
+ CHECK( bookAuthorElement.isElement(), true );
+ CHECK( bookAuthorElement.tagName(), QString("book:author") );
+ CHECK( bookAuthorElement.prefix().isNull(), true );
+ CHECK( bookAuthorElement.attribute("title"), QString("Ms") );
+ CHECK( bookAuthorElement.attribute("fnord:title"), QString("Goddess") );
+ CHECK( bookAuthorElement.attribute("name"), QString("Eris Kallisti") );
+
+ // ------------- now with namespace processing -----------
+ xmldevice.at(0); // just to rewind
+
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ char* defaultNS = "http://trolltech.com/fnord/";
+ char* bookNS = "http://trolltech.com/fnord/book/";
+ char* fnordNS = "http://trolltech.com/fnord/";
+
+ // <document>
+ rootElement = doc.documentElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.tagName(), QString("document") );
+ CHECK( rootElement.prefix().isEmpty(), true );
+ CHECK( rootElement.namespaceURI(), QString( defaultNS ) );
+ CHECK( rootElement.localName(), QString("document") );
+
+ // <book>
+ bookElement = rootElement.firstChild().toElement();
+ CHECK( bookElement.isNull(), false );
+ CHECK( bookElement.isElement(), true );
+ CHECK( bookElement.tagName(), QString("book") );
+ CHECK( bookElement.prefix().isEmpty(), true );
+ CHECK( bookElement.namespaceURI(), QString( defaultNS ) );
+ CHECK( bookElement.localName(), QString("book") );
+
+ // <book:title>
+ bookTitleElement = bookElement.firstChild().toElement();
+ CHECK( bookTitleElement.isNull(), false );
+ CHECK( bookTitleElement.isElement(), true );
+ CHECK( bookTitleElement.tagName(), QString("title") );
+ CHECK( bookTitleElement.prefix(), QString("book") );
+ CHECK( bookTitleElement.namespaceURI(), QString(bookNS) );
+ CHECK( bookTitleElement.localName(), QString("title") );
+
+ // another way, find it using namedItemNS()
+ KoXmlElement book2TitleElement;
+ book2TitleElement = KoXml::namedItemNS( rootElement.firstChild(), bookNS, "title" );
+ //book2TitleElement = bookElement.namedItemNS( bookNS, "title" ).toElement();
+ CHECK( book2TitleElement==bookTitleElement, true );
+ CHECK( book2TitleElement.isNull(), false );
+ CHECK( book2TitleElement.isElement(), true );
+ CHECK( book2TitleElement.tagName(), QString("title") );
+
+ // <book:author>
+ bookAuthorElement = bookTitleElement.nextSibling().toElement();
+ CHECK( bookAuthorElement.isNull(), false );
+ CHECK( bookAuthorElement.isElement(), true );
+ CHECK( bookAuthorElement.tagName(), QString("author") );
+ CHECK( bookAuthorElement.prefix(), QString("book") );
+ CHECK( bookAuthorElement.namespaceURI(), QString(bookNS) );
+ CHECK( bookAuthorElement.localName(), QString("author") );
+
+ // another way, find it using namedItemNS()
+ KoXmlElement book2AuthorElement;
+ book2AuthorElement = KoXml::namedItemNS( bookElement, bookNS, "author" );
+ //book2AuthorElement = bookElement.namedItemNS( bookNS, "author" ).toElement();
+ CHECK( book2AuthorElement==bookAuthorElement, true );
+ CHECK( book2AuthorElement.isNull(), false );
+ CHECK( book2AuthorElement.isElement(), true );
+ CHECK( book2AuthorElement.tagName(), QString("author") );
+
+ // attributes in <book:author>
+ // Note: with namespace processing, attribute's prefix is taken out and
+ // hence "fnord:title" will simply override "title"
+ // and searching attribute with prefix will give no result
+ CHECK( bookAuthorElement.hasAttribute("title"), true );
+ CHECK( bookAuthorElement.hasAttribute("fnord:title"), false );
+ CHECK( bookAuthorElement.hasAttribute("name"), true );
+ CHECK( bookAuthorElement.attribute("title"), QString("Goddess") );
+ CHECK( bookAuthorElement.attribute("fnord:title").isEmpty(), true );
+ CHECK( bookAuthorElement.attribute("name"), QString("Eris Kallisti") );
+
+ // attributes in <book:author>, with NS family of functions
+ // those without prefix are not accessible at all, because they do not belong
+ // to any namespace at all.
+ // Note: default namespace does not apply to attribute names!
+ CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"title"), true );
+ CHECK( bookAuthorElement.hasAttributeNS(bookNS,"title"), false );
+ CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"title"), true );
+
+ CHECK( bookAuthorElement.attributeNS(defaultNS,"title",""), QString("Goddess") );
+ CHECK( bookAuthorElement.attributeNS(bookNS,"title",""), QString("") );
+ CHECK( bookAuthorElement.attributeNS(fnordNS,"title",""), QString("Goddess") );
+
+ CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"fnord:title"), false );
+ CHECK( bookAuthorElement.hasAttributeNS(bookNS,"fnord:title"), false );
+ CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"fnord:title"), false );
+
+ CHECK( bookAuthorElement.hasAttributeNS(defaultNS,"name"), false );
+ CHECK( bookAuthorElement.hasAttributeNS(bookNS,"name"), false );
+ CHECK( bookAuthorElement.hasAttributeNS(fnordNS,"name"), false );
+
+ CHECK( bookAuthorElement.attributeNS(defaultNS,"name",QString::null).isEmpty(), true );
+ CHECK( bookAuthorElement.attributeNS(bookNS,"name",QString::null).isEmpty(), true );
+ CHECK( bookAuthorElement.attributeNS(fnordNS,"name",QString::null).isEmpty(), true );
+}
+
+void testUnload()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<earth>";
+ xmlstream << "<continents>";
+ xmlstream << "<asia/>";
+ xmlstream << "<africa/>";
+ xmlstream << "<europe/>";
+ xmlstream << "<america/>";
+ xmlstream << "<australia/>";
+ xmlstream << "<antartic/>";
+ xmlstream << "</continents>";
+ xmlstream << "<oceans>";
+ xmlstream << "<pacific/>";
+ xmlstream << "<atlantic/>";
+ xmlstream << "</oceans>";
+ xmlstream << "</earth>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ KoXmlElement earthElement;
+ earthElement = doc.documentElement().toElement();
+ CHECK( earthElement.isNull(), false );
+ CHECK( earthElement.isElement(), true );
+ CHECK( earthElement.parentNode().isNull(), false );
+ CHECK( earthElement.hasChildNodes(), true );
+ CHECK( earthElement.tagName(), QString("earth") );
+ CHECK( earthElement.prefix().isNull(), true );
+
+ // this ensures that all child nodes of <earth> are loaded
+ earthElement.firstChild();
+
+ // explicitly unload all child nodes of <earth>
+ KoXml::unload( earthElement );
+
+ // we should get the correct first child
+ KoXmlElement continentsElement = earthElement.firstChild().toElement();
+ CHECK( continentsElement.nodeName(), QString("continents") );
+ CHECK( continentsElement.isNull(), false );
+ CHECK( continentsElement.isElement(), true );
+ CHECK( continentsElement.isText(), false );
+ CHECK( continentsElement.isDocument(), false );
+ CHECK( continentsElement.hasChildNodes(), true );
+
+ // let us unload everything again
+ KoXml::unload( earthElement );
+
+ // we should get the correct last child
+ KoXmlElement oceansElement = earthElement.lastChild().toElement();
+ CHECK( oceansElement.nodeName(), QString("oceans") );
+ CHECK( oceansElement.isNull(), false );
+ CHECK( oceansElement.isElement(), true );
+ CHECK( oceansElement.isText(), false );
+ CHECK( oceansElement.isDocument(), false );
+ CHECK( oceansElement.hasChildNodes(), true );
+}
+
+void testSimpleXML()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<solarsystem>";
+ xmlstream << " <mercurius/>\n";
+ xmlstream << " <venus/>\n";
+ xmlstream << " <earth>\n";
+ xmlstream << " <moon/>\n";
+ xmlstream << " </earth>\n";
+ xmlstream << " <mars/>\n";
+ xmlstream << " <jupiter/>\n";
+ xmlstream << "</solarsystem>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent(&xmldevice,&errorMsg,&errorLine,&errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ // <solarsystem>
+ KoXmlElement rootElement;
+ rootElement = doc.documentElement();
+ CHECK( rootElement.isNull(), false );
+ CHECK( rootElement.isElement(), true );
+ CHECK( rootElement.parentNode().isNull(), false );
+ CHECK( rootElement.hasChildNodes(), true );
+ CHECK( rootElement.tagName(), QString("solarsystem") );
+ CHECK( rootElement.prefix().isNull(), true );
+
+ // node <mercurius>
+ KoXmlNode firstPlanetNode;
+ firstPlanetNode = rootElement.firstChild();
+ CHECK( firstPlanetNode.isNull(), false );
+ CHECK( firstPlanetNode.isElement(), true );
+ CHECK( firstPlanetNode.nextSibling().isNull(), false );
+ CHECK( firstPlanetNode.previousSibling().isNull(), true );
+ CHECK( firstPlanetNode.parentNode().isNull(), false );
+ CHECK( firstPlanetNode.parentNode()==rootElement, true );
+ CHECK( firstPlanetNode.parentNode()!=rootElement, false );
+ CHECK( firstPlanetNode.hasChildNodes(), false );
+ CHECK( firstPlanetNode.firstChild().isNull(), true );
+ CHECK( firstPlanetNode.lastChild().isNull(), true );
+
+ // element <mercurius>
+ KoXmlElement firstPlanetElement;
+ firstPlanetElement = firstPlanetNode.toElement();
+ CHECK( firstPlanetElement.isNull(), false );
+ CHECK( firstPlanetElement.isElement(), true );
+ CHECK( firstPlanetElement.parentNode().isNull(), false );
+ CHECK( firstPlanetElement.parentNode()==rootElement, true );
+ CHECK( firstPlanetElement.hasChildNodes(), false );
+ CHECK( firstPlanetElement.firstChild().isNull(), true );
+ CHECK( firstPlanetElement.lastChild().isNull(), true );
+ CHECK( firstPlanetElement.tagName(), QString("mercurius") );
+ CHECK( firstPlanetElement.prefix().isNull(), true );
+
+ // node <venus>
+ KoXmlNode secondPlanetNode;
+ secondPlanetNode = firstPlanetNode.nextSibling();
+ CHECK( secondPlanetNode.isNull(), false );
+ CHECK( secondPlanetNode.isElement(), true );
+ CHECK( secondPlanetNode.nextSibling().isNull(), false );
+ CHECK( secondPlanetNode.previousSibling().isNull(), false );
+ CHECK( secondPlanetNode.previousSibling()==firstPlanetNode, true );
+ CHECK( secondPlanetNode.previousSibling()==firstPlanetElement, true );
+ CHECK( secondPlanetNode.parentNode().isNull(), false );
+ CHECK( secondPlanetNode.parentNode()==rootElement, true );
+ CHECK( secondPlanetNode.parentNode()!=rootElement, false );
+ CHECK( secondPlanetNode.hasChildNodes(), false );
+ CHECK( secondPlanetNode.firstChild().isNull(), true );
+ CHECK( secondPlanetNode.lastChild().isNull(), true );
+
+ // element <venus>
+ KoXmlElement secondPlanetElement;
+ secondPlanetElement = secondPlanetNode.toElement();
+ CHECK( secondPlanetElement.isNull(), false );
+ CHECK( secondPlanetElement.isElement(), true );
+ CHECK( secondPlanetElement.nextSibling().isNull(), false );
+ CHECK( secondPlanetElement.previousSibling().isNull(), false );
+ CHECK( secondPlanetElement.previousSibling()==firstPlanetNode, true );
+ CHECK( secondPlanetElement.previousSibling()==firstPlanetElement, true );
+ CHECK( secondPlanetElement.parentNode().isNull(), false );
+ CHECK( secondPlanetElement.parentNode()==rootElement, true );
+ CHECK( secondPlanetElement.parentNode()!=rootElement, false );
+ CHECK( secondPlanetElement.hasChildNodes(), false );
+ CHECK( secondPlanetElement.firstChild().isNull(), true );
+ CHECK( secondPlanetElement.lastChild().isNull(), true );
+ CHECK( secondPlanetElement.tagName(), QString("venus") );
+ CHECK( secondPlanetElement.prefix().isNull(), true );
+}
+
+void testRootError()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ // multiple root nodes are not valid !
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<earth></earth><moon></moon>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), false );
+ CHECK( errorMsg.isEmpty(), false );
+ CHECK( errorMsg, QString("unexpected character") );
+ CHECK( errorLine, 1 );
+ CHECK( errorColumn, 17 );
+}
+
+void testMismatchedTag()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+ xmlstream << "<earth></e>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, &errorMsg, &errorLine, &errorColumn ), false );
+ CHECK( errorMsg.isEmpty(), false );
+ CHECK( errorMsg, QString("tag mismatch") );
+ CHECK( errorLine, 1 );
+ CHECK( errorColumn, 11 );
+}
+
+void testSimpleOpenDocumentText()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // content.xml from a simple OpenDocument text
+ // it has only paragraph "Hello, world!"
+ // automatic styles, declarations and unnecessary namespaces are omitted.
+ xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ xmlstream << "<office:document-content ";
+ xmlstream << " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"";
+ xmlstream << " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"";
+ xmlstream << " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
+ xmlstream << " office:version=\"1.0\">";
+ xmlstream << " <office:automatic-styles/>";
+ xmlstream << " <office:body>";
+ xmlstream << " <office:text>";
+ xmlstream << " <text:p text:style-name=\"Standard\">Hello, world!</text:p>";
+ xmlstream << " </office:text>";
+ xmlstream << " </office:body>";
+ xmlstream << "</office:document-content>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ char* officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+ char* textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+
+ // <office:document-content>
+ KoXmlElement contentElement;
+ contentElement = doc.documentElement();
+ CHECK( contentElement.isNull(), false );
+ CHECK( contentElement.isElement(), true );
+ CHECK( contentElement.parentNode().isNull(), false );
+ CHECK( contentElement.parentNode().toDocument()==doc, true );
+ CHECK( contentElement.firstChild().isNull(), false );
+ CHECK( contentElement.lastChild().isNull(), false );
+ CHECK( contentElement.previousSibling().isNull(), false );
+ CHECK( contentElement.nextSibling().isNull(), true );
+ CHECK( contentElement.localName(), QString("document-content") );
+ CHECK( contentElement.hasAttributeNS(officeNS,"version"), true );
+ CHECK( contentElement.attributeNS(officeNS,"version",""), QString("1.0") );
+
+ // <office:automatic-styles>
+ KoXmlElement stylesElement;
+ stylesElement = KoXml::namedItemNS( contentElement, officeNS, "automatic-styles" );
+ CHECK( stylesElement.isNull(), false );
+ CHECK( stylesElement.isElement(), true );
+ CHECK( stylesElement.parentNode().isNull(), false );
+ CHECK( stylesElement.parentNode()==contentElement, true );
+ CHECK( stylesElement.firstChild().isNull(), true );
+ CHECK( stylesElement.lastChild().isNull(), true );
+ CHECK( stylesElement.previousSibling().isNull(), true );
+ CHECK( stylesElement.nextSibling().isNull(), false );
+ CHECK( stylesElement.localName(), QString("automatic-styles") );
+
+ // also same <office:automatic-styles>, but without namedItemNS
+ KoXmlNode styles2Element;
+ styles2Element = contentElement.firstChild().toElement();
+ CHECK( styles2Element.isNull(), false );
+ CHECK( styles2Element.isElement(), true );
+ CHECK( styles2Element.parentNode().isNull(), false );
+ CHECK( styles2Element.parentNode()==contentElement, true );
+ CHECK( styles2Element.firstChild().isNull(), true );
+ CHECK( styles2Element.lastChild().isNull(), true );
+ CHECK( styles2Element.previousSibling().isNull(), true );
+ CHECK( styles2Element.nextSibling().isNull(), false );
+ CHECK( styles2Element.localName(), QString("automatic-styles") );
+
+ // <office:body>
+ KoXmlElement bodyElement;
+ bodyElement = KoXml::namedItemNS( contentElement, officeNS, "body" );
+ CHECK( bodyElement.isNull(), false );
+ CHECK( bodyElement.isElement(), true );
+ CHECK( bodyElement.parentNode().isNull(), false );
+ CHECK( bodyElement.parentNode()==contentElement, true );
+ CHECK( bodyElement.firstChild().isNull(), false );
+ CHECK( bodyElement.lastChild().isNull(), false );
+ CHECK( bodyElement.previousSibling().isNull(), false );
+ CHECK( bodyElement.nextSibling().isNull(), true );
+ CHECK( bodyElement.localName(), QString("body") );
+
+ // also same <office:body>, but without namedItemNS
+ KoXmlElement body2Element;
+ body2Element = stylesElement.nextSibling().toElement();
+ CHECK( body2Element.isNull(), false );
+ CHECK( body2Element.isElement(), true );
+ CHECK( body2Element.parentNode().isNull(), false );
+ CHECK( body2Element.parentNode()==contentElement, true );
+ CHECK( body2Element.firstChild().isNull(), false );
+ CHECK( body2Element.lastChild().isNull(), false );
+ CHECK( body2Element.previousSibling().isNull(), false );
+ CHECK( body2Element.nextSibling().isNull(), true );
+ CHECK( body2Element.localName(), QString("body") );
+
+ // <office:text>
+ KoXmlElement textElement;
+ textElement = KoXml::namedItemNS( bodyElement, officeNS, "text" );
+ CHECK( textElement.isNull(), false );
+ CHECK( textElement.isElement(), true );
+ CHECK( textElement.parentNode().isNull(), false );
+ CHECK( textElement.parentNode()==bodyElement, true );
+ CHECK( textElement.firstChild().isNull(), false );
+ CHECK( textElement.lastChild().isNull(), false );
+ CHECK( textElement.previousSibling().isNull(), true );
+ CHECK( textElement.nextSibling().isNull(), true );
+ CHECK( textElement.localName(), QString("text") );
+
+ // the same <office:text>, but without namedItemNS
+ KoXmlElement text2Element;
+ text2Element = bodyElement.firstChild().toElement();
+ CHECK( text2Element.isNull(), false );
+ CHECK( text2Element.isElement(), true );
+ CHECK( text2Element.parentNode().isNull(), false );
+ CHECK( text2Element.parentNode()==bodyElement, true );
+ CHECK( text2Element.firstChild().isNull(), false );
+ CHECK( text2Element.lastChild().isNull(), false );
+ CHECK( text2Element.previousSibling().isNull(), true );
+ CHECK( text2Element.nextSibling().isNull(), true );
+ CHECK( text2Element.localName(), QString("text") );
+
+ // <text:p>
+ KoXmlElement parElement;
+ parElement = textElement.firstChild().toElement();
+ CHECK( parElement.isNull(), false );
+ CHECK( parElement.isElement(), true );
+ CHECK( parElement.parentNode().isNull(), false );
+ CHECK( parElement.parentNode()==textElement, true );
+ CHECK( parElement.firstChild().isNull(), false );
+ CHECK( parElement.lastChild().isNull(), false );
+ CHECK( parElement.previousSibling().isNull(), true );
+ CHECK( parElement.nextSibling().isNull(), true );
+ CHECK( parElement.tagName(), QString("p") );
+ CHECK( parElement.text(), QString("Hello, world!") );
+ CHECK( parElement.attributeNS( QString(textNS),"style-name",""), QString("Standard") );
+}
+
+void testSimpleOpenDocumentSpreadsheet()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // content.xml from a simple OpenDocument spreadsheet
+ // the document has three worksheets, the last two are empty.
+ // on the first sheet, cell A1 contains the text "Hello, world".
+ // automatic styles, font declarations and unnecessary namespaces are omitted.
+
+ xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ xmlstream << "<office:document-content ";
+ xmlstream << "xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"";
+ xmlstream << "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
+ xmlstream << "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\">";
+ xmlstream << "<office:body>";
+ xmlstream << "<office:spreadsheet>";
+ xmlstream << "<table:table table:name=\"Sheet1\" table:style-name=\"ta1\" table:print=\"false\">";
+ xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
+ xmlstream << "<table:table-row table:style-name=\"ro1\">";
+ xmlstream << "<table:table-cell office:value-type=\"string\">";
+ xmlstream << "<text:p>Hello, world</text:p>";
+ xmlstream << "</table:table-cell>";
+ xmlstream << "</table:table-row>";
+ xmlstream << "</table:table>";
+ xmlstream << "<table:table table:name=\"Sheet2\" table:style-name=\"ta1\" table:print=\"false\">";
+ xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
+ xmlstream << "<table:table-row table:style-name=\"ro1\">";
+ xmlstream << "<table:table-cell/>";
+ xmlstream << "</table:table-row>";
+ xmlstream << "</table:table>";
+ xmlstream << "<table:table table:name=\"Sheet3\" table:style-name=\"ta1\" table:print=\"false\">";
+ xmlstream << "<table:table-column table:style-name=\"co1\" table:default-cell-style-name=\"Default\"/>";
+ xmlstream << "<table:table-row table:style-name=\"ro1\">";
+ xmlstream << "<table:table-cell/>";
+ xmlstream << "</table:table-row>";
+ xmlstream << "</table:table>";
+ xmlstream << "</office:spreadsheet>";
+ xmlstream << "</office:body>";
+ xmlstream << "</office:document-content>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ QString officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+ QString tableNS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
+ QString textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+
+ // <office:document-content>
+ KoXmlElement contentElement;
+ contentElement = doc.documentElement();
+ CHECK( contentElement.isNull(), false );
+ CHECK( contentElement.isElement(), true );
+ CHECK( contentElement.parentNode().isNull(), false );
+ CHECK( contentElement.parentNode().toDocument()==doc, true );
+ CHECK( contentElement.firstChild().isNull(), false );
+ CHECK( contentElement.lastChild().isNull(), false );
+ CHECK( contentElement.previousSibling().isNull(), false );
+ CHECK( contentElement.nextSibling().isNull(), true );
+ CHECK( contentElement.localName(), QString("document-content") );
+
+ // <office:body>
+ KoXmlElement bodyElement;
+ bodyElement = contentElement.firstChild().toElement();
+ CHECK( bodyElement.isNull(), false );
+ CHECK( bodyElement.isElement(), true );
+ CHECK( bodyElement.parentNode().isNull(), false );
+ CHECK( bodyElement.parentNode()==contentElement, true );
+ CHECK( bodyElement.firstChild().isNull(), false );
+ CHECK( bodyElement.lastChild().isNull(), false );
+ CHECK( bodyElement.previousSibling().isNull(), true );
+ CHECK( bodyElement.nextSibling().isNull(), true );
+ CHECK( bodyElement.localName(), QString("body") );
+
+ // <office:spreadsheet>
+ KoXmlElement spreadsheetElement;
+ spreadsheetElement = bodyElement.firstChild().toElement();
+ CHECK( spreadsheetElement.isNull(), false );
+ CHECK( spreadsheetElement.isElement(), true );
+ CHECK( spreadsheetElement.parentNode().isNull(), false );
+ CHECK( spreadsheetElement.parentNode()==bodyElement, true );
+ CHECK( spreadsheetElement.firstChild().isNull(), false );
+ CHECK( spreadsheetElement.lastChild().isNull(), false );
+ CHECK( spreadsheetElement.previousSibling().isNull(), true );
+ CHECK( spreadsheetElement.nextSibling().isNull(), true );
+ CHECK( spreadsheetElement.localName(), QString("spreadsheet") );
+
+ // <table:table> for Sheet1
+ KoXmlElement sheet1Element;
+ sheet1Element = spreadsheetElement.firstChild().toElement();
+ CHECK( sheet1Element.isNull(), false );
+ CHECK( sheet1Element.isElement(), true );
+ CHECK( sheet1Element.parentNode().isNull(), false );
+ CHECK( sheet1Element.parentNode()==spreadsheetElement, true );
+ CHECK( sheet1Element.firstChild().isNull(), false );
+ CHECK( sheet1Element.lastChild().isNull(), false );
+ CHECK( sheet1Element.previousSibling().isNull(), true );
+ CHECK( sheet1Element.nextSibling().isNull(), false );
+ CHECK( sheet1Element.tagName(), QString("table") );
+ CHECK( sheet1Element.hasAttributeNS(tableNS,"name"), true );
+ CHECK( sheet1Element.attributeNS(tableNS,"name",""), QString("Sheet1") );
+ CHECK( sheet1Element.attributeNS(tableNS,"style-name",""), QString("ta1") );
+ CHECK( sheet1Element.attributeNS(tableNS,"print",""), QString("false") );
+
+ KoXml::load( sheet1Element, 100 );
+
+ // <table:table-column>
+ KoXmlElement columnElement;
+ columnElement = sheet1Element.firstChild().toElement();
+ CHECK( columnElement.isNull(), false );
+ CHECK( columnElement.isElement(), true );
+ CHECK( columnElement.parentNode().isNull(), false );
+ CHECK( columnElement.parentNode()==sheet1Element, true );
+ CHECK( columnElement.firstChild().isNull(), true );
+ CHECK( columnElement.lastChild().isNull(), true );
+ CHECK( columnElement.previousSibling().isNull(), true );
+ CHECK( columnElement.nextSibling().isNull(), false );
+ CHECK( columnElement.tagName(), QString("table-column") );
+ CHECK( columnElement.attributeNS(tableNS,"style-name",""), QString("co1") );
+ CHECK( columnElement.attributeNS(tableNS,"default-cell-style-name",""), QString("Default") );
+
+ // <table:table-row>
+ KoXmlElement rowElement;
+ rowElement = columnElement.nextSibling().toElement();
+ CHECK( rowElement.isNull(), false );
+ CHECK( rowElement.isElement(), true );
+ CHECK( rowElement.parentNode().isNull(), false );
+ CHECK( rowElement.parentNode()==sheet1Element, true );
+ CHECK( rowElement.firstChild().isNull(), false );
+ CHECK( rowElement.lastChild().isNull(), false );
+ CHECK( rowElement.previousSibling().isNull(), false );
+ CHECK( rowElement.nextSibling().isNull(), true );
+ CHECK( rowElement.tagName(), QString("table-row") );
+ CHECK( rowElement.attributeNS(tableNS,"style-name",""), QString("ro1") );
+
+ // <table:table-cell>
+ KoXmlElement cellElement;
+ cellElement = rowElement.firstChild().toElement();
+ CHECK( cellElement.isNull(), false );
+ CHECK( cellElement.isElement(), true );
+ CHECK( cellElement.parentNode().isNull(), false );
+ CHECK( cellElement.parentNode()==rowElement, true );
+ CHECK( cellElement.firstChild().isNull(), false );
+ CHECK( cellElement.lastChild().isNull(), false );
+ CHECK( cellElement.previousSibling().isNull(), true );
+ CHECK( cellElement.nextSibling().isNull(), true );
+ CHECK( cellElement.tagName(), QString("table-cell") );
+ CHECK( cellElement.attributeNS(officeNS,"value-type",""), QString("string") );
+
+ // <text:p>
+ KoXmlElement parElement;
+ parElement = cellElement.firstChild().toElement();
+ CHECK( parElement.isNull(), false );
+ CHECK( parElement.isElement(), true );
+ CHECK( parElement.parentNode().isNull(), false );
+ CHECK( parElement.parentNode()==cellElement, true );
+ CHECK( parElement.firstChild().isNull(), false );
+ CHECK( parElement.lastChild().isNull(), false );
+ CHECK( parElement.previousSibling().isNull(), true );
+ CHECK( parElement.nextSibling().isNull(), true );
+ CHECK( parElement.tagName(), QString("p") );
+ CHECK( parElement.text(), QString("Hello, world") );
+
+ // <table:table> for Sheet2
+ KoXmlElement sheet2Element;
+ sheet2Element = sheet1Element.nextSibling().toElement();
+ CHECK( sheet2Element.isNull(), false );
+ CHECK( sheet2Element.isElement(), true );
+ CHECK( sheet2Element.parentNode().isNull(), false );
+ CHECK( sheet2Element.parentNode()==spreadsheetElement, true );
+ CHECK( sheet2Element.firstChild().isNull(), false );
+ CHECK( sheet2Element.lastChild().isNull(), false );
+ CHECK( sheet2Element.previousSibling().isNull(), false );
+ CHECK( sheet2Element.nextSibling().isNull(), false );
+ CHECK( sheet2Element.tagName(), QString("table") );
+
+ // </table:table> for Sheet3
+ KoXmlElement sheet3Element;
+ sheet3Element = sheet2Element.nextSibling().toElement();
+ CHECK( sheet3Element.isNull(), false );
+ CHECK( sheet3Element.isElement(), true );
+ CHECK( sheet3Element.parentNode().isNull(), false );
+ CHECK( sheet3Element.parentNode()==spreadsheetElement, true );
+ CHECK( sheet3Element.firstChild().isNull(), false );
+ CHECK( sheet3Element.lastChild().isNull(), false );
+ CHECK( sheet3Element.previousSibling().isNull(), false );
+ CHECK( sheet3Element.nextSibling().isNull(), true );
+ CHECK( sheet3Element.tagName(), QString("table") );
+}
+
+void testSimpleOpenDocumentPresentation()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // content.xml from a simple OpenDocument presentation
+ // styles, declarations and unnecessary namespaces are omitted
+ // the first page is "Title" and has two text boxes
+ // the second page is
+
+ xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ xmlstream << "<office:document-content ";
+ xmlstream << " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" ";
+ xmlstream << " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
+ xmlstream << " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\" ";
+ xmlstream << " xmlns:presentation=\"urn:oasis:names:tc:opendocument:xmlns:presentation:1.0\" ";
+ xmlstream << " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\" ";
+ xmlstream << " office:version=\"1.0\">";
+ xmlstream << " <office:scripts/>";
+ xmlstream << " <office:automatic-styles/>";
+ xmlstream << " <office:body>";
+ xmlstream << " <office:presentation>";
+ xmlstream << " <draw:page draw:name=\"Title\" draw:style-name=\"dp1\" ";
+ xmlstream << " draw:master-page-name=\"lyt-cool\" ";
+ xmlstream << " presentation:presentation-page-layout-name=\"AL1T0\">";
+ xmlstream << " <draw:frame presentation:style-name=\"pr1\" ";
+ xmlstream << " draw:text-style-name=\"P2\" draw:layer=\"layout\" ";
+ xmlstream << " svg:width=\"23.912cm\" svg:height=\"3.508cm\" ";
+ xmlstream << " svg:x=\"2.058cm\" svg:y=\"1.543cm\" ";
+ xmlstream << " presentation:class=\"title\" ";
+ xmlstream << " presentation:user-transformed=\"true\">";
+ xmlstream << " <draw:text-box>";
+ xmlstream << " <text:p text:style-name=\"P1\">Foobar</text:p>";
+ xmlstream << " </draw:text-box>";
+ xmlstream << " </draw:frame>";
+ xmlstream << " <draw:frame presentation:style-name=\"pr2\" ";
+ xmlstream << " draw:text-style-name=\"P3\" draw:layer=\"layout\"";
+ xmlstream << " svg:width=\"23.912cm\" svg:height=\"13.231cm\"";
+ xmlstream << " svg:x=\"2.058cm\" svg:y=\"5.838cm\" ";
+ xmlstream << " presentation:class=\"subtitle\">";
+ xmlstream << " <draw:text-box>";
+ xmlstream << " <text:p text:style-name=\"P3\">Foo</text:p>";
+ xmlstream << " </draw:text-box>";
+ xmlstream << " </draw:frame>";
+ xmlstream << " <presentation:notes draw:style-name=\"dp2\">";
+ xmlstream << " <draw:page-thumbnail draw:style-name=\"gr1\" draw:layer=\"layout\" svg:width=\"13.706cm\" svg:height=\"10.28cm\" svg:x=\"3.647cm\" svg:y=\"2.853cm\" draw:page-number=\"1\" presentation:class=\"page\"/>";
+ xmlstream << " <draw:frame presentation:style-name=\"pr3\" draw:text-style-name=\"P1\" draw:layer=\"layout\" svg:width=\"14.518cm\" svg:height=\"11.411cm\" svg:x=\"3.249cm\" svg:y=\"14.13cm\" presentation:class=\"notes\" presentation:placeholder=\"true\">";
+ xmlstream << " <draw:text-box/>";
+ xmlstream << " </draw:frame>";
+ xmlstream << " </presentation:notes>";
+ xmlstream << " </draw:page>";
+ xmlstream << " <presentation:settings presentation:stay-on-top=\"true\"/>";
+ xmlstream << " </office:presentation>";
+ xmlstream << " </office:body>";
+ xmlstream << "</office:document-content>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ char* officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+ char* drawNS = "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0";
+ char* textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+ char* presentationNS = "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0";
+ char* svgNS = "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0";
+
+ // <office:document-content>
+ KoXmlElement contentElement;
+ contentElement = doc.documentElement();
+ CHECK( contentElement.isNull(), false );
+
+ CHECK( contentElement.isElement(), true );
+ CHECK( contentElement.parentNode().isNull(), false );
+ CHECK( contentElement.parentNode().toDocument()==doc, true );
+ CHECK( contentElement.firstChild().isNull(), false );
+ CHECK( contentElement.lastChild().isNull(), false );
+ CHECK( contentElement.previousSibling().isNull(), false );
+
+ CHECK( contentElement.nextSibling().isNull(), true );
+ CHECK( contentElement.localName(), QString("document-content") );
+ CHECK( contentElement.hasAttributeNS(officeNS,"version"), true );
+ CHECK( contentElement.attributeNS(officeNS,"version",""), QString("1.0") );
+
+ // <office:scripts>
+ KoXmlElement scriptsElement;
+ scriptsElement = KoXml::namedItemNS( contentElement, officeNS, "scripts" );
+ CHECK( scriptsElement.isNull(), false );
+ CHECK( scriptsElement.isElement(), true );
+ CHECK( scriptsElement.parentNode().isNull(), false );
+ CHECK( scriptsElement.parentNode()==contentElement, true );
+ CHECK( scriptsElement.firstChild().isNull(), true );
+ CHECK( scriptsElement.lastChild().isNull(), true );
+ CHECK( scriptsElement.previousSibling().isNull(), true );
+ CHECK( scriptsElement.nextSibling().isNull(), false );
+ CHECK( scriptsElement.localName(), QString("scripts") );
+
+ // <office:automatic-styles>
+ KoXmlElement stylesElement;
+ stylesElement = KoXml::namedItemNS( contentElement, officeNS, "automatic-styles" );
+ CHECK( stylesElement.isNull(), false );
+ CHECK( stylesElement.isElement(), true );
+ CHECK( stylesElement.parentNode().isNull(), false );
+ CHECK( stylesElement.parentNode()==contentElement, true );
+ CHECK( stylesElement.firstChild().isNull(), true );
+ CHECK( stylesElement.lastChild().isNull(), true );
+ CHECK( stylesElement.previousSibling().isNull(), false );
+ CHECK( stylesElement.nextSibling().isNull(), false );
+ CHECK( stylesElement.localName(), QString("automatic-styles") );
+
+ // also same <office:automatic-styles>, but without namedItemNS
+ KoXmlNode styles2Element;
+ styles2Element = scriptsElement.nextSibling().toElement();
+ CHECK( styles2Element.isNull(), false );
+ CHECK( styles2Element.isElement(), true );
+ CHECK( styles2Element.parentNode().isNull(), false );
+ CHECK( styles2Element.parentNode()==contentElement, true );
+ CHECK( styles2Element.firstChild().isNull(), true );
+ CHECK( styles2Element.lastChild().isNull(), true );
+ CHECK( styles2Element.previousSibling().isNull(), false );
+ CHECK( styles2Element.nextSibling().isNull(), false );
+ CHECK( styles2Element.localName(), QString("automatic-styles") );
+
+ // <office:body>
+ KoXmlElement bodyElement;
+ bodyElement = KoXml::namedItemNS( contentElement, officeNS, "body" );
+ CHECK( bodyElement.isNull(), false );
+ CHECK( bodyElement.isElement(), true );
+ CHECK( bodyElement.parentNode().isNull(), false );
+ CHECK( bodyElement.parentNode()==contentElement, true );
+ CHECK( bodyElement.firstChild().isNull(), false );
+ CHECK( bodyElement.lastChild().isNull(), false );
+ CHECK( bodyElement.previousSibling().isNull(), false );
+ CHECK( bodyElement.nextSibling().isNull(), true );
+ CHECK( bodyElement.localName(), QString("body") );
+
+ // also same <office:body>, but without namedItemNS
+ KoXmlElement body2Element;
+ body2Element = stylesElement.nextSibling().toElement();
+ CHECK( body2Element.isNull(), false );
+ CHECK( body2Element.isElement(), true );
+ CHECK( body2Element.parentNode().isNull(), false );
+ CHECK( body2Element.parentNode()==contentElement, true );
+ CHECK( body2Element.firstChild().isNull(), false );
+ CHECK( body2Element.lastChild().isNull(), false );
+ CHECK( body2Element.previousSibling().isNull(), false );
+ CHECK( body2Element.nextSibling().isNull(), true );
+ CHECK( body2Element.localName(), QString("body") );
+
+ // <office:presentation>
+ KoXmlElement presentationElement;
+ presentationElement = KoXml::namedItemNS( bodyElement, officeNS, "presentation" );
+ CHECK( presentationElement.isNull(), false );
+ CHECK( presentationElement.isElement(), true );
+ CHECK( presentationElement.parentNode().isNull(), false );
+ CHECK( presentationElement.parentNode()==bodyElement, true );
+ CHECK( presentationElement.firstChild().isNull(), false );
+ CHECK( presentationElement.lastChild().isNull(), false );
+ CHECK( presentationElement.previousSibling().isNull(), true );
+ CHECK( presentationElement.nextSibling().isNull(), true );
+ CHECK( presentationElement.localName(), QString("presentation") );
+
+ // the same <office:presentation>, but without namedItemNS
+ KoXmlElement presentation2Element;
+ presentation2Element = bodyElement.firstChild().toElement();
+ CHECK( presentation2Element.isNull(), false );
+ CHECK( presentation2Element.isElement(), true );
+ CHECK( presentation2Element.parentNode().isNull(), false );
+ CHECK( presentation2Element.parentNode()==bodyElement, true );
+ CHECK( presentation2Element.firstChild().isNull(), false );
+ CHECK( presentation2Element.lastChild().isNull(), false );
+ CHECK( presentation2Element.previousSibling().isNull(), true );
+ CHECK( presentation2Element.nextSibling().isNull(), true );
+ CHECK( presentation2Element.localName(), QString("presentation") );
+
+ // <draw:page> for "Title"
+ KoXmlElement titlePageElement;
+ titlePageElement = presentationElement.firstChild().toElement();
+ CHECK( titlePageElement.isNull(), false );
+ CHECK( titlePageElement.isElement(), true );
+ CHECK( titlePageElement.parentNode().isNull(), false );
+ CHECK( titlePageElement.parentNode()==presentationElement, true );
+ CHECK( titlePageElement.firstChild().isNull(), false );
+ CHECK( titlePageElement.lastChild().isNull(), false );
+ CHECK( titlePageElement.previousSibling().isNull(), true );
+ CHECK( titlePageElement.nextSibling().isNull(), false );
+ CHECK( titlePageElement.localName(), QString("page") );
+ CHECK( titlePageElement.attributeNS(drawNS,"name",""), QString("Title") );
+ CHECK( titlePageElement.attributeNS(drawNS,"style-name",""), QString("dp1") );
+ CHECK( titlePageElement.attributeNS(drawNS,"master-page-name",""), QString("lyt-cool") );
+ CHECK( titlePageElement.attributeNS(presentationNS,
+ "presentation-page-layout-name",""), QString("AL1T0") );
+
+ // <draw:frame> for the title frame
+ KoXmlElement titleFrameElement;
+ titleFrameElement = titlePageElement.firstChild().toElement();
+ CHECK( titleFrameElement.isNull(), false );
+ CHECK( titleFrameElement.isElement(), true );
+ CHECK( titleFrameElement.parentNode().isNull(), false );
+ CHECK( titleFrameElement.parentNode()==titlePageElement, true );
+ CHECK( titleFrameElement.firstChild().isNull(), false );
+ CHECK( titleFrameElement.lastChild().isNull(), false );
+ CHECK( titleFrameElement.previousSibling().isNull(), true );
+ CHECK( titleFrameElement.nextSibling().isNull(), false );
+ CHECK( titleFrameElement.localName(), QString("frame") );
+ CHECK( titleFrameElement.attributeNS(presentationNS,"style-name",""), QString("pr1") );
+ CHECK( titleFrameElement.attributeNS(presentationNS,"class",""), QString("title") );
+ CHECK( titleFrameElement.attributeNS(presentationNS,"user-transformed",""), QString("true") );
+ CHECK( titleFrameElement.attributeNS(drawNS,"text-style-name",""), QString("P2") );
+ CHECK( titleFrameElement.attributeNS(drawNS,"layer",""), QString("layout") );
+ CHECK( titleFrameElement.attributeNS(svgNS,"width",""), QString("23.912cm") );
+ CHECK( titleFrameElement.attributeNS(svgNS,"height",""), QString("3.508cm") );
+ CHECK( titleFrameElement.attributeNS(svgNS,"x",""), QString("2.058cm") );
+ CHECK( titleFrameElement.attributeNS(svgNS,"y",""), QString("1.543cm") );
+
+ // <draw:text-box> of the title frame
+ KoXmlElement titleBoxElement;
+ titleBoxElement = titleFrameElement.firstChild().toElement();
+ CHECK( titleBoxElement.isNull(), false );
+ CHECK( titleBoxElement.isElement(), true );
+ CHECK( titleBoxElement.parentNode().isNull(), false );
+ CHECK( titleBoxElement.parentNode()==titleFrameElement, true );
+ CHECK( titleBoxElement.firstChild().isNull(), false );
+ CHECK( titleBoxElement.lastChild().isNull(), false );
+ CHECK( titleBoxElement.previousSibling().isNull(), true );
+ CHECK( titleBoxElement.nextSibling().isNull(), true );
+ CHECK( titleBoxElement.localName(), QString("text-box") );
+
+ // <text:p> for the title text-box
+ KoXmlElement titleParElement;
+ titleParElement = titleBoxElement.firstChild().toElement();
+ CHECK( titleParElement.isNull(), false );
+ CHECK( titleParElement.isElement(), true );
+ CHECK( titleParElement.parentNode().isNull(), false );
+ CHECK( titleParElement.parentNode()==titleBoxElement, true );
+ CHECK( titleParElement.firstChild().isNull(), false );
+ CHECK( titleParElement.lastChild().isNull(), false );
+ CHECK( titleParElement.previousSibling().isNull(), true );
+ CHECK( titleParElement.nextSibling().isNull(), true );
+ CHECK( titleParElement.localName(), QString("p") );
+ CHECK( titleParElement.attributeNS(textNS,"style-name",""), QString("P1") );
+ CHECK( titleParElement.text(), QString("Foobar") );
+
+ // <draw:frame> for the subtitle frame
+ KoXmlElement subtitleFrameElement;
+ subtitleFrameElement = titleFrameElement.nextSibling().toElement();
+ CHECK( subtitleFrameElement.isNull(), false );
+ CHECK( subtitleFrameElement.isElement(), true );
+ CHECK( subtitleFrameElement.parentNode().isNull(), false );
+ CHECK( subtitleFrameElement.parentNode()==titlePageElement, true );
+ CHECK( subtitleFrameElement.firstChild().isNull(), false );
+ CHECK( subtitleFrameElement.lastChild().isNull(), false );
+ CHECK( subtitleFrameElement.previousSibling().isNull(), false );
+ CHECK( subtitleFrameElement.nextSibling().isNull(), false );
+ CHECK( subtitleFrameElement.localName(), QString("frame") );
+ CHECK( subtitleFrameElement.attributeNS(presentationNS,"style-name",""), QString("pr2") );
+ CHECK( subtitleFrameElement.attributeNS(presentationNS,"class",""), QString("subtitle") );
+ CHECK( subtitleFrameElement.hasAttributeNS(presentationNS,"user-transformed"), false );
+ CHECK( subtitleFrameElement.attributeNS(drawNS,"text-style-name",""), QString("P3") );
+ CHECK( subtitleFrameElement.attributeNS(drawNS,"layer",""), QString("layout") );
+ CHECK( subtitleFrameElement.attributeNS(svgNS,"width",""), QString("23.912cm") );
+ CHECK( subtitleFrameElement.attributeNS(svgNS,"height",""), QString("13.231cm") );
+ CHECK( subtitleFrameElement.attributeNS(svgNS,"x",""), QString("2.058cm") );
+ CHECK( subtitleFrameElement.attributeNS(svgNS,"y",""), QString("5.838cm") );
+
+ // <draw:text-box> of the subtitle frame
+ KoXmlElement subtitleBoxElement;
+ subtitleBoxElement = subtitleFrameElement.firstChild().toElement();
+ CHECK( subtitleBoxElement.isNull(), false );
+ CHECK( subtitleBoxElement.isElement(), true );
+ CHECK( subtitleBoxElement.parentNode().isNull(), false );
+ CHECK( subtitleBoxElement.parentNode()==subtitleFrameElement, true );
+ CHECK( subtitleBoxElement.firstChild().isNull(), false );
+ CHECK( subtitleBoxElement.lastChild().isNull(), false );
+ CHECK( subtitleBoxElement.previousSibling().isNull(), true );
+ CHECK( subtitleBoxElement.nextSibling().isNull(), true );
+ CHECK( subtitleBoxElement.localName(), QString("text-box") );
+
+ // <text:p> for the subtitle text-box
+ KoXmlElement subtitleParElement;
+ subtitleParElement = subtitleBoxElement.firstChild().toElement();
+ CHECK( subtitleParElement.isNull(), false );
+ CHECK( subtitleParElement.isElement(), true );
+ CHECK( subtitleParElement.parentNode().isNull(), false );
+ CHECK( subtitleParElement.parentNode()==subtitleBoxElement, true );
+ CHECK( subtitleParElement.firstChild().isNull(), false );
+ CHECK( subtitleParElement.lastChild().isNull(), false );
+ CHECK( subtitleParElement.previousSibling().isNull(), true );
+ CHECK( subtitleParElement.nextSibling().isNull(), true );
+ CHECK( subtitleParElement.localName(), QString("p") );
+ CHECK( subtitleParElement.attributeNS(textNS,"style-name",""), QString("P3") );
+ CHECK( subtitleParElement.text(), QString("Foo") );
+}
+
+void testSimpleOpenDocumentFormula()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // content.xml from a simple OpenDocument formula
+ // this is essentially MathML
+ xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ xmlstream << "<!DOCTYPE math:math PUBLIC \"-//OpenOffice.org//DTD Modified W3C MathML 1.01//EN\" \"math.dtd\">";
+ xmlstream << "<math:math xmlns:math=\"http://www.w3.org/1998/Math/MathML\">";
+ xmlstream << " <math:semantics>";
+ xmlstream << " <math:mrow>";
+ xmlstream << " <math:mi>E</math:mi>";
+ xmlstream << " <math:mo math:stretchy=\"false\">=</math:mo>";
+ xmlstream << " <math:msup>";
+ xmlstream << " <math:mi math:fontstyle=\"italic\">mc</math:mi>";
+ xmlstream << " <math:mn>2</math:mn>";
+ xmlstream << " </math:msup>";
+ xmlstream << " </math:mrow>";
+ xmlstream << " <math:annotation math:encoding=\"StarMath 5.0\">E = mc^2 </math:annotation>";
+ xmlstream << " </math:semantics>";
+ xmlstream << "</math:math>";
+
+ KoXmlDocument doc;
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ char* mathNS = "http://www.w3.org/1998/Math/MathML";
+
+ // <math:math>
+ KoXmlElement mathElement;
+ mathElement = doc.documentElement();
+ CHECK( mathElement.isNull(), false );
+ CHECK( mathElement.isElement(), true );
+ CHECK( mathElement.parentNode().isNull(), false );
+ CHECK( mathElement.parentNode().toDocument()==doc, true );
+ CHECK( mathElement.firstChild().isNull(), false );
+ CHECK( mathElement.lastChild().isNull(), false );
+ CHECK( mathElement.previousSibling().isNull(), false );
+ CHECK( mathElement.nextSibling().isNull(), true );
+ CHECK( mathElement.localName(), QString("math") );
+
+ // <math:semantics>
+ KoXmlElement semanticsElement;
+ semanticsElement = KoXml::namedItemNS( mathElement, mathNS, "semantics" );
+ CHECK( semanticsElement.isNull(), false );
+ CHECK( semanticsElement.isElement(), true );
+ CHECK( semanticsElement.parentNode().isNull(), false );
+ CHECK( semanticsElement.parentNode().toElement()==mathElement, true );
+ CHECK( semanticsElement.firstChild().isNull(), false );
+ CHECK( semanticsElement.lastChild().isNull(), false );
+ CHECK( semanticsElement.previousSibling().isNull(), true );
+ CHECK( semanticsElement.nextSibling().isNull(), true );
+ CHECK( semanticsElement.localName(), QString("semantics") );
+
+ // the same <math:semantics> but without namedItemNS
+ KoXmlElement semantics2Element;
+ semantics2Element = mathElement.firstChild().toElement();
+ CHECK( semantics2Element.isNull(), false );
+ CHECK( semantics2Element.isElement(), true );
+ CHECK( semantics2Element.parentNode().isNull(), false );
+ CHECK( semantics2Element.parentNode().toElement()==mathElement, true );
+ CHECK( semantics2Element.firstChild().isNull(), false );
+ CHECK( semantics2Element.lastChild().isNull(), false );
+ CHECK( semantics2Element.previousSibling().isNull(), true );
+ CHECK( semantics2Element.nextSibling().isNull(), true );
+ CHECK( semantics2Element.localName(), QString("semantics") );
+
+ // <math:mrow>
+ KoXmlElement mrowElement;
+ mrowElement = semanticsElement.firstChild().toElement();
+ CHECK( mrowElement.isNull(), false );
+ CHECK( mrowElement.isElement(), true );
+ CHECK( mrowElement.parentNode().isNull(), false );
+ CHECK( mrowElement.parentNode().toElement()==semanticsElement, true );
+ CHECK( mrowElement.firstChild().isNull(), false );
+ CHECK( mrowElement.lastChild().isNull(), false );
+ CHECK( mrowElement.previousSibling().isNull(), true );
+ CHECK( mrowElement.nextSibling().isNull(), false );
+ CHECK( mrowElement.localName(), QString("mrow") );
+
+ // <math:mi> for "E"
+ KoXmlElement miElement;
+ miElement = mrowElement.firstChild().toElement();
+ CHECK( miElement.isNull(), false );
+ CHECK( miElement.isElement(), true );
+ CHECK( miElement.parentNode().isNull(), false );
+ CHECK( miElement.parentNode().toElement()==mrowElement, true );
+ CHECK( miElement.firstChild().isNull(), false );
+ CHECK( miElement.lastChild().isNull(), false );
+ CHECK( miElement.previousSibling().isNull(), true );
+ CHECK( miElement.nextSibling().isNull(), false );
+ CHECK( miElement.localName(), QString("mi") );
+
+ // <math:mo> for "="
+ KoXmlElement moElement;
+ moElement = miElement.nextSibling().toElement();
+ CHECK( moElement.isNull(), false );
+ CHECK( moElement.isElement(), true );
+ CHECK( moElement.parentNode().isNull(), false );
+ CHECK( moElement.parentNode().toElement()==mrowElement, true );
+ CHECK( moElement.firstChild().isNull(), false );
+ CHECK( moElement.lastChild().isNull(), false );
+ CHECK( moElement.previousSibling().isNull(), false );
+ CHECK( moElement.nextSibling().isNull(), false );
+ CHECK( moElement.localName(), QString("mo") );
+ CHECK( moElement.attributeNS(mathNS,"stretchy",""), QString("false") );
+
+ // <math:msup> for "mc" and superscripted "2"
+ KoXmlElement msupElement;
+ msupElement = moElement.nextSibling().toElement();
+ CHECK( msupElement.isNull(), false );
+ CHECK( msupElement.isElement(), true );
+ CHECK( msupElement.parentNode().isNull(), false );
+ CHECK( msupElement.parentNode().toElement()==mrowElement, true );
+ CHECK( msupElement.firstChild().isNull(), false );
+ CHECK( msupElement.lastChild().isNull(), false );
+ CHECK( msupElement.previousSibling().isNull(), false );
+ CHECK( msupElement.nextSibling().isNull(), true );
+ CHECK( msupElement.localName(), QString("msup") );
+
+ // <math:mi> inside the <math:msup> for "mc"
+ KoXmlElement mcElement;
+ mcElement = msupElement.firstChild().toElement();
+ CHECK( mcElement.isNull(), false );
+ CHECK( mcElement.isElement(), true );
+ CHECK( mcElement.parentNode().isNull(), false );
+ CHECK( mcElement.parentNode().toElement()==msupElement, true );
+ CHECK( mcElement.firstChild().isNull(), false );
+ CHECK( mcElement.lastChild().isNull(), false );
+ CHECK( mcElement.previousSibling().isNull(), true );
+ CHECK( mcElement.nextSibling().isNull(), false );
+ CHECK( mcElement.localName(), QString("mi") );
+ CHECK( mcElement.text(), QString("mc") );
+ CHECK( mcElement.attributeNS(mathNS,"fontstyle",""), QString("italic") );
+
+ // <math:mn> inside the <math:msup> for "2" (superscript)
+ KoXmlElement mnElement;
+ mnElement = mcElement.nextSibling().toElement();
+ CHECK( mnElement.isNull(), false );
+ CHECK( mnElement.isElement(), true );
+ CHECK( mnElement.parentNode().isNull(), false );
+ CHECK( mnElement.parentNode().toElement()==msupElement, true );
+ CHECK( mnElement.firstChild().isNull(), false );
+ CHECK( mnElement.lastChild().isNull(), false );
+ CHECK( mnElement.previousSibling().isNull(), false );
+ CHECK( mnElement.nextSibling().isNull(), true );
+ CHECK( mnElement.localName(), QString("mn") );
+ CHECK( mnElement.text(), QString("2") );
+
+ // <math:annotation>
+ KoXmlElement annotationElement;
+ annotationElement = semanticsElement.lastChild().toElement();
+ CHECK( annotationElement.isNull(), false );
+ CHECK( annotationElement.isElement(), true );
+ CHECK( annotationElement.parentNode().isNull(), false );
+ CHECK( annotationElement.parentNode().toElement()==semanticsElement, true );
+ CHECK( annotationElement.firstChild().isNull(), false );
+ CHECK( annotationElement.lastChild().isNull(), false );
+ CHECK( annotationElement.previousSibling().isNull(), false );
+ CHECK( annotationElement.nextSibling().isNull(), true );
+ CHECK( annotationElement.localName(), QString("annotation") );
+ CHECK( annotationElement.text(), QString("E = mc^2 ") );
+ CHECK( annotationElement.attributeNS(mathNS,"encoding",""), QString("StarMath 5.0") );
+}
+
+void testLargeOpenDocumentSpreadsheet()
+{
+ QString errorMsg;
+ int errorLine = 0;
+ int errorColumn = 0;
+
+ int sheetCount = 4;
+ int rowCount = 200;
+ int colCount = 200*2;
+
+ QByteArray xmlbuf;
+ QBuffer xmldevice( xmlbuf );
+ QTextStream xmlstream( xmlbuf, IO_WriteOnly );
+
+ // content.xml
+ xmlstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ xmlstream << "<office:document-content ";
+ xmlstream << "xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" ";
+ xmlstream << "xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" ";
+ xmlstream << "xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" >";
+ xmlstream << "<office:body>";
+ xmlstream << "<office:spreadsheet>";
+ for( int i = 0; i < sheetCount; i++ )
+ {
+ QString sheetName = QString("Sheet%1").arg(i+1);
+ xmlstream << "<table:table table:name=\"" << sheetName;
+ xmlstream << "\" table:print=\"false\">";
+ for( int j = 0; j < rowCount; j++ )
+ {
+ xmlstream << "<table:table-row>";
+ for( int k = 0; k < colCount; k++ )
+ {
+ xmlstream << "<table:table-cell office:value-type=\"string\">";
+ xmlstream << "<text:p>Hello, world</text:p>";
+ xmlstream << "</table:table-cell>";
+ }
+ xmlstream << "</table:table-row>";
+ }
+ xmlstream << "</table:table>";
+ }
+ xmlstream << "</office:spreadsheet>";
+ xmlstream << "</office:body>";
+ xmlstream << "</office:document-content>";
+
+ printf("Raw XML size: %d KB\n", xmlbuf.size()/1024 );
+
+ QTime timer;
+ timer.start();
+
+#if 1
+ // just to test parsing speed with plain dumb handler
+ QXmlSimpleReader* reader = new QXmlSimpleReader;
+ reader->setFeature( "http://xml.org/sax/features/namespaces", true );
+ QXmlDefaultHandler handler;
+ reader->setContentHandler( &handler );
+ reader->setErrorHandler( &handler );
+ reader->setLexicalHandler( &handler );
+ reader->setDeclHandler( &handler );
+ reader->setDTDHandler( &handler );
+ QXmlInputSource xmlSource;
+ xmlSource.setData( QString::fromUtf8( xmlbuf.data(), xmlbuf.size() ) );
+ timer.start();
+ reader->parse( &xmlSource );
+ printf("Large spreadsheet: QXmlDefaultHandler parsing time is %d ms\n", timer.elapsed() );
+ delete reader;
+#endif
+
+ timer.start();
+ KoXmlDocument doc;
+
+ // uncomment to see the performance if on-demand/lazy loading is not used
+ // will definitely eat more memory
+#ifndef KOXML_USE_QDOM
+ doc.setFastLoading( true );
+#endif
+
+ CHECK( doc.setContent( &xmldevice, true, &errorMsg, &errorLine, &errorColumn ), true );
+ CHECK( errorMsg.isEmpty(), true );
+ CHECK( errorLine, 0 );
+ CHECK( errorColumn, 0 );
+
+ printf("Large spreadsheet: parsing time is %d ms\n", timer.elapsed() );
+
+ // release memory taken by the XML document content
+ xmlbuf.resize( 0 );
+
+ // namespaces that will be used
+ QString officeNS = "urn:oasis:names:tc:opendocument:xmlns:office:1.0";
+ QString tableNS = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
+ QString textNS = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";
+
+ // <office:document-content>
+ KoXmlElement contentElement;
+ contentElement = doc.documentElement();
+ CHECK( contentElement.isNull(), false );
+ CHECK( contentElement.isElement(), true );
+ CHECK( contentElement.localName(), QString("document-content") );
+
+ // <office:body>
+ KoXmlElement bodyElement;
+ bodyElement = contentElement.firstChild().toElement();
+ CHECK( bodyElement.isNull(), false );
+ CHECK( bodyElement.isElement(), true );
+ CHECK( bodyElement.localName(), QString("body") );
+
+ // <office:spreadsheet>
+ KoXmlElement spreadsheetElement;
+ spreadsheetElement = bodyElement.firstChild().toElement();
+ CHECK( spreadsheetElement.isNull(), false );
+ CHECK( spreadsheetElement.isElement(), true );
+ CHECK( spreadsheetElement.localName(), QString("spreadsheet") );
+
+ // now we visit every sheet, every row, every cell
+ timer.start();
+ KoXmlElement tableElement;
+ tableElement = spreadsheetElement.firstChild().toElement();
+ for( int table=0; table < sheetCount; table++ )
+ {
+ QString tableName = QString("Sheet%1").arg(table+1);
+ CHECK( tableElement.isNull(), false );
+ CHECK( tableElement.isElement(), true );
+ CHECK( tableElement.localName(), QString("table") );
+ CHECK( tableElement.hasAttributeNS(tableNS,"name"), true );
+ CHECK( tableElement.attributeNS(tableNS,"name",""), tableName );
+ CHECK( tableElement.attributeNS(tableNS,"print",""), QString("false") );
+
+ // load everything for this table
+ KoXml::load( tableElement, 99 );
+
+ CHECK( tableElement.parentNode().isNull(), false );
+ CHECK( tableElement.parentNode()==spreadsheetElement, true );
+ CHECK( tableElement.firstChild().isNull(), false );
+ CHECK( tableElement.lastChild().isNull(), false );
+
+ KoXmlElement rowElement;
+ rowElement = tableElement.firstChild().toElement();
+ for( int row=0; row < rowCount; row++ )
+ {
+ CHECK( rowElement.isNull(), false );
+ CHECK( rowElement.isElement(), true );
+ CHECK( rowElement.localName(), QString("table-row") );
+ CHECK( rowElement.parentNode().isNull(), false );
+ CHECK( rowElement.parentNode()==tableElement, true );
+ CHECK( rowElement.firstChild().isNull(), false );
+ CHECK( rowElement.lastChild().isNull(), false );
+
+ KoXmlElement cellElement;
+ cellElement = rowElement.firstChild().toElement();
+ for( int col=0; col < colCount; col++ )
+ {
+ CHECK( cellElement.isNull(), false );
+ CHECK( cellElement.isElement(), true );
+ CHECK( cellElement.localName(), QString("table-cell") );
+ CHECK( cellElement.text(), QString("Hello, world") );
+ CHECK( cellElement.hasAttributeNS(officeNS,"value-type"), true );
+ CHECK( cellElement.attributeNS(officeNS,"value-type",""), QString("string" ) );
+ CHECK( cellElement.parentNode().isNull(), false );
+ CHECK( cellElement.parentNode()==rowElement, true );
+ CHECK( cellElement.firstChild().isNull(), false );
+ CHECK( cellElement.lastChild().isNull(), false );
+ cellElement = cellElement.nextSibling().toElement();
+ }
+
+ //KoXml::unload( rowElement );
+ rowElement = rowElement.nextSibling().toElement();
+ }
+
+ KoXml::unload( tableElement );
+ tableElement = tableElement.nextSibling().toElement();
+ }
+
+ printf("Large spreadsheet: iterating time is %d ms\n", timer.elapsed() );
+}
+
+int main( int argc, char** argv )
+{
+ Q_UNUSED( argc );
+ Q_UNUSED( argv );
+
+ testNode();
+ testElement();
+ testAttributes();
+ testText();
+ testCDATA();
+ testDocument();
+ testNamespace();
+
+ testUnload();
+
+ testSimpleXML();
+ testRootError();
+ testMismatchedTag();
+
+ testSimpleOpenDocumentText();
+ testSimpleOpenDocumentSpreadsheet();
+ testSimpleOpenDocumentPresentation();
+ testSimpleOpenDocumentFormula();
+
+// testLargeOpenDocumentSpreadsheet();
+
+#ifdef KOXML_USE_QDOM
+ printf("Using QDom: ");
+#else
+ printf("Using KoXml: ");
+#endif
+ printf("%d tests, %d failed\n", testCount, testFailed );
+
+ return testFailed;
+}
diff --git a/lib/kofficecore/tests/priorityqueue_test.cpp b/lib/kofficecore/tests/priorityqueue_test.cpp
new file mode 100644
index 00000000..d2c7eafd
--- /dev/null
+++ b/lib/kofficecore/tests/priorityqueue_test.cpp
@@ -0,0 +1,87 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Werner Trobin <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <priorityqueue.h>
+#include <kdebug.h>
+#include <qptrlist.h>
+#include <qasciidict.h>
+#include <stdlib.h>
+#include <time.h>
+
+struct Node {
+ Node( unsigned int key ) : m_key( key ), m_index( 0 ) {}
+
+ unsigned int key() const { return m_key; }
+ void setKey( unsigned int key ) { m_key = key; }
+
+ int index() const { return m_index; }
+ void setIndex( int i ) { m_index = i; }
+private:
+ unsigned int m_key;
+ int m_index;
+};
+
+static const char* const keys[] = { "one", "two", "three", "four", "five",
+ "six", "seven", "eight", "nine", "ten",
+ "eleven", "twelve", 0 };
+
+int main( int /*argc*/, char **/*argv*/ )
+{
+ QPtrList<Node> list;
+ list.setAutoDelete( true );
+ QAsciiDict<Node> dict;
+
+ KOffice::PriorityQueue<Node> queue;
+
+ srand( time( 0 ) );
+ for ( int i = 0; i < 12; ++i ) {
+ Node *n = new Node( rand() % 20 );
+ list.append( n );
+ queue.insert( n );
+ // Check whether the AsciiDict CTOR is okay
+ Node *n2 = new Node( *n );
+ dict.insert( keys[ i ], n2 );
+ }
+
+ kdDebug() << "##### Queue 1: " << endl;
+ queue.dump();
+
+ kdDebug() << "##### Queue 2: " << endl;
+ KOffice::PriorityQueue<Node> queue2( dict );
+ queue2.dump();
+
+ Node *n = list.at( 6 );
+ kdDebug() << "##### Decreasing node: " << n->key() << " at " << n->index() << endl;
+ n->setKey( 2 );
+ queue.keyDecreased( n );
+ queue.dump();
+
+ n = list.at( 2 );
+ kdDebug() << "##### Decreasing node: " << n->key() << " at " << n->index() << endl;
+ n->setKey( 0 );
+ queue.keyDecreased( n );
+ queue.dump();
+
+ n = queue.extractMinimum();
+ while ( n ) {
+ queue.dump();
+ n = queue.extractMinimum();
+ }
+ return 0;
+}