2 commits - c++/lib c++/tests

Christian Mollekopf mollekopf at kolabsys.com
Thu Mar 1 14:26:05 CET 2012


 c++/lib/kolabcontainers.cpp      |   20 +
 c++/lib/kolabcontainers.h        |    1 
 c++/lib/kolabkcalconversion.cpp  |  367 ++++++++++++++++++++++++++++++---
 c++/lib/kolabkcalconversion.h    |   24 +-
 c++/tests/kcalconversiontest.cpp |  423 +++++++++++++++++++++++++++------------
 c++/tests/kcalconversiontest.h   |   15 -
 6 files changed, 687 insertions(+), 163 deletions(-)

New commits:
commit 1b10e0759c73a7298db29f762ff3f9682fba088e
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Mar 1 14:25:56 2012 +0100

    More KCalConversion

diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index cc46ee2..88ec2bc 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -30,9 +30,14 @@ namespace KCalConversion {
 KDateTime toDate(const Kolab::DateTime &dt)
 {
     KDateTime date;
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return KDateTime();
+    }
     if (dt.isDateOnly()) { //Date only
         date.setDateOnly(true);
         date.setDate(QDate(dt.year(), dt.month(), dt.day()));
+        date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
     } else {
         date.setDate(QDate(dt.year(), dt.month(), dt.day()));
         date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
@@ -47,13 +52,21 @@ KDateTime toDate(const Kolab::DateTime &dt)
                 }
             }
             date.setTimeSpec(KDateTime::Spec(tz));
-        } //Floating
+        } else { //Floating
+            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
+        }
     }
+    Q_ASSERT(date.timeSpec().isValid());
+    Q_ASSERT(date.isValid());
     return date;
 }
 
 DateTime fromDate(const KDateTime &dt)
 {
+    if (!dt.isValid()) {
+//         qDebug() << "invalid datetime converted";
+        return DateTime();
+    }
     DateTime date;
     if (dt.isDateOnly()) { //Date only
         const QDate &d = dt.date();
@@ -70,8 +83,10 @@ DateTime fromDate(const KDateTime &dt)
             date.setTimezone(dt.timeZone().name().toStdString()); //FIXME use system independent name according to spec
         } else if (dt.timeType() != KDateTime::ClockTime) {
             qWarning() << "invalid timespec, assuming floating time" << dt.timeType();
+            return DateTime();
         }
     }
+    Q_ASSERT(date.isValid());
     return date;
 }
 
@@ -99,12 +114,34 @@ KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
     return KCalCore::Incidence::SecrecyPublic;
 }
 
+Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
+{
+    switch(c) {
+        case KCalCore::Incidence::SecrecyPublic:
+            return Kolab::Public;
+        case KCalCore::Incidence::SecrecyPrivate:
+            return Kolab::Private;
+        case KCalCore::Incidence::SecrecyConfidential:
+            return Kolab::Confidential;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::Public;
+}
+
 int toPriority(int priority)
 {
     //Same mapping
     return priority;
 }
 
+int fromPriority(int priority)
+{
+    //Same mapping
+    return priority;
+}
+
 KCalCore::Incidence::Status toStatus(Kolab::Status s)
 {
     switch (s) {
@@ -133,6 +170,34 @@ KCalCore::Incidence::Status toStatus(Kolab::Status s)
     return KCalCore::Incidence::StatusNone;
 }
 
+Kolab::Status fromStatus(KCalCore::Incidence::Status s)
+{
+    switch (s) {
+        case KCalCore::Incidence::StatusNone:
+            return UndefinedStatus;
+        case KCalCore::Incidence::StatusNeedsAction:
+            return NeedsAction;
+        case KCalCore::Incidence::StatusCompleted:
+            return Completed;
+        case KCalCore::Incidence::StatusInProcess:
+            return InProcess;
+        case KCalCore::Incidence::StatusCanceled:
+            return Cancelled;
+        case KCalCore::Incidence::StatusTentative:
+            return Tentative;
+        case KCalCore::Incidence::StatusConfirmed:
+            return Confirmed;
+        case KCalCore::Incidence::StatusDraft:
+            return Draft;
+        case KCalCore::Incidence::StatusFinal:
+            return Final;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return UndefinedStatus;
+}
+
 QStringList toStringList(const std::vector<std::string> &l)
 {
     QStringList list;
@@ -142,6 +207,15 @@ QStringList toStringList(const std::vector<std::string> &l)
     return list;
 }
 
+std::vector<std::string> fromStringList(const QStringList &l)
+{
+    std::vector<std::string> list;
+    foreach(const QString &s, l) {
+        list.push_back(s.toStdString());
+    }
+    return list;
+}
+
 KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
 {
     switch (p) {
@@ -162,6 +236,26 @@ KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
     return KCalCore::Attendee::NeedsAction;
 }
 
+Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
+{
+    switch (p) {
+        case KCalCore::Attendee::NeedsAction:
+            return PartNeedsAction;
+        case KCalCore::Attendee::Accepted:
+            return PartAccepted;
+        case KCalCore::Attendee::Declined:
+            return PartDeclined;
+        case KCalCore::Attendee::Tentative:
+            return PartTentative;
+        case KCalCore::Attendee::Delegated:
+            return PartDelegated;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return PartNeedsAction;
+}
+
 KCalCore::Attendee::Role toRole(Kolab::Role r)
 {
     switch (r) {
@@ -180,7 +274,26 @@ KCalCore::Attendee::Role toRole(Kolab::Role r)
     return KCalCore::Attendee::ReqParticipant;
 }
 
-void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
+Kolab::Role fromRole(KCalCore::Attendee::Role r)
+{
+    switch (r) {
+        case KCalCore::Attendee::ReqParticipant:
+            return Required;
+        case KCalCore::Attendee::Chair:
+            return Chair;
+        case KCalCore::Attendee::OptParticipant:
+            return Optional;
+        case KCalCore::Attendee::NonParticipant:
+            return NonParticipant;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Required;
+}
+
+template <typename T>
+void setIncidence(KCalCore::Incidence &i, const T &e)
 {
     if (!e.uid().empty()) {
         i.setUid(QString::fromStdString(e.uid()));
@@ -195,15 +308,10 @@ void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
     if (e.start().isValid()) {
         i.setDtStart(toDate(e.start()));
     }
-    if (e.duration().isValid()) {
-        i.setDuration(toDuration(e.duration()));
-    }
+
     i.setSummary(QString::fromStdString(e.summary())); //TODO detect richtext
     i.setDescription(QString::fromStdString(e.description())); //TODO detect richtext
-    i.setPriority(toPriority(e.priority()));
     i.setStatus(toStatus(e.status()));
-    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
-    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizerName()), QString::fromStdString(e.organizerEmail()))));
     foreach (const Kolab::Attendee a, e.attendees()) {
         i.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee(QString::fromStdString(a.name()), 
                                                                      QString::fromStdString(a.email()), 
@@ -228,10 +336,24 @@ void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
 //     i.setCustomProperties(); //TODO
 }
 
-void getIncidence(Event &i, const KCalCore::Event &e)
+template <typename T, typename I>
+void getIncidence(T &i, const I &e)
 {
     i.setUid(e.uid().toStdString());
-//     i.setCreated(fromDate(e.created()));
+    i.setCreated(fromDate(e.created()));
+    i.setLastModified(fromDate(e.lastModified()));
+    i.setSequence(e.revision());
+    i.setClassification(fromSecrecy(e.secrecy()));
+    i.setCategories(fromStringList(e.categories()));
+    
+    i.setStart(fromDate(e.dtStart()));
+    i.setSummary(e.summary().toStdString());
+    i.setDescription(e.description().toStdString());
+    i.setStatus(fromStatus(e.status()));
+    //TODO attendees
+    //TODO attachments
+    //TODO alarms
+    //TODO custom properties
 }
 
 int toWeekDay(Kolab::Weekday wday)
@@ -258,6 +380,30 @@ int toWeekDay(Kolab::Weekday wday)
     return 1;
 }
 
+Kolab::Weekday fromWeekDay(int wday)
+{
+    switch (wday) {
+        case 1:
+            return Kolab::Monday;
+        case 2:
+            return Kolab::Tuesday;
+        case 3:
+            return Kolab::Wednesday;
+        case 4:
+            return Kolab::Thursday;
+        case 5:
+            return Kolab::Friday;
+        case 6:
+            return Kolab::Saturday;
+        case 7:
+            return Kolab::Sunday;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::Monday;
+}
+
 KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
 {
     switch(freq) {
@@ -285,37 +431,59 @@ KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Fre
     return KCalCore::RecurrenceRule::rNone;
 }
 
+Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
+{
+    switch(freq) {
+        case KCalCore::RecurrenceRule::rNone:
+            qWarning() << "no recurrence?";
+            break;
+        case KCalCore::RecurrenceRule::rYearly:
+            return Kolab::RecurrenceRule::Yearly;
+        case KCalCore::RecurrenceRule::rMonthly:
+            return Kolab::RecurrenceRule::Monthly;
+        case KCalCore::RecurrenceRule::rWeekly:
+            return Kolab::RecurrenceRule::Weekly;
+        case KCalCore::RecurrenceRule::rDaily:
+            return Kolab::RecurrenceRule::Daily;
+        case KCalCore::RecurrenceRule::rHourly:
+            return Kolab::RecurrenceRule::Hourly;
+        case KCalCore::RecurrenceRule::rMinutely:
+            return Kolab::RecurrenceRule::Minutely;
+        case KCalCore::RecurrenceRule::rSecondly:
+            return Kolab::RecurrenceRule::Secondly;
+        default:
+            qWarning() << "unhandled";
+            Q_ASSERT(0);
+    }
+    return Kolab::RecurrenceRule::None;
+}
+
 KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
 {
     return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday())-1); //Yes, we have a different day-int mapping here...
 }
 
-KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
+Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
 {
-    KCalCore::Event::Ptr e(new KCalCore::Event);
-    setIncidence(*e, event);
-    if (event.end().isValid()) {
-        e->setDtEnd(toDate(event.end()));
-    }
-    if (event.transparency()) {
-        e->setTransparency(KCalCore::Event::Transparent);
-    } else {
-        e->setTransparency(KCalCore::Event::Opaque);
-    }
+    return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()+1)); //Yes, we have a different day-int mapping here...
+}
 
+template <typename T>
+void setRecurrence(KCalCore::Incidence &e, const T &event)
+{
     const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
     if (rrule.isValid()) {
-        KCalCore::Recurrence *rec = e->recurrence();
-
+        KCalCore::Recurrence *rec = e.recurrence();
+        
         KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
         Q_ASSERT(defaultRR);
-
+        
         defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
         defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
         defaultRR->setFrequency(rrule.interval());
-
+        
         if (rrule.end().isValid()) {
-            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime
+            rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
         } else {
             rec->setDuration(rrule.count());
         }
@@ -350,15 +518,112 @@ KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
         }
     }
     foreach (const Kolab::DateTime &dt, event.recurrenceDates()) {
-        e->recurrence()->addRDateTime(toDate(dt));//TODO date/datetime
+        e.recurrence()->addRDateTime(toDate(dt));//TODO date/datetime
     }
     foreach (const Kolab::DateTime &dt, event.exceptionDates()) {
-        e->recurrence()->addExDateTime(toDate(dt));//TODO date/datetime
+        e.recurrence()->addExDateTime(toDate(dt));//TODO date/datetime
     }
-    if (event.recurrenceID().isValid()) {
-        e->setRecurrenceId(toDate(event.recurrenceID()));
+
+}
+
+template <typename T, typename I>
+void getRecurrence(T &i, const I &e)
+{
+    if (!e.recurs()) {
+        return;
+    }
+    KCalCore::Recurrence *rec = e.recurrence();
+    KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
+    if (!defaultRR) {
+        qWarning() << "no recurrence";
+        return;
+    }
+    Q_ASSERT(defaultRR);
+
+    Kolab::RecurrenceRule rrule;
+    rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
+    rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
+    rrule.setInterval(defaultRR->frequency());
+  
+    if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
+        if (defaultRR->duration() > 0) {
+            rrule.setCount(defaultRR->duration());
+        }
+    } else {
+        rrule.setEnd(fromDate(defaultRR->endDt()));
+    }
+    
+    rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
+    rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
+    rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
+    
+    std::vector<Kolab::DayPos> daypos;
+    foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
+        daypos.push_back(fromWeekDayPos(dp));
+    }
+    rrule.setByday(daypos);
+    
+    rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
+    rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
+    rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
+    rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
+    i.setRecurrenceRule(rrule);
+    
+    std::vector<Kolab::DateTime> rdates;
+    foreach (const KDateTime &dt, rec->rDateTimes()) { //TODO date/datetime
+        rdates.push_back(fromDate(dt));
+    }
+    i.setRecurrenceDates(rdates);
+    
+    std::vector<Kolab::DateTime> exdates;
+    foreach (const KDateTime &dt, rec->exDateTimes()) { //TODO date/datetime
+        exdates.push_back(fromDate(dt));
+    }
+    i.setExceptionDates(exdates);
+    
+    if (!rec->exRules().empty()) {
+        qWarning() << "exrules are not supported";
+    }
+}
+
+template <typename T>
+void setTodoEvent(KCalCore::Incidence &i, const T &e)
+{
+    i.setPriority(toPriority(e.priority()));
+    i.setLocation(QString::fromStdString(e.location())); //TODO detect richtext
+    i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(QString::fromStdString(e.organizerName()), QString::fromStdString(e.organizerEmail()))));
+    if (e.recurrenceID().isValid()) {
+        i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
+    }
+    setRecurrence(i, e);
+}
+
+template <typename T, typename I>
+void getTodoEvent(T &i, const I &e)
+{
+    i.setPriority(fromPriority(e.priority()));
+    i.setLocation(e.location().toStdString());
+    i.setOrganizer(e.organizer()->email().toStdString(),e.organizer()->name().toStdString());
+    i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
+    getRecurrence(i, e);
+}
+
+KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
+{
+    KCalCore::Event::Ptr e(new KCalCore::Event);
+    setIncidence(*e, event);
+    setTodoEvent(*e, event);
+    if (event.end().isValid()) {
+        e->setDtEnd(toDate(event.end()));
+    }
+    if (event.duration().isValid()) {
+        e->setDuration(toDuration(event.duration()));
+    }
+    if (event.transparency()) {
+        e->setTransparency(KCalCore::Event::Transparent);
+    } else {
+        e->setTransparency(KCalCore::Event::Opaque);
     }
-        
     return e;
 }
 
@@ -366,10 +631,50 @@ Event fromKCalCore(const KCalCore::Event &event)
 {
     Event e;
     getIncidence(e, event);
+    getTodoEvent(e, event);
+    //TODO end, duration transp
+    return e;
+}
+
+
+
+KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
+{
+    KCalCore::Todo::Ptr e(new KCalCore::Todo);
+    setIncidence(*e, todo);
+    setTodoEvent(*e, todo);
+    if (todo.due().isValid()) {
+        e->setDtDue(toDate(todo.due()));
+    }
+    return e;
+}
 
+Todo fromKCalCore ( const KCalCore::Todo &todo )
+{
+    Todo t;
+    getIncidence(t, todo);
+    getTodoEvent(t, todo);
+    t.setDue(fromDate(todo.dtDue(true)));
+    return t;
+}
+
+KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
+{
+    KCalCore::Journal::Ptr e(new KCalCore::Journal);
+    setIncidence(*e, journal);
+    //TODO contacts
     return e;
 }
 
+Journal fromKCalCore ( const KCalCore::Journal &journal )
+{
+    Journal j;
+    getIncidence(j, journal);
+    //TODO contacts
+    return j;
+}
+
+
 
 }
 }
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 45cbc7b..b440840 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -19,20 +19,32 @@
 #define KOLABKCALCONVERSION_H
 
 #include "kolabevent.h"
+#include "kolabtodo.h"
+#include "kolabjournal.h"
 #include <kcalcore/event.h>
+#include <kcalcore/todo.h>
+#include <kcalcore/journal.h>
 
 namespace Kolab {
+    /**
+     * Conversion of Kolab-Containers to/from KCalCore Containers.
+     *
+     * TODO: There is no error handling other than qWarning used so far.
+     */
     namespace KCalConversion {
-        
-        
+
         KCalCore::Event::Ptr toKCalCore(const Kolab::Event &);
         Kolab::Event fromKCalCore(const KCalCore::Event &);
-        
-        //TODO converters in both directions for all containers
-        
+
+        KCalCore::Todo::Ptr toKCalCore(const Kolab::Todo &);
+        Kolab::Todo fromKCalCore(const KCalCore::Todo &);
+
+        KCalCore::Journal::Ptr toKCalCore(const Kolab::Journal &);
+        Kolab::Journal fromKCalCore(const KCalCore::Journal &);
+
         KDateTime toDate(const Kolab::DateTime &dt);
         DateTime fromDate(const KDateTime &dt);
-        
+
     };
 };
 
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index d15e927..85a5f9a 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -16,8 +16,12 @@ using namespace Kolab::KCalConversion;
 Q_DECLARE_METATYPE(Kolab::Duration);
 Q_DECLARE_METATYPE(Kolab::DateTime);
 Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(Kolab::Todo);
+Q_DECLARE_METATYPE(Kolab::Journal);
 Q_DECLARE_METATYPE(std::vector<Kolab::DateTime>);
 Q_DECLARE_METATYPE(KCalCore::Event);
+Q_DECLARE_METATYPE(KCalCore::Todo);
+Q_DECLARE_METATYPE(KCalCore::Journal);
 
 namespace QTest {
     
@@ -84,24 +88,56 @@ namespace QTest {
             Q_ASSERT(at.rRules().size() == 1);
             
             ba += "Recurrence(";
-            ba += QString::number(r->recurrenceType()) + ", ";
-            ba += QString::number(r->frequency()) + ", ";
-            ba += QString::number(r->duration()) + ", ";
-            ba += QByteArray(toString(r->startDt())) + ", ";
-            ba += QByteArray(toString(r->endDt())) + ", ";
-            ba += QByteArray(toString(r->bySeconds())) + ", ";
-            ba += QByteArray(toString(r->byMinutes())) + ", ";
-            ba += QByteArray(toString(r->byHours())) + ", ";
-            ba += QByteArray(toString(r->byDays())) + ", ";
-            ba += QByteArray(toString(r->byMonthDays())) + ", ";
-            ba += QByteArray(toString(r->byYearDays())) + ", ";
-            ba += QByteArray(toString(r->byMonths())) + ", ";
+            ba += QString::number(r->recurrenceType()) + "\n";
+            ba += QString::number(r->frequency()) + "\n";
+            ba += QString::number(r->duration()) + "\n";
+            ba += QByteArray(toString(r->startDt())) + "\n";
+            ba += QByteArray(toString(r->endDt())) + "\n";
+            ba += QByteArray(toString(r->bySeconds())) + "\n";
+            ba += QByteArray(toString(r->byMinutes())) + "\n";
+            ba += QByteArray(toString(r->byHours())) + "\n";
+            ba += QByteArray(toString(r->byDays())) + "\n";
+            ba += QByteArray(toString(r->byMonthDays())) + "\n";
+            ba += QByteArray(toString(r->byYearDays())) + "\n";
+            ba += QByteArray(toString(r->byMonths())) + "\n";
             ba += ")";
         }
         return qstrdup(ba.data());
     }
