diff --git a/kabc/contactgrouptool.cpp b/kabc/contactgrouptool.cpp index d4345c54d..a9cf82b76 100644 --- a/kabc/contactgrouptool.cpp +++ b/kabc/contactgrouptool.cpp @@ -1,215 +1,324 @@ /* This file is part of libkabc. Copyright (c) 2008 Tobias Koenig + Copyright (c) 2008 Kevin Krammer 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 "contactgrouptool.h" + +#include "contactgroup.h" + #include #include #include #include #include -#include "contactgroup.h" - -#include "contactgrouptool.h" - using namespace KABC; class XmlContactGroupWriter : public QXmlStreamWriter { public: - XmlContactGroupWriter( const ContactGroup &group ); + XmlContactGroupWriter(); - void write( QIODevice *device ); + void write( const ContactGroup &group, QIODevice *device ); + void write( const QList &groupLis, QIODevice *device ); private: + void writeGroup( const ContactGroup &group ); void writeReference( const ContactGroup::Reference& ); void writeData( const ContactGroup::Data& ); - - ContactGroup mGroup; }; -XmlContactGroupWriter::XmlContactGroupWriter( const ContactGroup &group ) - : mGroup( group ) +XmlContactGroupWriter::XmlContactGroupWriter() { setAutoFormatting( true ); } -void XmlContactGroupWriter::write( QIODevice *device ) +void XmlContactGroupWriter::write( const ContactGroup &group, QIODevice *device ) { setDevice( device ); writeStartDocument(); - writeStartElement( "contactGroup" ); - writeAttribute( "uid", mGroup.id() ); - writeAttribute( "name", mGroup.name() ); + writeGroup( group ); - for ( uint i = 0; i < mGroup.referencesCount(); ++i ) { - writeReference( mGroup.reference( i ) ); - } + writeEndDocument(); +} - for ( uint i = 0; i < mGroup.dataCount(); ++i ) { - writeData( mGroup.data( i ) ); +void XmlContactGroupWriter::write( const QList &groupList, QIODevice *device ) +{ + setDevice( device ); + + writeStartDocument(); + + writeStartElement( "contactGroupList" ); + + foreach ( const ContactGroup & group, groupList ) { + writeGroup( group ); } writeEndElement(); writeEndDocument(); } +void XmlContactGroupWriter::writeGroup( const ContactGroup &group ) +{ + writeStartElement( "contactGroup" ); + writeAttribute( "uid", group.id() ); + writeAttribute( "name", group.name() ); + + for ( uint i = 0; i < group.referencesCount(); ++i ) { + writeReference( group.reference( i ) ); + } + + for ( uint i = 0; i < group.dataCount(); ++i ) { + writeData( group.data( i ) ); + } + + writeEndElement(); +} + void XmlContactGroupWriter::writeReference( const ContactGroup::Reference &reference ) { writeStartElement( "contactReference" ); writeAttribute( "uid", reference.uid() ); if ( !reference.preferredEmail().isEmpty() ) writeAttribute( "preferredEmail", reference.preferredEmail() ); // TODO: customs writeEndElement(); } void XmlContactGroupWriter::writeData( const ContactGroup::Data &data ) { writeStartElement( "contactData" ); writeAttribute( "name", data.name() ); writeAttribute( "email", data.email() ); // TODO: customs writeEndElement(); } class XmlContactGroupReader : public QXmlStreamReader { public: - XmlContactGroupReader( ContactGroup *group ); + XmlContactGroupReader(); - bool read( QIODevice *device ); + bool read( QIODevice *device, ContactGroup &group ); + bool read( QIODevice *device, QList &groupList ); private: - bool readReference(); - bool readData(); - - ContactGroup *mGroup; + bool readGroup( ContactGroup &group ); + bool readReference( ContactGroup::Reference &reference ); + bool readData( ContactGroup::Data &data ); }; -XmlContactGroupReader::XmlContactGroupReader( ContactGroup *group ) - : mGroup( group ) +XmlContactGroupReader::XmlContactGroupReader() { - Q_ASSERT_X( group != 0, "XmlContactGroupReader", "Passed an invalid group" ); } -bool XmlContactGroupReader::read( QIODevice *device ) +bool XmlContactGroupReader::read( QIODevice *device, ContactGroup &group ) +{ + setDevice( device ); + + while ( !atEnd() ) { + readNext(); + if ( isStartElement() ) { + if ( name() == QLatin1String( "contactGroup" ) ) { + return readGroup( group ); + } else { + raiseError( "The document does not describe a ContactGroup" ); + } + } + } + + return error() == NoError; +} + +bool XmlContactGroupReader::read( QIODevice *device, QList &groupList ) { setDevice( device ); int depth = 0; while ( !atEnd() ) { readNext(); - if ( isStartElement() ) { ++depth; if ( depth == 1 ) { - if ( name() == QLatin1String( "contactGroup" ) ) { - const QXmlStreamAttributes elementAttributes = attributes(); - const QStringRef uid = elementAttributes.value( "uid" ); - if ( uid.isEmpty() ) { - raiseError( "ContactGroup is missing a uid" ); - continue; - } - - const QStringRef name = elementAttributes.value( "name" ); - if ( name.isEmpty() ) { - raiseError( "ContactGroup is missing a name" ); - continue; - } - - mGroup->setId( uid.toString() ); - mGroup->setName( name.toString() ); + if ( name() == QLatin1String( "contactGroupList" ) ) { + continue; } else { - raiseError( "The document does not describe a ContactGroup" ); + raiseError( "The document does not describe a list of ContactGroup" ); } } else if ( depth == 2 ) { - if ( name() == QLatin1String( "contactData" ) ) { - const QXmlStreamAttributes elementAttributes = attributes(); - const QStringRef email = elementAttributes.value( "email" ); - if ( email.isEmpty() ) { - raiseError( "ContactData is missing an email address" ); - continue; - } - - const QStringRef name = elementAttributes.value( "name" ); - if ( name.isEmpty() ) { - raiseError( "ContactData is missing a name" ); - continue; - } - - ContactGroup::Data data( name.toString(), email.toString() ); - mGroup->append( data ); - } else if ( name() == QLatin1String( "contactReference" ) ) { - const QXmlStreamAttributes elementAttributes = attributes(); - const QStringRef uid = elementAttributes.value( "uid" ); - if ( uid.isEmpty() ) { - raiseError( "ContactReference is missing a uid" ); - continue; - } - - ContactGroup::Reference reference( uid.toString() ); - mGroup->append( reference ); + if ( name() == QLatin1String( "contactGroup" ) ) { + ContactGroup group; + if ( !readGroup( group ) ) + return false; + + groupList.append( group ); } else { - raiseError( "The document does not describe a ContactGroup" ); + raiseError( "The document does not describe a list of ContactGroup" ); } - } else { - raiseError( "The document does not describe a ContactGroup" ); } - } else if ( isEndElement() ) { + } + + if ( isEndElement() ) { --depth; } } - return !error(); + return error() == NoError; +} + +bool XmlContactGroupReader::readGroup( ContactGroup &group ) +{ + const QXmlStreamAttributes elementAttributes = attributes(); + const QStringRef uid = elementAttributes.value( "uid" ); + if ( uid.isEmpty() ) { + raiseError( "ContactGroup is missing a uid" ); + return false; + } + + const QStringRef groupName = elementAttributes.value( "name" ); + if ( groupName.isEmpty() ) { + raiseError( "ContactGroup is missing a name" ); + return false; + } + + group.setId( uid.toString() ); + group.setName( groupName.toString() ); + + while ( !atEnd() ) { + readNext(); + if ( isStartElement() ) { + if ( name() == QLatin1String( "contactData" ) ) { + ContactGroup::Data data; + if ( !readData( data ) ) + return false; + + group.append( data ); + } else if ( name() == QLatin1String( "contactReference" ) ) { + ContactGroup::Reference reference; + if ( !readReference( reference ) ) + return false; + + group.append( reference ); + } else { + raiseError( "The document does not describe a ContactGroup" ); + } + } + + if ( isEndElement() ) { + if ( name() == QLatin1String( "contactGroup" ) ) + return true; + } + } + + return false; +} + +bool XmlContactGroupReader::readData( ContactGroup::Data &data ) +{ + const QXmlStreamAttributes elementAttributes = attributes(); + const QStringRef email = elementAttributes.value( "email" ); + if ( email.isEmpty() ) { + raiseError( "ContactData is missing an email address" ); + return false; + } + + const QStringRef name = elementAttributes.value( "name" ); + if ( name.isEmpty() ) { + raiseError( "ContactData is missing a name" ); + return false; + } + + data.setName( name.toString() ); + data.setEmail( email.toString() ); + + return true; +} + +bool XmlContactGroupReader::readReference( ContactGroup::Reference &reference ) +{ + const QXmlStreamAttributes elementAttributes = attributes(); + const QStringRef uid = elementAttributes.value( "uid" ); + if ( uid.isEmpty() ) { + raiseError( "ContactReference is missing a uid" ); + return false; + } + + reference.setUid( uid.toString() ); + + return true; } bool ContactGroupTool::convertFromXml( QIODevice *device, ContactGroup &group, QString *errorMessage ) { Q_UNUSED( errorMessage ) - XmlContactGroupReader reader( &group ); + XmlContactGroupReader reader; - bool ok = reader.read( device ); + bool ok = reader.read( device, group ); if ( !ok && errorMessage != 0 ) *errorMessage = reader.errorString(); return ok; } bool ContactGroupTool::convertToXml( const ContactGroup &group, QIODevice *device, QString *errorMessage ) { Q_UNUSED( errorMessage ) - XmlContactGroupWriter writer( group ); - writer.write( device ); + XmlContactGroupWriter writer; + writer.write( group, device ); + + return true; +} + +bool ContactGroupTool::convertFromXml( QIODevice *device, QList &groupList, QString *errorMessage ) +{ + Q_UNUSED( errorMessage ) + + XmlContactGroupReader reader; + + bool ok = reader.read( device, groupList ); + + if ( !ok && errorMessage != 0 ) + *errorMessage = reader.errorString(); + + return ok; +} + +bool ContactGroupTool::convertToXml( const QList &groupList, QIODevice *device, QString *errorMessage ) +{ + Q_UNUSED( errorMessage ) + + XmlContactGroupWriter writer; + writer.write( groupList, device ); return true; } diff --git a/kabc/contactgrouptool.h b/kabc/contactgrouptool.h index 53a8632f3..3434d65db 100644 --- a/kabc/contactgrouptool.h +++ b/kabc/contactgrouptool.h @@ -1,46 +1,52 @@ /* This file is part of libkabc. Copyright (c) 2008 Tobias Koenig + Copyright (c) 2008 Kevin Krammer 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. */ #ifndef KABC_CONTACTGROUPTOOL_H #define KABC_CONTACTGROUPTOOL_H #include "kabc_export.h" class QIODevice; class QString; +template class QList; + namespace KABC { class ContactGroup; /** * * @since 4.2 */ class KABC_EXPORT ContactGroupTool { public: static bool convertFromXml( QIODevice *device, ContactGroup &group, QString *errorMessage = 0 ); static bool convertToXml( const ContactGroup &group, QIODevice *device, QString *errorMessage = 0 ); + + static bool convertFromXml( QIODevice *device, QList &groupList, QString *errorMessage = 0 ); + static bool convertToXml( const QList &groupList, QIODevice *device, QString *errorMessage = 0 ); }; } #endif diff --git a/kabc/tests/CMakeLists.txt b/kabc/tests/CMakeLists.txt index 7b029ed32..f4f5efbb5 100644 --- a/kabc/tests/CMakeLists.txt +++ b/kabc/tests/CMakeLists.txt @@ -1,166 +1,175 @@ set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) include_directories( ${CMAKE_SOURCE_DIR}/kabc ) ########### next target ############### set(addresstest_SRCS addresstest.cpp) kde4_add_unit_test(addresstest TESTNAME kabc-addresstest ${addresstest_SRCS}) target_link_libraries(addresstest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(addresseetest_SRCS addresseetest.cpp) kde4_add_unit_test(addresseetest TESTNAME kabc-addresseetest ${addresseetest_SRCS}) target_link_libraries(addresseetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(geotest_SRCS geotest.cpp) kde4_add_unit_test(geotest TESTNAME kabc-geotest ${geotest_SRCS}) target_link_libraries(geotest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(keytest_SRCS keytest.cpp) kde4_add_unit_test(keytest TESTNAME kabc-keytest ${keytest_SRCS}) target_link_libraries(keytest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(phonenumbertest_SRCS phonenumbertest.cpp) kde4_add_unit_test(phonenumbertest TESTNAME kabc-phonenumbertest ${phonenumbertest_SRCS}) target_link_libraries(phonenumbertest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(picturetest_SRCS picturetest.cpp) kde4_add_unit_test(picturetest TESTNAME kabc-picturetest ${picturetest_SRCS}) target_link_libraries(picturetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(secrecytest_SRCS secrecytest.cpp) kde4_add_unit_test(secrecytest TESTNAME kabc-secrecytest ${secrecytest_SRCS}) target_link_libraries(secrecytest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(soundtest_SRCS soundtest.cpp) kde4_add_unit_test(soundtest TESTNAME kabc-soundtest ${soundtest_SRCS}) target_link_libraries(soundtest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(timezonetest_SRCS timezonetest.cpp) kde4_add_unit_test(timezonetest TESTNAME kabc-timezonetest ${timezonetest_SRCS}) target_link_libraries(timezonetest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(testlock_SRCS testlock.cpp) kde4_add_executable(testlock TEST ${testlock_SRCS}) target_link_libraries(testlock ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} kabc ${QT_QTTEST_LIBRARY} ${QT_QTGUI_LIBRARY}) ########### next target ############### set(testkabc_SRCS testkabc.cpp) kde4_add_executable(testkabc TEST ${testkabc_SRCS}) target_link_libraries(testkabc ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${KDE4_KDEUI_LIBS}) ########### next target ############### set(testkabcdlg_SRCS testkabcdlg.cpp) kde4_add_executable(testkabcdlg TEST ${testkabcdlg_SRCS}) target_link_libraries(testkabcdlg ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${KDE4_KDEUI_LIBS}) ########### next target ############### if (UNIX) set(bigread_SRCS bigread.cpp) kde4_add_executable(bigread TEST ${bigread_SRCS}) target_link_libraries(bigread ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} kabc kabc_file_core ) endif (UNIX) ########### next target ############### if (UNIX) set(bigwrite_SRCS bigwrite.cpp) kde4_add_executable(bigwrite TEST ${bigwrite_SRCS}) target_link_libraries(bigwrite ${KDE4_KDECORE_LIBS} ${KDE4_KDEUI_LIBS} kabc kabc_file_core ) endif (UNIX) ########### next target ############### #set(testaddresseelist_SRCS testaddresseelist.cpp) #kde4_add_unit_test(testaddresseelist TESTNAME kabc-testaddresseelist ${testaddresseelist_SRCS}) #target_link_libraries(testaddresseelist ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY}) ########### next target ############### set(kabcargl_SRCS kabcargl.cpp) kde4_add_executable(kabcargl TEST ${kabcargl_SRCS}) target_link_libraries(kabcargl ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${KDE4_KDEUI_LIBS} ) ########### next target ############### set(testaddresslineedit_SRCS testaddresslineedit.cpp) kde4_add_executable(testaddresslineedit TEST ${testaddresslineedit_SRCS}) target_link_libraries(testaddresslineedit ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY} ${KDE4_KDEUI_LIBS}) + +########### next target ############### + +set(contactgrouptest_SRCS contactgrouptest.cpp) + + +kde4_add_unit_test(contactgrouptest TESTNAME kabc-contactgrouptest ${contactgrouptest_SRCS}) + +target_link_libraries(contactgrouptest ${KDE4_KDECORE_LIBS} kabc ${QT_QTTEST_LIBRARY}) diff --git a/kabc/tests/contactgrouptest.cpp b/kabc/tests/contactgrouptest.cpp new file mode 100644 index 000000000..33979e249 --- /dev/null +++ b/kabc/tests/contactgrouptest.cpp @@ -0,0 +1,113 @@ +/* + This file is part of libkabc. + Copyright (c) 2008 Kevin Krammer + + 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 + +#include "kabc/contactgroup.h" +#include "kabc/contactgrouptool.h" + +#include + +using namespace KABC; + +class ContactGroupTest : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void testGroupRoundTrip(); + void testGroupListRoundTrip(); +}; + +QTEST_KDEMAIN( ContactGroupTest, NoGUI ) + +void ContactGroupTest::testGroupRoundTrip() +{ + // TODO should also test empty group + + ContactGroup group( "TestGroup" ); + group.append( ContactGroup::Reference( "Xggdjetw" ) ); + group.append( ContactGroup::Data( "Tobias Koenig", "tokoe@kde.org" ) ); + group.append( ContactGroup::Data( "Kevin Krammer", "kevin.krammer@gmx.at" ) ); + + QBuffer buffer; + buffer.open( QIODevice::WriteOnly ); + + QString errorMessage; + bool result = ContactGroupTool::convertToXml( group, &buffer, &errorMessage ); + + QVERIFY( result ); + QVERIFY( errorMessage.isEmpty() ); + buffer.close(); + QVERIFY( buffer.size() > 0 ); + buffer.open( QIODevice::ReadOnly ); + + ContactGroup group2; + result = ContactGroupTool::convertFromXml( &buffer, group2, &errorMessage ); + QVERIFY( result ); + QVERIFY( errorMessage.isEmpty() ); + QCOMPARE( group, group2 ); +} + +void ContactGroupTest::testGroupListRoundTrip() +{ + // TODO should also test empty list + + ContactGroup::List list; + + ContactGroup group1( "TestGroup1" ); + group1.append( ContactGroup::Reference( "Xggdjetw" ) ); + group1.append( ContactGroup::Data( "Tobias Koenig", "tokoe@kde.org" ) ); + group1.append( ContactGroup::Data( "Kevin Krammer", "kevin.krammer@gmx.at" ) ); + + list.append( group1 ); + + ContactGroup group2( "TestGroup2" ); + group2.append( ContactGroup::Reference( "Xggdjetw" ) ); + group2.append( ContactGroup::Data( "Tobias Koenig", "tokoe@kde.org" ) ); + group2.append( ContactGroup::Data( "Kevin Krammer", "kevin.krammer@gmx.at" ) ); + + list.append( group2 ); + + QBuffer buffer; + buffer.open( QIODevice::WriteOnly ); + + QString errorMessage; + bool result = ContactGroupTool::convertToXml( list, &buffer, &errorMessage ); + + QVERIFY( result ); + QVERIFY( errorMessage.isEmpty() ); + buffer.close(); + QVERIFY( buffer.size() > 0 ); + + buffer.open( QIODevice::ReadOnly ); + + ContactGroup::List list2; + result = ContactGroupTool::convertFromXml( &buffer, list2, &errorMessage ); + QVERIFY( result ); + QVERIFY( errorMessage.isEmpty() ); + QVERIFY( list2.size() == 2 ); + QCOMPARE( list2[0], group1 ); + QCOMPARE( list2[1], group2 ); +} + +#include "contactgrouptest.moc" + +// kate: space-indent on; indent-width 2; replace-tabs on;