summaryrefslogtreecommitdiffstats
path: root/lib/store/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/store/tests')
-rw-r--r--lib/store/tests/Makefile.am18
-rw-r--r--lib/store/tests/storage_test.cpp220
-rw-r--r--lib/store/tests/storedroptest.cpp138
-rw-r--r--lib/store/tests/xmlwritertest.cpp144
-rw-r--r--lib/store/tests/xmlwritertest.h46
5 files changed, 566 insertions, 0 deletions
diff --git a/lib/store/tests/Makefile.am b/lib/store/tests/Makefile.am
new file mode 100644
index 000000000..caeed44e8
--- /dev/null
+++ b/lib/store/tests/Makefile.am
@@ -0,0 +1,18 @@
+####### General stuff
+
+KDE_CXXFLAGS = $(USE_RTTI)
+INCLUDES= -I$(srcdir)/.. -I$(srcdir)/../../kofficecore $(all_includes)
+
+####### Files
+
+check_PROGRAMS = storage_test xmlwritertest storedroptest
+TESTS = storage_test xmlwritertest
+
+storage_test_SOURCES = storage_test.cpp
+storage_test_LDADD = ../libkstore.la
+
+xmlwritertest_SOURCES = xmlwritertest.cpp
+xmlwritertest_LDADD = ../libkstore.la
+
+storedroptest_SOURCES = storedroptest.cpp
+storedroptest_LDADD = ../libkstore.la
diff --git a/lib/store/tests/storage_test.cpp b/lib/store/tests/storage_test.cpp
new file mode 100644
index 000000000..6fd03bf3e
--- /dev/null
+++ b/lib/store/tests/storage_test.cpp
@@ -0,0 +1,220 @@
+/* This file is part of the KDE project
+ Copyright (C) 2002 Werner Trobin <trobin@kde.org>
+
+ 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 <qdir.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+
+#include <KoStore.h>
+#include <kdebug.h>
+#include <stdlib.h>
+
+#include <string.h>
+
+namespace {
+ const char* const test1 = "This test checks whether we're able to write to some arbitrary directory.\n";
+ const char* const testDir = "0";
+ const char* const testDirResult = "0/";
+ const char* const test2 = "This time we try to append the given relative path to the current dir.\n";
+ const char* const test3 = "<xml>Hello World</xml>";
+ const char* const testDir2 = "test2/with/a";
+ const char* const testDir2Result = "0/test2/with/a/";
+ const char* const test4 = "<xml>Heureka, it works</xml>";
+
+ const char* const badStorage = "Ooops, bad storage???";
+ const char* const unableToOpen = "Couldn't open storage!";
+ const char* const brokenPath = "Path handling broken!";
+ const char* const unableToRead = "Couldn't read stream back!";
+}
+
+int cleanUp( KoStore* store, const QString& testFile, const char* error )
+{
+ QFile::remove( testFile );
+ delete store;
+ kdDebug() << error << endl;
+ return 1;
+}
+
+int test( const char* testName, KoStore::Backend backend, const QString& testFile )
+{
+ if ( QFile::exists( testFile ) )
+ QFile::remove( testFile );
+ QDir dirTest( testFile );
+ if ( dirTest.exists() ) {
+ system( QCString( "rm -rf " ) + QFile::encodeName( testFile ) ); // QDir::rmdir isn't recursive!
+ }
+
+ kdDebug() << "======================="<<testName<<"====================================" << endl;
+ KoStore* store = KoStore::createStore( testFile, KoStore::Write, "", backend );
+ if ( store->bad() )
+ return cleanUp( store, testFile, badStorage );
+
+ if ( store->open( "test1/with/a/relative/dir.txt" ) ) {
+ for ( int i = 0; i < 100; ++i )
+ store->write( test1, strlen( test1 ) );
+ store->close();
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ store->enterDirectory( testDir );
+ if ( store->currentPath() != QString( testDirResult ) )
+ return cleanUp( store, testFile, brokenPath );
+
+ if ( store->open( "test2/with/a/relative/dir.txt" ) ) {
+ for ( int i = 0; i < 100; ++i )
+ store->write( test2, strlen( test2 ) );
+ store->close();
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ if ( store->open( "root" ) ) {
+ store->write( test3, strlen( test3 ) );
+ store->close();
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ store->enterDirectory( testDir2 );
+ if ( store->currentPath() != QString( testDir2Result ) )
+ return cleanUp( store, testFile, brokenPath );
+
+ if ( store->open( "root" ) ) {
+ store->write( test4, strlen( test4 ) );
+ store->close();
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ if ( store->isOpen() )
+ store->close();
+ delete store;
+
+ kdDebug() << "===========================================================" << endl;
+
+ store = KoStore::createStore( testFile, KoStore::Read, "", backend );
+ if ( store->bad() )
+ return cleanUp( store, testFile, badStorage );
+
+ if ( store->open( "test1/with/a/relative/dir.txt" ) ) {
+ QIODevice* dev = store->device();
+ int i = 0, lim = strlen( test1 ), count = 0;
+ while ( static_cast<char>( dev->getch() ) == test1[i++] ) {
+ if ( i == lim ) {
+ i = 0;
+ ++count;
+ }
+ }
+ store->close();
+ if ( count != 100 )
+ return cleanUp( store, testFile, unableToRead );
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ store->enterDirectory( testDir );
+ if ( store->currentPath() != QString( testDirResult ) )
+ return cleanUp( store, testFile, brokenPath );
+
+ if ( store->open( "test2/with/a/relative/dir.txt" ) ) {
+ QIODevice* dev = store->device();
+ int i = 0, lim = strlen( test2 ), count = 0;
+ while ( static_cast<char>( dev->getch() ) == test2[i++] ) {
+ if ( i == lim ) {
+ i = 0;
+ ++count;
+ }
+ }
+ store->close();
+ if ( count != 100 )
+ return cleanUp( store, testFile, unableToRead );
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ store->enterDirectory( testDir2 );
+ store->pushDirectory();
+
+ while ( store->leaveDirectory() );
+ store->enterDirectory( testDir );
+ if ( store->currentPath() != QString( testDirResult ) )
+ return cleanUp( store, testFile, brokenPath );
+
+ if ( store->open( "root" ) ) {
+ if ( store->size() == 22 ) {
+ QIODevice* dev = store->device();
+ unsigned int i = 0;
+ while ( static_cast<char>( dev->getch() ) == test3[i++] );
+ store->close();
+ if ( ( i - 1 ) != strlen( test3 ) )
+ return cleanUp( store, testFile, unableToRead );
+ }
+ else {
+ kdError() << "Wrong size! maindoc.xml is " << store->size() << " should be 22." << endl;
+ delete store;
+ return 1;
+ }
+ }
+ else {
+ kdError() << "Couldn't open storage!" << endl;
+ delete store;
+ return 1;
+ }
+
+ store->popDirectory();
+ if ( store->currentPath() != QString( testDir2Result ) )
+ return cleanUp( store, testFile, brokenPath );
+
+ if ( store->open( "root" ) ) {
+ char buf[29];
+ store->read( buf, 28 );
+ buf[28] = '\0';
+ store->close();
+ if ( strncmp( buf, test4, 28 ) != 0 )
+ return cleanUp( store, testFile, unableToRead );
+ }
+ else
+ return cleanUp( store, testFile, unableToOpen );
+
+ if ( store->isOpen() )
+ store->close();
+ delete store;
+ QFile::remove( testFile );
+
+ kdDebug() << "===========================================================" << endl;
+ return 0;
+}
+
+int main( int argc, char **argv )
+{
+ KCmdLineArgs::init( argc, argv, "storage_test", "A test for the KoStore classes", "1" );
+ KApplication app( argc, argv );
+
+ // KZip (due to KSaveFile) doesn't support relative filenames
+ // So use $PWD as base for the paths explicitely.
+ const QString testDir = QDir::currentDirPath();
+ if ( test( "Tar", KoStore::Tar, testDir+"test.tgz" ) != 0 )
+ return 1;
+ if ( test( "Directory", KoStore::Directory, testDir+"testdir/maindoc.xml" ) != 0 )
+ return 1;
+ if ( test( "Zip", KoStore::Zip, testDir+"test.zip" ) != 0 )
+ return 1;
+}
diff --git a/lib/store/tests/storedroptest.cpp b/lib/store/tests/storedroptest.cpp
new file mode 100644
index 000000000..0510ea62a
--- /dev/null
+++ b/lib/store/tests/storedroptest.cpp
@@ -0,0 +1,138 @@
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <KoStore.h>
+#include <qtextbrowser.h>
+#include <qstringlist.h>
+#include <qbuffer.h>
+#include <qclipboard.h>
+
+class StoreDropTest : public QTextBrowser
+{
+public:
+ StoreDropTest( QWidget* parent );
+protected:
+ virtual void contentsDragEnterEvent( QDragEnterEvent * e );
+ virtual void contentsDragMoveEvent( QDragMoveEvent * e );
+ virtual void contentsDropEvent( QDropEvent * e );
+ virtual void keyPressEvent( QKeyEvent * e );
+ virtual void paste();
+private:
+ bool processMimeSource( QMimeSource* ev );
+ void showZipContents( QByteArray data, const char* mimeType, bool oasis );
+ QString loadTextFile( KoStore* store, const QString& fileName );
+};
+
+int main( int argc, char** argv )
+{
+ KApplication::disableAutoDcopRegistration();
+ KCmdLineArgs::init(argc, argv, "storedroptest", 0, 0, 0, 0);
+ KApplication app;
+
+ StoreDropTest* window = new StoreDropTest( 0 );
+ window->resize( 500, 500 );
+ window->show();
+
+ QObject::connect( qApp, SIGNAL( lastWindowClosed() ), qApp, SLOT( quit() ) );
+ return app.exec();
+}
+
+StoreDropTest::StoreDropTest( QWidget* parent )
+ : QTextBrowser( parent )
+{
+ setText( "KoStore drop/paste test\nDrop or paste a selection from a KOffice application into this widget to see the ZIP contents" );
+ setAcceptDrops( true );
+}
+
+void StoreDropTest::contentsDragEnterEvent( QDragEnterEvent * ev )
+{
+ ev->acceptAction();
+}
+
+void StoreDropTest::contentsDragMoveEvent( QDragMoveEvent * ev )
+{
+ ev->acceptAction();
+}
+
+void StoreDropTest::keyPressEvent( QKeyEvent * e )
+{
+ if ( ( ( e->state() & ShiftButton ) && e->key() == Key_Insert ) ||
+ ( ( e->state() & ControlButton ) && e->key() == Key_V ) )
+ paste();
+ //else
+ // QTextBrowser::keyPressEvent( e );
+}
+
+void StoreDropTest::paste()
+{
+ qDebug( "paste" );
+ QMimeSource* m = QApplication::clipboard()->data();
+ if ( !m )
+ return;
+ processMimeSource( m );
+}
+
+void StoreDropTest::contentsDropEvent( QDropEvent *ev )
+{
+ if ( processMimeSource( ev ) )
+ ev->acceptAction();
+ else
+ ev->ignore();
+}
+
+bool StoreDropTest::processMimeSource( QMimeSource* ev )
+{
+ const QCString acceptMimeType = "application/vnd.oasis.opendocument.";
+ const char* fmt;
+ QStringList formats;
+ for (int i=0; (fmt = ev->format(i)); i++) {
+ formats += fmt;
+ bool oasis = QString( fmt ).startsWith( acceptMimeType );
+ if ( oasis || QString( fmt ) == "application/x-kpresenter" ) {
+ QByteArray data = ev->encodedData( fmt );
+ showZipContents( data, fmt, oasis );
+ return true;
+ }
+ }
+ setText( "No acceptable format found. All I got was:\n" + formats.join( "\n" ) );
+ return false;
+}
+
+void StoreDropTest::showZipContents( QByteArray data, const char* mimeType, bool oasis )
+{
+ if ( data.isEmpty() ) {
+ setText( "No data!" );
+ return;
+ }
+ QBuffer buffer( data );
+ KoStore * store = KoStore::createStore( &buffer, KoStore::Read );
+ if ( store->bad() ) {
+ setText( "Invalid ZIP!" );
+ return;
+ }
+ store->disallowNameExpansion();
+
+ QString txt = QString( "Valid ZIP file found for format " ) + mimeType + "\n";
+
+ if ( oasis ) {
+ txt += loadTextFile( store, "content.xml" );
+ txt += loadTextFile( store, "styles.xml" );
+ txt += loadTextFile( store, "settings.xml" );
+ txt += loadTextFile( store, "META-INF/manifest.xml" );
+ } else {
+ txt += loadTextFile( store, "maindoc.xml" );
+ }
+ setText( txt );
+}
+
+QString StoreDropTest::loadTextFile( KoStore* store, const QString& fileName )
+{
+ if ( !store->open( fileName ) )
+ return QString( "%1 not found\n" ).arg( fileName );
+
+ QByteArray data = store->device()->readAll();
+ store->close();
+ QString txt = QString( "Found %1: \n" ).arg( fileName );
+ txt += QString::fromUtf8( data.data(), data.size() );
+ txt += "\n";
+ return txt;
+}
diff --git a/lib/store/tests/xmlwritertest.cpp b/lib/store/tests/xmlwritertest.cpp
new file mode 100644
index 000000000..dad86f8f4
--- /dev/null
+++ b/lib/store/tests/xmlwritertest.cpp
@@ -0,0 +1,144 @@
+#include "xmlwritertest.h"
+
+#include "KoXmlWriter.h"
+
+#include <qapplication.h>
+#include <qfile.h>
+#include <qdatetime.h>
+
+static const int numParagraphs = 30000;
+void speedTest()
+{
+ QTime time;
+ time.start();
+ QString paragText = QString::fromUtf8( "This is the text of the paragraph. I'm including a euro sign to test encoding issues: €" );
+ QCString styleName = "Heading 1";
+
+ QFile out( QString::fromLatin1( "out5.xml" ) );
+ if ( out.open(IO_WriteOnly) )
+ {
+ KoXmlWriter writer( &out );
+ writer.startDocument( "rootelem" );
+ writer.startElement( "rootelem" );
+ for ( int i = 0 ; i < numParagraphs ; ++i )
+ {
+ writer.startElement( "paragraph" );
+ writer.addAttribute( "text:style-name", styleName );
+ writer.addTextNode( paragText );
+ writer.endElement();
+ }
+ writer.endElement();
+ writer.endDocument();
+ }
+ out.close();
+ qDebug( "writing %i XML elements using KoXmlWriter: %i ms", numParagraphs, time.elapsed() );
+}
+
+int main( int argc, char** argv ) {
+ QApplication app( argc, argv, QApplication::Tty );
+
+ TEST_BEGIN( 0, 0 );
+ TEST_END( "framework test", "<r/>\n" );
+
+ TEST_BEGIN( "-//KDE//DTD kword 1.3//EN", "http://www.koffice.org/DTD/kword-1.3.dtd" );
+ TEST_END( "doctype test", "<!DOCTYPE r PUBLIC \"-//KDE//DTD kword 1.3//EN\" \"http://www.koffice.org/DTD/kword-1.3.dtd\">\n<r/>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.addAttribute( "a", "val" );
+ writer.addAttribute( "b", "<\">" );
+ writer.addAttribute( "c", -42 );
+ writer.addAttribute( "d", 1234.56789012345 );
+ writer.addAttributePt( "e", 1234.56789012345 );
+ TEST_END( "attributes test", "<r a=\"val\" b=\"&lt;&quot;&gt;\" c=\"-42\" d=\"1234.56789012345\" e=\"1234.56789012345pt\"/>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "m" );
+ writer.endElement();
+ TEST_END( "empty element test", "<r>\n <m/>\n</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "a" );
+ writer.startElement( "b" );
+ writer.startElement( "c" );
+ writer.endElement();
+ writer.endElement();
+ writer.endElement();
+ TEST_END( "indent test", "<r>\n <a>\n <b>\n <c/>\n </b>\n </a>\n</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "a" );
+ writer.startElement( "b", false /*no indent*/ );
+ writer.startElement( "c" );
+ writer.endElement();
+ writer.addTextNode( "te" );
+ writer.addTextNode( "xt" );
+ writer.endElement();
+ writer.endElement();
+ TEST_END( "textnode test", "<r>\n <a>\n <b><c/>text</b>\n </a>\n</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "p", false /*no indent*/ );
+ writer.addTextSpan( QString::fromLatin1( " \t\n foo " ) );
+ writer.endElement();
+ TEST_END( "textspan test", "<r>\n"
+ " <p><text:s text:c=\"3\"/><text:tab/><text:line-break/> foo<text:s text:c=\"2\"/></p>\n"
+ "</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "p", false /*no indent*/ );
+ QMap<int, int> tabCache;
+ tabCache.insert( 3, 0 );
+ writer.addTextSpan( QString::fromUtf8( " \t\n foö " ), tabCache );
+ writer.endElement();
+ TEST_END( "textspan with tabcache", "<r>\n"
+ " <p><text:s text:c=\"3\"/><text:tab text:tab-ref=\"1\"/><text:line-break/> foö<text:s text:c=\"2\"/></p>\n"
+ "</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.startElement( "p", false /*no indent*/ );
+ writer.addProcessingInstruction( "opendocument foobar" );
+ writer.addTextSpan( QString::fromLatin1( "foo" ) );
+ writer.endElement();
+ TEST_END( "processinginstruction test", "<r>\n"
+ " <p><?opendocument foobar?>foo</p>\n"
+ "</r>\n" );
+
+ TEST_BEGIN( 0, 0 );
+ writer.addManifestEntry( QString::fromLatin1( "foo/bar/blah" ), QString::fromLatin1( "mime/type" ) );
+ TEST_END( "addManifestEntry", "<r>\n <manifest:file-entry manifest:media-type=\"mime/type\" manifest:full-path=\"foo/bar/blah\"/>\n</r>\n" );
+
+ int sz = 15000; // must be more than KoXmlWriter::s_escapeBufferLen
+ QCString x( sz );
+ x.fill( 'x', sz );
+ x += '&';
+ QCString expected = "<r a=\"";
+ expected += x + "amp;\"/>\n";
+ TEST_BEGIN( 0, 0 );
+ writer.addAttribute( "a", x );
+ TEST_END( "escaping long cstring", expected.data() );
+
+ QString longPath;
+ for ( uint i = 0 ; i < 1000 ; ++i )
+ longPath += QString::fromLatin1( "M10 10L20 20 " );
+ expected = "<r a=\"";
+ expected += longPath.utf8() + "\"/>\n";
+ TEST_BEGIN( 0, 0 );
+ writer.addAttribute( "a", longPath );
+ TEST_END( "escaping long qstring", expected.data() );
+
+
+ TEST_BEGIN( 0, 0 );
+ bool val = true;
+ int num = 1;
+ double numdouble = 5.0;
+ writer.addConfigItem( QString::fromLatin1( "TestConfigBool" ), val );
+ writer.addConfigItem( QString::fromLatin1( "TestConfigInt" ), num );
+ writer.addConfigItem( QString::fromLatin1( "TestConfigDouble" ), numdouble );
+ TEST_END( "test config", "<r>\n"
+ " <config:config-item config:name=\"TestConfigBool\" config:type=\"boolean\">true</config:config-item>\n"
+ " <config:config-item config:name=\"TestConfigInt\" config:type=\"int\">1</config:config-item>\n"
+ " <config:config-item config:name=\"TestConfigDouble\" config:type=\"double\">5</config:config-item>\n"
+ "</r>\n" );
+
+ speedTest();
+}
diff --git a/lib/store/tests/xmlwritertest.h b/lib/store/tests/xmlwritertest.h
new file mode 100644
index 000000000..c5dc76e75
--- /dev/null
+++ b/lib/store/tests/xmlwritertest.h
@@ -0,0 +1,46 @@
+#ifndef XMLWRITERTEST_H
+#define XMLWRITERTEST_H
+
+#define QT_NO_CAST_ASCII
+
+// Those macros are in a separate header file in order to share them
+// with kofficecore/tests/kogenstylestest.cpp
+
+#include <qbuffer.h>
+#include <qregexp.h>
+
+#define TEST_BEGIN(publicId,systemId) \
+ { \
+ QCString cstr; \
+ QBuffer buffer( cstr ); \
+ buffer.open( IO_WriteOnly ); \
+ { \
+ KoXmlWriter writer( &buffer ); \
+ writer.startDocument( "r", publicId, systemId ); \
+ writer.startElement( "r" )
+
+#define TEST_END(testname, expected) \
+ writer.endElement(); \
+ writer.endDocument(); \
+ } \
+ buffer.putch( '\0' ); /*null-terminate*/ \
+ QCString expectedFull( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); \
+ expectedFull += expected; \
+ if ( cstr == expectedFull ) \
+ qDebug( "%s OK", testname ); \
+ else { \
+ qDebug( "%s FAILED!", testname ); \
+ QCString s1 = cstr; \
+ QCString s2 = expectedFull; \
+ if ( s1.length() != s2.length() ) \
+ qDebug( "got length %d, expected %d", s1.length(), s2.length() ); \
+ s1.replace( QRegExp( QString::fromLatin1( "[x]{1000}" ) ), "[x]*1000" ); \
+ s2.replace( QRegExp( QString::fromLatin1( "[x]{1000}" ) ), "[x]*1000" ); \
+ qDebug( "%s", s1.data() ); \
+ qDebug( "Expected:\n%s", s2.data() ); \
+ return 1; /*exit*/ \
+ } \
+ }
+
+
+#endif