+    
+    template<>
+    char *toString(const Kolab::RecurrenceRule &at)
+    {
+        QByteArray ba;
+        ba += "KolabRecurrenceRule(";
+        ba += QString::number(at.weekStart()) + "\n";
+        ba += QString::number(at.frequency()) + "\n";
+        ba += QString::number(at.interval()) + "\n";
+        ba += QString::number(at.count()) + "\n";
+        ba += QByteArray(toString(at.end())) + "\n";
+        ba += QByteArray(toString(at.bysecond())) + "\n";
+        ba += QByteArray(toString(at.byminute())) + "\n";
+        ba += QByteArray(toString(at.byhour())) + "\n";
+        ba += QByteArray(toString(at.byday())) + "\n";
+        ba += QByteArray(toString(at.bymonthday())) + "\n";
+        ba += QByteArray(toString(at.byyearday())) + "\n";
+        ba += QByteArray(toString(at.byweekno())) + "\n";
+        ba += QByteArray(toString(at.bymonth())) + "\n";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+}
+
+template <typename T>
+void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
+{
+    QCOMPARE(list.size(), other.size());
+    for (int i = 0 ; i < list.size(); i++) {
+        QCOMPARE(*list.at(i), *other.at(i));
+    }
 }
 
+
 void KCalConversionTest::testDate_data()
 {
     QTest::addColumn<Kolab::DateTime>( "input" );
@@ -168,106 +204,159 @@ void KCalConversionTest::testConversion_data()
     stringVector.push_back("cat2");
     stringVector.push_back("parent/child");
     
-    KCalCore::Event kcal;
-    kcal.setUid("uid");
-    kcal.setCreated(toDate(date));
-    kcal.setLastModified(toDate(date));
-    kcal.setRevision(3);
-    kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
-    kcal.setCategories(toStringList(stringVector));
-    kcal.setDtStart(toDate(date));
-    kcal.setDtEnd(toDate(date2));
-    kcal.setTransparency(KCalCore::Event::Transparent);
-    
-    kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
-    kcal.recurrence()->setDaily(3);
-    kcal.recurrence()->setDuration(5);
-//     kcal.recurrence()->setEndDateTime(); //TODO
-    kcal.recurrence()->addRDateTime(toDate(date2));
-    kcal.recurrence()->addExDateTime(toDate(date3));
-    
-    KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
-    QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
-    rr->setBySeconds(intList);
-    rr->setByMinutes(intList);
-    rr->setByHours(intList);
-    rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,0) << KCalCore::RecurrenceRule::WDayPos(5,3));
-    rr->setByMonthDays(intList);
-    rr->setByYearDays(intList);
-    rr->setByMonths(intList);
-    rr->setByWeekNumbers(intList);
-    
-    kcal.setSummary("summary");
-    kcal.setDescription("description");
-    kcal.setPriority(3);
-    kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
-    kcal.setLocation("location");
-    kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
-    kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant, "uid")));
-    //TODO KCalCore Delegate/Delegator
-    kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
-    KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
-    KCalCore::Person::List addressees;
-    addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
-    alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
-    kcal.addAlarm(alarm);
-    //TODO alarms
-    //TODO custom properties
-    
-    Kolab::Event kolab;
-    kolab.setUid("uid");
-    kolab.setCreated(date);
-    kolab.setLastModified(date);
-    kolab.setSequence(3);
-    kolab.setClassification(Kolab::Confidential);
-    kolab.setCategories(stringVector);
-    kolab.setStart(date);
-    kolab.setEnd(date2);
-    kolab.setTransparency(true);
-    
-    Kolab::RecurrenceRule rrule;
-    rrule.setInterval(3);
-    rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-    rrule.setCount(5);
-    rrule.setBysecond(intVector);
-    rrule.setByminute(intVector);
-    rrule.setByhour(intVector);
-    rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
-    rrule.setBymonthday(intVector);
-    rrule.setByyearday(intVector);
-    rrule.setByweekno(intVector);
-    rrule.setBymonth(intVector);
-    
-    kolab.setRecurrenceRule(rrule);
-    kolab.setRecurrenceID(date2, true);
-    kolab.setRecurrenceDates(std::vector<Kolab::DateTime>() << date2);
-    kolab.setExceptionDates(std::vector<Kolab::DateTime>() << date3);
-    
-    kolab.setSummary("summary");
-    kolab.setDescription("description");
-    kolab.setPriority(3);
-    kolab.setStatus(Kolab::Confirmed);
-    kolab.setLocation("location");
-    kolab.setOrganizer("organizer at email", "organizer");
-    
-    Kolab::Attendee a("attendee at email");
-    a.setName("attendee");
-    a.setUid("uid");
-    kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
-    
-    Kolab::Attachment attach;
-    attach.setUri("uri", "mimetype/mime");
-    kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
-    
-//     std::vector<std::string> receipents;
-//     receipents.push_back("email at email");
-//     Kolab::Alarm alarm2("summary", "description", receipents);
-//     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
-
-    QTest::newRow( "test1" ) << kcal << kolab;
-    
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setSecrecy(KCalCore::Incidence::SecrecyConfidential);
+        kcal.setCategories(toStringList(stringVector));
+        kcal.setDtStart(toDate(date));
+        kcal.setDtEnd(toDate(date2));
+        kcal.setTransparency(KCalCore::Event::Transparent);
+        
+        kcal.setRecurrenceId(toDate(date2)); //TODO THISANDFUTURE
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setDuration(5);
+        kcal.recurrence()->addRDateTime(toDate(date2));
+        kcal.recurrence()->addExDateTime(toDate(date3));
+        
+        KCalCore::RecurrenceRule *rr = kcal.recurrence()->defaultRRule(true);
+        QList<int> intList = QVector<int>::fromStdVector(intVector).toList();
+        rr->setBySeconds(intList);
+        rr->setByMinutes(intList);
+        rr->setByHours(intList);
+        rr->setByDays(QList<KCalCore::RecurrenceRule::WDayPos>() << KCalCore::RecurrenceRule::WDayPos(3,0) << KCalCore::RecurrenceRule::WDayPos(5,3));
+        rr->setByMonthDays(intList);
+        rr->setByYearDays(intList);
+        rr->setByMonths(intList);
+        rr->setByWeekNumbers(intList);
+        
+        kcal.setSummary("summary");
+        kcal.setDescription("description");
+        kcal.setPriority(3);
+        kcal.setStatus(KCalCore::Incidence::StatusConfirmed);
+        kcal.setLocation("location");
+        kcal.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person("organizer", "organizer at email")));
+        kcal.addAttendee(KCalCore::Attendee::Ptr(new KCalCore::Attendee("attendee", "attendee at email", false, KCalCore::Attendee::NeedsAction, KCalCore::Attendee::ReqParticipant, "uid")));
+        //TODO KCalCore Delegate/Delegator
+        kcal.addAttachment(KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString("uri"), "mimetype/mime")));
+        KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&kcal));    
+        KCalCore::Person::List addressees;
+        addressees.append(KCalCore::Person::Ptr(new KCalCore::Person("name", "email at email")));
+        alarm->setEmailAlarm("subject", "text", addressees, QStringList()); //No support for attachments
+        kcal.addAlarm(alarm);
+        //TODO alarms
+        //TODO custom properties
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setClassification(Kolab::Confidential);
+        kolab.setCategories(stringVector);
+        kolab.setStart(date);
+        kolab.setEnd(date2);
+        kolab.setTransparency(true);
+        
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setCount(5);
+        rrule.setBysecond(intVector);
+        rrule.setByminute(intVector);
+        rrule.setByhour(intVector);
+        rrule.setByday(std::vector<Kolab::DayPos>() << Kolab::DayPos(3, Kolab::Monday) << Kolab::DayPos(5, Kolab::Thursday));
+        rrule.setBymonthday(intVector);
+        rrule.setByyearday(intVector);
+        rrule.setByweekno(intVector);
+        rrule.setBymonth(intVector);
+        
+        kolab.setRecurrenceRule(rrule);
+        kolab.setRecurrenceID(date2, true);
+        kolab.setRecurrenceDates(std::vector<Kolab::DateTime>() << date2);
+        kolab.setExceptionDates(std::vector<Kolab::DateTime>() << date3);
+        
+        kolab.setSummary("summary");
+        kolab.setDescription("description");
+        kolab.setPriority(3);
+        kolab.setStatus(Kolab::Confirmed);
+        kolab.setLocation("location");
+        kolab.setOrganizer("organizer at email", "organizer");
+        
+        Kolab::Attendee a("attendee at email");
+        a.setName("attendee");
+        a.setUid("uid");
+        kolab.setAttendees(std::vector<Kolab::Attendee>() << a);
+        
+        Kolab::Attachment attach;
+        attach.setUri("uri", "mimetype/mime");
+        kolab.setAttachments(std::vector<Kolab::Attachment>() << attach);
+        
+    //     std::vector<std::string> receipents;
+    //     receipents.push_back("email at email");
+    //     Kolab::Alarm alarm2("summary", "description", receipents);
+    //     kolab.setAlarms(std::vector<Kolab::Alarm>() << alarm2);
+
+        QTest::newRow( "with endDate and recurrence duration" ) << kcal << kolab;
+    }
+    {
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setRevision(3);
+        kcal.setDtStart(toDate(date));
+        kcal.setDuration(KCalCore::Duration(toDate(date), toDate(date2)));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(date3));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setSequence(3);
+        kolab.setStart(date);
+        kolab.setDuration(Kolab::Duration(0, 0, 1, 0));
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(date3);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("with duration and recurrence endDate") << kcal << kolab;
+    }
+    {
+        Kolab::DateTime start(2011,1,1);
+        Kolab::DateTime end(2011,1,3);
+        
+        KCalCore::Event kcal;
+        kcal.setUid("uid");
+        kcal.setCreated(toDate(date));
+        kcal.setLastModified(toDate(date));
+        kcal.setDtStart(toDate(start));
+        kcal.setDtEnd(toDate(end));
+        kcal.recurrence()->setDaily(3);
+        kcal.recurrence()->setEndDateTime(toDate(end));
+        
+        Kolab::Event kolab;
+        kolab.setUid("uid");
+        kolab.setCreated(date);
+        kolab.setLastModified(date);
+        kolab.setStart(start);
+        kolab.setEnd(end);
+        Kolab::RecurrenceRule rrule;
+        rrule.setInterval(3);
+        rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+        rrule.setEnd(end);
+        kolab.setRecurrenceRule(rrule);
+        
+        QTest::newRow("date only dates") << kcal << kolab;
+    }
 }
