From kde-commits Thu Jun 18 16:24:54 2009 From: Bertjan Broeksema Date: Thu, 18 Jun 2009 16:24:54 +0000 To: kde-commits Subject: KDE/kdepim/akonadi/resources/mbox/libmbox Message-Id: <1245342294.608306.1313.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=124534230427291 SVN commit 983626 by bbroeksema: Add some first tests for loading and saving. Make those tests actually work. Some more tests are needed,especially to test behavior when message have an arbitrary number of '\n' characters appended. M +26 -19 mbox.cpp M +39 -0 tests/mboxtest.cpp M +1 -0 tests/mboxtest.h --- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/mbox.cpp #983625:983626 @@ -114,22 +114,20 @@ return -1; } - int nextOffset = d->mAppendedEntries.size() - 1; // Offset of the appended message + int nextOffset = d->mAppendedEntries.size(); // Offset of the appended message // Make sure the byte array is large enough to check for an end character. // Then check if the required newlines are there. - if ( nextOffset < 1 ) { // Empty, add one empty line - if ( d->mMboxFile.size() == 0 ) { - d->mAppendedEntries.append( "\n"); - ++nextOffset; - } + if ( nextOffset < 1 && d->mMboxFile.size() > 0 ) { // Empty, add one empty line + d->mAppendedEntries.append( "\n"); + ++nextOffset; } else if ( nextOffset == 1 && d->mAppendedEntries.at( 0 ) != '\n' ) { // This should actually not happen, but catch it anyway. if (d->mMboxFile.size() < 0 ) { d->mAppendedEntries.append( "\n"); ++nextOffset; } - } else { + } else if (nextOffset >= 2) { if ( d->mAppendedEntries.at( nextOffset - 1 ) != '\n' ) { if ( d->mAppendedEntries.at( nextOffset ) != '\n' ) { d->mAppendedEntries.append( "\n\n" ); @@ -157,8 +155,6 @@ QList MBox::entryList(const QSet &deletedItems) const { - Q_ASSERT(d->mMboxFile.isOpen()); - QList result; foreach ( const MsgInfo &info, d->mEntries ) { @@ -175,7 +171,7 @@ return false; d->mMboxFile.setFileName( KUrl(fileName).path() ); - if ( ! d->mMboxFile.exists() ) + if ( !d->mMboxFile.exists() && !d->mMboxFile.open( QIODevice::WriteOnly ) ) return false; if ( ! lock() ) @@ -186,17 +182,21 @@ QRegExp regexp("^From .*[0-9][0-9]:[0-9][0-9]"); QByteArray line; + QByteArray prevSeparator; quint64 offs = 0; // The offset of the next message to read. bool previousLineIsEmpty; while ( !d->mMboxFile.atEnd() ) { quint64 pos = d->mMboxFile.pos(); + previousLineIsEmpty = line.isEmpty(); + line = d->mMboxFile.readLine(); if ( regexp.indexIn(line) >= 0 || d->mMboxFile.atEnd() ) { // Found the separator or at end of file, the message starts at offs quint64 msgSize = pos - offs; + if( pos > 0 ) { // This is not the separator of the first mail in the file. If pos == 0 // than we matched the separator of the first mail in the file. @@ -207,9 +207,18 @@ // there're two new line characters we assume that one of them was added // with the seperator. info.second = previousLineIsEmpty ? (msgSize - 2) : (msgSize - 1); + if ( d->mMboxFile.atEnd() ) + info.second += 1; + // Don't add the seperator size and the newline up to the message size. + info.second -= prevSeparator.size() + 1; + d->mEntries << info; } + + if ( regexp.indexIn(line) >= 0 ) + prevSeparator = line; + offs += msgSize; // Mark the beginning of the next message. } } @@ -222,9 +231,6 @@ if ( d->mMboxFile.fileName().isEmpty() ) return false; // We cannot lock if there is no file loaded. - if ( d->mLockType == None ) - return true; - d->mFileLocked = false; QStringList args; @@ -287,8 +293,9 @@ } break; - case None: // This is never reached because of the check at the - return 0; // beginning of the function. + case None: + d->mFileLocked = true; + break; default: break; } @@ -386,8 +393,7 @@ bool MBox::save( const QString &fileName ) { - if ( d->mMboxFile.fileName().isEmpty() - || KUrl( fileName ).path() != d->mMboxFile.fileName() ) + if ( !fileName.isEmpty() && KUrl( fileName ).path() != d->mMboxFile.fileName() ) { // File saved != file loaded from return false; // FIXME: Implement this case @@ -399,12 +405,13 @@ if ( !lock() ) return false; + Q_ASSERT( d->mMboxFile.isOpen() ); + d->mMboxFile.seek( d->mMboxFile.size() ); d->mMboxFile.write( d->mAppendedEntries ); d->mAppendedEntries.clear(); - unlock(); - return true; + return unlock(); } bool MBox::setLockType(LockType ltype) --- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/tests/mboxtest.cpp #983625:983626 @@ -169,6 +169,45 @@ QCOMPARE( mbox.entryList().last().second, static_cast( sEntry2.size() ) ); } +void MboxTest::testSaveAndLoad() +{ + QFile file( fileName() ); + file.remove(); + QVERIFY( !file.exists() ); + + MBox mbox; + QVERIFY( mbox.setLockType( MBox::None ) ); + QVERIFY( mbox.load( fileName() ) ); + mbox.appendEntry( mMail1 ); + mbox.appendEntry( mMail2 ); + + QList infos1 = mbox.entryList(); + QCOMPARE( infos1.size(), 2 ); + + QVERIFY( mbox.save() ); + QVERIFY( file.exists() ); + + QList infos2 = mbox.entryList(); + QCOMPARE( infos2.size(), 2 ); + + for ( int i = 0; i < 2; ++i ) { + QCOMPARE( infos1.at(i).first, infos2.at(i).first ); + QCOMPARE( infos1.at(i).second, infos2.at(i).second ); + } + + MBox mbox2; + QVERIFY( mbox2.setLockType( MBox::None ) ); + QVERIFY( mbox2.load( fileName() ) ); + + QList infos3 = mbox2.entryList(); + QCOMPARE( infos3.size(), 2 ); + + for ( int i = 0; i < 2; ++i ) { + QCOMPARE( infos3.at(i).first, infos2.at(i).first ); + QCOMPARE( infos3.at(i).second, infos2.at(i).second ); + } +} + void MboxTest::cleanupTestCase() { mTempDir->unlink(); --- trunk/KDE/kdepim/akonadi/resources/mbox/libmbox/tests/mboxtest.h #983625:983626 @@ -35,6 +35,7 @@ void testLockBeforeLoad(); void testProcMailLock(); void testAppend(); + void testSaveAndLoad(); void cleanupTestCase(); private: