diff options
Diffstat (limited to 'lib/store/tests')
-rw-r--r-- | lib/store/tests/Makefile.am | 18 | ||||
-rw-r--r-- | lib/store/tests/storage_test.cpp | 220 | ||||
-rw-r--r-- | lib/store/tests/storedroptest.cpp | 138 | ||||
-rw-r--r-- | lib/store/tests/xmlwritertest.cpp | 144 | ||||
-rw-r--r-- | lib/store/tests/xmlwritertest.h | 46 |
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=\"<">\" 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 |