-    
+
 void KCalConversionTest::testConversion()
 {
     QFETCH(KCalCore::Event, kcal);
@@ -295,14 +384,8 @@ void KCalConversionTest::testConversion()
     QCOMPARE(e->location(), kcal.location());
     QCOMPARE(e->organizer()->name(), kcal.organizer()->name());
     QCOMPARE(e->organizer()->email(), kcal.organizer()->email());
-    QCOMPARE(e->attendees().size(), 1);
-    for (int i = 0 ; i < e->attendees().size(); i++) {
-        QCOMPARE(*e->attendees().at(i), *kcal.attendees().at(i));
-    }
-    QCOMPARE(e->attachments().size(), 1);
-    for (int i = 0 ; i < e->attachments().size(); i++) {
-        QCOMPARE(*e->attachments().at(i), *kcal.attachments().at(i));
-    }
+    comparePointerVectors(e->attendees(), kcal.attendees());
+    comparePointerVectors(e->attachments(), kcal.attachments());
     
 //     QCOMPARE(e->alarms(), kcal.alarms()); //TODO
 //TODO custom properties
@@ -313,6 +396,106 @@ void KCalConversionTest::testConversion()
     
     const Kolab::Event &b = fromKCalCore(kcal);
     QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.created(), kolab.created());
+    QCOMPARE(b.lastModified(), kolab.lastModified());
+    QCOMPARE(b.sequence(), kolab.sequence());
+    QCOMPARE(b.classification(), kolab.classification());
+    QCOMPARE(b.categories(), kolab.categories());
+    QCOMPARE(b.start(), kolab.start());
+    //end
+    //duration
+    
+    QCOMPARE(b.recurrenceRule(), kolab.recurrenceRule());
+    QCOMPARE(b.recurrenceID(), kolab.recurrenceID());
+    QCOMPARE(b.recurrenceDates(), kolab.recurrenceDates());
+    QCOMPARE(b.exceptionDates(), kolab.exceptionDates());
+    
+    QCOMPARE(b.summary(), kolab.summary());
+    QCOMPARE(b.description(), kolab.description());
+    QCOMPARE(b.status(), kolab.status());
+}
+
+
+void KCalConversionTest::testTodoConversion_data()
+{
+    QTest::addColumn<KCalCore::Todo>( "kcal" );
+    QTest::addColumn<Kolab::Todo>( "kolab" );
+    
+    Kolab::DateTime date(2011,2,2,12,11,10);
+    Kolab::DateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Todo kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setDtDue(toDate(date2));
+        
+        Kolab::Todo kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setDue(date2);
+
+        QTest::newRow( "todo" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testTodoConversion()
+{
+    QFETCH(KCalCore::Todo, kcal);
+    QFETCH(Kolab::Todo, kolab);
+    
+    const KCalCore::Todo::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->dtDue(), kcal.dtDue());
+   
+    const Kolab::Todo &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.due(), kolab.due());
+}
+
+void KCalConversionTest::testJournalConversion_data()
+{
+    QTest::addColumn<KCalCore::Journal>( "kcal" );
+    QTest::addColumn<Kolab::Journal>( "kolab" );
+    
+    Kolab::DateTime date(2011,2,2,12,11,10);
+    Kolab::DateTime date2(2011,2,2,12,12,10);
+    
+    {
+        KCalCore::Journal kcal;
+        kcal.setUid("uid");
+        kcal.setDtStart(toDate(date));
+        kcal.setSummary("summary");
+        
+        Kolab::Journal kolab;
+        kolab.setUid("uid");
+        kolab.setStart(date);
+        kolab.setSummary("summary");
+        
+        QTest::newRow( "journal" ) << kcal << kolab;
+    }
+}
+
+
+void KCalConversionTest::testJournalConversion()
+{
+    QFETCH(KCalCore::Journal, kcal);
+    QFETCH(Kolab::Journal, kolab);
+    
+    const KCalCore::Journal::Ptr e = toKCalCore(kolab);
+    
+    QCOMPARE(e->uid(), kcal.uid());
+    QCOMPARE(e->dtStart(), kcal.dtStart());
+    QCOMPARE(e->summary(), kcal.summary());
+    
+    const Kolab::Journal &b = fromKCalCore(kcal);
+    QCOMPARE(b.uid(), kolab.uid());
+    QCOMPARE(b.start(), kolab.start());
+    QCOMPARE(b.summary(), kolab.summary());
 }
 
 
@@ -408,7 +591,7 @@ void KCalConversionTest::testTimesInInterval_data()
             rrule.setInterval(1);
             rrule.setCount(5);
             event.setRecurrenceRule(rrule);
-            
+
             std::vector<Kolab::DateTime> result;
             result.push_back(Kolab::DateTime(2011,1,1,1,1,1)); 
             result.push_back(Kolab::DateTime(2011,1,2,1,1,1));
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index 5ef6be6..3eb662f 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -8,16 +8,19 @@ class KCalConversionTest : public QObject
 {
   Q_OBJECT
   private slots:
-      
-      
-//     void BenchmarkRoundtripKCAL();
-// 
-    void testConversion_data();
-    void testConversion();
 
     void testDate_data();
     void testDate();
     
+    void testConversion_data();
+    void testConversion();
+
+    void testTodoConversion_data();
+    void testTodoConversion();
+    
+    void testJournalConversion_data();
+    void testJournalConversion();
+    
     void testDateTZ_data();
     void testDateTZ();
 


commit e04dcfc76728ed9f85a2fa333c5dea1358a1e475
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Thu Mar 1 14:22:31 2012 +0100

    recurrence rule comparator

diff --git a/c++/lib/kolabcontainers.cpp b/c++/lib/kolabcontainers.cpp
index 785507c..031770d 100644
--- a/c++/lib/kolabcontainers.cpp
+++ b/c++/lib/kolabcontainers.cpp
@@ -226,6 +226,26 @@ void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other)
     *d = *other.d;
 }
 
+bool RecurrenceRule::operator==(const Kolab::RecurrenceRule &other) const
+{
+    if ( d->freq == other.frequency() &&
+        d->weekstart == other.weekStart() &&
+        d->end == other.end() &&
+        d->count == other.count() &&
+        d->interval == other.interval() &&
+        d->bysecond == other.bysecond() &&
+        d->byminute == other.byminute() &&
+        d->byhour == other.byhour() &&
+        d->byday == other.byday() &&
+        d->bymonthday == other.bymonthday() &&
+        d->byyearday == other.byyearday() &&
+        d->byweekno == other.byweekno() &&
+        d->bymonth == other.bymonth()) {
+            return true;
+        }
+        return false;
+}
+
 RecurrenceRule::~RecurrenceRule()
 {
     
diff --git a/c++/lib/kolabcontainers.h b/c++/lib/kolabcontainers.h
index b8dc630..7065710 100644
--- a/c++/lib/kolabcontainers.h
+++ b/c++/lib/kolabcontainers.h
@@ -222,6 +222,7 @@ public:
     ~RecurrenceRule();
 
     void operator=(const RecurrenceRule &);
+    bool operator==(const RecurrenceRule &other) const;
     
     enum Frequency {
         None,





More information about the commits mailing list