3 commits - c++/compiled c++/lib c++/tests
Christian Mollekopf
mollekopf at kolabsys.com
Wed Feb 29 23:18:14 CET 2012
c++/compiled/XMLParserWrapper.cpp | 14
c++/compiled/XMLParserWrapper.h | 9
c++/lib/CMakeLists.txt | 13
c++/lib/calendaring.cpp | 54 +++
c++/lib/calendaring.h | 35 ++
c++/lib/kolabkcalconversion.cpp | 188 +++++++++++
c++/lib/kolabkcalconversion.h | 3
c++/tests/bindingstest.cpp | 14
c++/tests/kcalconversiontest.cpp | 609 +++++++++++++++++++-------------------
c++/tests/kcalconversiontest.h | 16
c++/tests/serializers.h | 2
c++/tests/testfiles/icalEvent.xml | 8
12 files changed, 633 insertions(+), 332 deletions(-)
New commits:
commit 003399e48e233fc1014db9c833b9047f30e2b0b6
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Feb 29 23:17:46 2012 +0100
First Proof-Of-Concept for advanced calendaring features, read timezone info from system using ktimezoned, use only existing timezones
The ktimezoned runtime dependency could be a problem on some platforms....
Bindings for the module are still missing.
diff --git a/c++/lib/CMakeLists.txt b/c++/lib/CMakeLists.txt
index 12c2133..189639f 100644
--- a/c++/lib/CMakeLists.txt
+++ b/c++/lib/CMakeLists.txt
@@ -45,12 +45,17 @@ if(KDECORE_FOUND AND KCALCORE_FOUND)
message("Building KCalCore dependend libraries.")
#Library with converters to/from kcalcore and code to provide advanced functionality (such as expanding recurrences) from kcalcore.
- add_library(kolabkcal SHARED kolabkcalconversion.cpp)
+ add_library(kolabkcal SHARED kolabkcalconversion.cpp calendaring.cpp)
target_link_libraries(kolabkcal kolabxml ${KCALCORE} ${KDECORE})
- #Library with serialization/deserialization code for KCalCore containers (deprecated)
-# add_library(kolabxmlkcal SHARED kcalkolabformat.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES})
-# target_link_libraries(kolabxmlkcal xerces-c ${KCALCORE} ${KDECORE})
+ set_target_properties(kolabkcal PROPERTIES VERSION 0.1.0 SOVERSION 0)
+ install(TARGETS kolabkcal LIBRARY DESTINATION lib)
+
+ install( FILES
+ kolabkcalconversion.h
+ calendaring.h
+ DESTINATION include/kolab COMPONENT Devel)
+
else()
message(WARNING "Could not build KCalCore/KDElibs dependend libraries, because kdepimlibs/kdelibs is missing.")
endif()
diff --git a/c++/lib/calendaring.cpp b/c++/lib/calendaring.cpp
new file mode 100644
index 0000000..60e4355
--- /dev/null
+++ b/c++/lib/calendaring.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "calendaring.h"
+
+#include <kcalcore/event.h>
+#include <KDE/KCalCore/Todo>
+#include <Qt/qdebug.h>
+
+#include "kolabkcalconversion.h"
+
+namespace Kolab {
+
+ namespace Calendaring {
+
+ bool conflicts(const Kolab::Event &e1, const Kolab::Event &e2)
+ {
+ KCalCore::Event::Ptr k1 = KCalConversion::toKCalCore(e1);
+ KCalCore::Event::Ptr k2 = KCalConversion::toKCalCore(e2);
+ if (k2->dtEnd().compare(k1->dtStart()) == KDateTime::Before) {
+ return false;
+ } else if (k1->dtEnd().compare(k2->dtStart()) == KDateTime::Before) {
+ return false;
+ }
+ return true;
+ }
+
+ std::vector<Kolab::DateTime> timeInInterval(const Kolab::Event &e, const Kolab::DateTime &start, const Kolab::DateTime &end)
+ {
+ KCalCore::Event::Ptr k = KCalConversion::toKCalCore(e);
+ KCalCore::DateTimeList list = k->recurrence()->timesInInterval(KCalConversion::toDate(start), KCalConversion::toDate(end));
+ std::vector<Kolab::DateTime> dtList;
+ foreach(const KDateTime &dt, list) {
+ dtList.push_back(KCalConversion::fromDate(dt));
+ }
+ return dtList;
+ }
+
+ } //Namespace
+} //Namespace
\ No newline at end of file
diff --git a/c++/lib/calendaring.h b/c++/lib/calendaring.h
new file mode 100644
index 0000000..7ee946c
--- /dev/null
+++ b/c++/lib/calendaring.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 Christian Mollekopf <mollekopf at kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KOLABCALENDARING_H
+#define KOLABCALENDARING_H
+
+#include "kolabevent.h"
+#include <kcalcore/event.h>
+
+namespace Kolab {
+ namespace Calendaring {
+ /**
+ * Returns true if the events conflict (overlap)
+ */
+ bool conflicts(const Kolab::Event &, const Kolab::Event &);
+
+ std::vector<Kolab::DateTime> timeInInterval(const Kolab::Event &, const Kolab::DateTime &start, const Kolab::DateTime &end);
+ };
+};
+
+#endif
\ No newline at end of file
diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index 1c24bbe..cc46ee2 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -22,6 +22,7 @@
#include <QtCore/QVector>
#include <QtCore/QDebug>
#include <vector>
+#include <KDE/KSystemTimeZones>
namespace Kolab {
namespace KCalConversion {
@@ -38,7 +39,14 @@ KDateTime toDate(const Kolab::DateTime &dt)
if (dt.isUTC()) { //UTC
date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
} else if (!dt.timezone().empty()) { //Timezone
- date.setTimeSpec(KDateTime::Spec(KTimeZone(QString::fromStdString(dt.timezone()))));
+ const KTimeZone &tz = KSystemTimeZones::zone(QString::fromStdString(dt.timezone())); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+ if (!tz.isValid()) {
+ qWarning() << "timezone not found" << QString::fromStdString(dt.timezone());
+ if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
+ qWarning() << "ktimezoned is not available and required for timezone interpretation";
+ }
+ }
+ date.setTimeSpec(KDateTime::Spec(tz));
} //Floating
}
return date;
diff --git a/c++/lib/kolabkcalconversion.h b/c++/lib/kolabkcalconversion.h
index 60c5e3f..45cbc7b 100644
--- a/c++/lib/kolabkcalconversion.h
+++ b/c++/lib/kolabkcalconversion.h
@@ -30,6 +30,9 @@ namespace Kolab {
//TODO converters in both directions for all containers
+ KDateTime toDate(const Kolab::DateTime &dt);
+ DateTime fromDate(const KDateTime &dt);
+
};
};
diff --git a/c++/tests/bindingstest.cpp b/c++/tests/bindingstest.cpp
index 69422f3..0a34988 100644
--- a/c++/tests/bindingstest.cpp
+++ b/c++/tests/bindingstest.cpp
@@ -32,7 +32,7 @@ void setIncidence(T &ev)
ev.setSequence(1);
ev.setClassification(Kolab::Confidential);
ev.addCategory("Category");
- ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ ev.setStart(Kolab::DateTime("Europe/Zurich", 2006,1,6,12,0,0));
Kolab::RecurrenceRule rule;
rule.setFrequency(Kolab::RecurrenceRule::Daily);
@@ -54,9 +54,9 @@ void setIncidence(T &ev)
rule.setBymonth(list);
ev.setRecurrenceRule(rule);
- ev.addRecurrenceDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
- ev.addExceptionDate(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
- ev.setRecurrenceID(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0), true);
+ ev.addRecurrenceDate(Kolab::DateTime("Europe/Zurich", 2006,1,6,12,0,0));
+ ev.addExceptionDate(Kolab::DateTime("Europe/Zurich", 2006,1,6,12,0,0));
+ ev.setRecurrenceID(Kolab::DateTime("Europe/Zurich", 2006,1,6,12,0,0), true);
ev.setSummary("summary");
ev.setDescription("description");
ev.setPriority(3);
@@ -181,7 +181,7 @@ void BindingsTest::eventCompletness()
{
Kolab::Event ev;
setIncidence(ev);
- ev.setEnd(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ ev.setEnd(Kolab::DateTime("Europe/Zurich", 2006,1,8,12,0,0));
ev.setTransparency(true);
std::string result = Kolab::writeEvent(ev);
@@ -213,7 +213,7 @@ void BindingsTest::todoCompletness()
{
Kolab::Todo ev;
setIncidence(ev);
- ev.setDue(Kolab::DateTime("US/Eastern", 2006,1,8,12,0,0));
+ ev.setDue(Kolab::DateTime("Europe/Zurich", 2006,1,8,12,0,0));
ev.addRelatedTo("rel1");
ev.addRelatedTo("rel2");
ev.setPercentComplete(50);
@@ -239,7 +239,7 @@ void BindingsTest::journalCompletness()
ev.setSequence(1);
ev.setClassification(Kolab::Confidential);
ev.addCategory("Category");
- ev.setStart(Kolab::DateTime("US/Eastern", 2006,1,6,12,0,0));
+ ev.setStart(Kolab::DateTime("Europe/Zurich", 2006,1,6,12,0,0));
Kolab::Attendee attendee("email");
attendee.setName("name");
attendee.setPartStat(Kolab::PartDelegated);
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index b8b9fdd..d15e927 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -2,10 +2,12 @@
#include <QtCore/QObject>
#include <QtTest/QtTest>
+#include <KDE/KSystemTimeZones>
#include <kcalcore/recurrence.h>
#include <lib/kolabkcalconversion.h>
#include <lib/kolabkcalconversion.cpp>
+#include <lib/calendaring.h>
#include "serializers.h"
@@ -14,6 +16,7 @@ using namespace Kolab::KCalConversion;
Q_DECLARE_METATYPE(Kolab::Duration);
Q_DECLARE_METATYPE(Kolab::DateTime);
Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(std::vector<Kolab::DateTime>);
Q_DECLARE_METATYPE(KCalCore::Event);
namespace QTest {
@@ -104,7 +107,7 @@ void KCalConversionTest::testDate_data()
QTest::addColumn<Kolab::DateTime>( "input" );
QTest::addColumn<KDateTime>( "result" );
- QTest::newRow( "datetime with tz" ) << Kolab::DateTime("US/Eastern",2006,1,8,12,0,0) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
+ QTest::newRow( "datetime with tz" ) << Kolab::DateTime("Europe/Zurich",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Zurich"));
QTest::newRow( "floating datetime" ) << Kolab::DateTime(2006,1,8,12,0,0, false) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::Spec(KDateTime::ClockTime));
QTest::newRow( "utc datetime" ) << Kolab::DateTime(2006,1,8,12,0,0, true) << KDateTime(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KDateTime::UTC));
QTest::newRow( "date only" ) << Kolab::DateTime(2006,1,8) << KDateTime(QDate(2006, 1, 8));
@@ -124,6 +127,30 @@ void KCalConversionTest::testDate()
}
+void KCalConversionTest::testDateTZ_data()
+{
+ QTest::addColumn<Kolab::DateTime>( "input" );
+ QTest::addColumn<KDateTime>( "result" );
+ QTest::addColumn<int>( "offset" );
+
+ QTest::newRow( "berlin" ) << Kolab::DateTime("Europe/Berlin",2006,1,8,12,0,0) << KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KSystemTimeZones::zone("Europe/Berlin")) << 3600;
+}
+
+void KCalConversionTest::testDateTZ()
+{
+ QFETCH(Kolab::DateTime, input);
+ QFETCH(KDateTime, result);
+ QFETCH(int, offset);
+
+ const KDateTime &r = Kolab::KCalConversion::toDate(input);
+ QCOMPARE(result.timeZone().name(), QString::fromStdString(input.timezone()));
+ QCOMPARE(r.timeZone().currentOffset(), offset);
+
+ const Kolab::DateTime &r2 = Kolab::KCalConversion::fromDate(result);
+ QCOMPARE(QString::fromStdString(r2.timezone()), result.timeZone().name());
+}
+
+
void KCalConversionTest::testConversion_data()
{
QTest::addColumn<KCalCore::Event>( "kcal" );
@@ -279,144 +306,147 @@ void KCalConversionTest::testConversion()
// QCOMPARE(e->alarms(), kcal.alarms()); //TODO
//TODO custom properties
+
+ QBENCHMARK {
+ toKCalCore(kolab);
+ }
const Kolab::Event &b = fromKCalCore(kcal);
QCOMPARE(b.uid(), kolab.uid());
}
-/*
-void KCalConversionTest::BenchmarkRoundtripKCAL()
-{
- std::ifstream ifs;
-// ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
- ifs.open ("../../tests/testfiles/icalEvent.xml");
- std::string result;
-
- std::istream_iterator<std::string> DataBegin( ifs );
- std::istream_iterator<std::string> DataEnd;
- while( DataBegin != DataEnd ) {
- result += *DataBegin;
- result += "\n";
- DataBegin++;
+void KCalConversionTest::testEventConflict_data()
+{
+ QTest::addColumn<Kolab::Event>( "e1" );
+ QTest::addColumn<Kolab::Event>( "e2" );
+ QTest::addColumn<bool>( "result" );
+ {
+ Kolab::Event e1;
+ e1.setStart(Kolab::DateTime(2011,10,10,12,1,1));
+ e1.setEnd(Kolab::DateTime(2011,10,11,12,1,1));
+
+ Kolab::Event e2;
+ e2.setStart(Kolab::DateTime(2011,11,10,12,1,1));
+ e2.setEnd(Kolab::DateTime(2011,11,11,12,1,1));
+
+ QTest::newRow( "after" ) << e1 << e2 << false;
}
-
-// std::string a;
-// while (!ifs.eof()) {
-// ifs >> a;
-// result.append(a);
-// }
- std::cout << result << std::endl;
- QBENCHMARK {
- Kolab::KCal::readEvent(result, false);
+ {
+ Kolab::Event e1;
+ e1.setStart(Kolab::DateTime(2011,10,10,12,1,1));
+ e1.setEnd(Kolab::DateTime(2011,10,11,12,1,1));
+
+ Kolab::Event e2;
+ e2.setStart(Kolab::DateTime(2011,9,10,12,1,1));
+ e2.setEnd(Kolab::DateTime(2011,9,11,12,1,1));
+
+ QTest::newRow( "before" ) << e1 << e2 << false;
}
-}
-
-void KCalConversionTest::readEvent()
-{
- KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
- QVERIFY(event);
-
- //Check basics
- QCOMPARE(event->created(), KDateTime(QDate(2006, 2, 6), QTime(00, 11, 21), KDateTime::Spec(KDateTime::UTC)));
- QCOMPARE(event->created().timeSpec().type(), KDateTime::UTC);
- QCOMPARE(event->dtStart(), KDateTime(QDate(2006, 1, 2), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- QCOMPARE(event->dtStart().timeZone().name(), KTimeZone(QString::fromLatin1("US/Eastern")).name());
-
- //Check recurrence
- //TODO do some "heavy" testing for recurrences, including possible edge cases.
-
- //Check recurrence rule
- foreach (const KCalCore::RecurrenceRule *rule, event->recurrence()->rRules()) {
- QCOMPARE(rule->startDt(), event->recurrence()->startDateTime());
- }
- QCOMPARE(event->recurrence()->rRules().size(), 1);
- KCalCore::RecurrenceRule *rule = event->recurrence()->rRules().first();
- QCOMPARE(rule->recurrenceType(), KCalCore::RecurrenceRule::rDaily);
- QCOMPARE(rule->duration(), 5);
- KDateTime start(event->dtStart());
- KDateTime end(QDate(2006, 12, 14), QTime(12, 0, 0));
- QCOMPARE(rule->timesInInterval(start, end).size(), 5); //count/duration limit
- QCOMPARE(rule->timesInInterval(start, KDateTime(QDate(2006, 1, 4))).size(), 3); //end date limit
- const KCalCore::DateTimeList &ruleList = rule->timesInInterval(start, end);
- foreach (const KDateTime &d, ruleList) {
- QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-// kDebug() << d << d.timeZone().name();
+ {
+ Kolab::Event e1;
+ e1.setStart(Kolab::DateTime(2011,10,10,12,1,1));
+ e1.setEnd(Kolab::DateTime(2011,10,11,12,1,1));
+
+ Kolab::Event e2;
+ e2.setStart(Kolab::DateTime(2011,10,10,12,1,1));
+ e2.setEnd(Kolab::DateTime(2011,10,11,12,1,1));
+
+ QTest::newRow( "conflict" ) << e1 << e2 << true;
}
- QCOMPARE(ruleList.first(), event->dtStart());
- QCOMPARE(ruleList.last(), KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- //Check complete recurrence
- const KCalCore::DateTimeList &list = event->recurrence()->timesInInterval(start, end);
- foreach (const KDateTime &d, list) {
- QCOMPARE(d.timeZone().name(), event->dtStart().timeZone().name());
-// kDebug() << d << d.timeZone().name();
+
+ {
+ Kolab::Event e1;
+ e1.setStart(Kolab::DateTime("Europe/Zurich", 2011,10,10,6,1,1));
+ e1.setEnd(Kolab::DateTime("Europe/Zurich", 2011,10,10,6,1,2));
+
+ Kolab::Event e2;
+ e2.setStart(Kolab::DateTime("Asia/Dubai",2011,10,10,6,1,1));
+ e2.setEnd(Kolab::DateTime("Asia/Dubai",2011,10,10,6,1,2));
+
+ QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
}
- QCOMPARE(event->summary(), QString::fromLatin1("Event #2"));
- kDebug() << event->summary();
-// QCOMPARE(event->summary(), QString::fromUtf8("Test.
Test.Test.")); //FIXME fix control character 
 (linefeed)
- kDebug() << event->description();
+ {
+ Kolab::Event e1;
+ e1.setStart(Kolab::DateTime("Europe/Berlin", 2011,10,10,6,1,1));
+ e1.setEnd(Kolab::DateTime("Europe/Berlin", 2011,10,10,6,1,2));
+
+ Kolab::Event e2;
+ e2.setStart(Kolab::DateTime("Europe/Zurich",2011,10,10,6,1,1));
+ e2.setEnd(Kolab::DateTime("Europe/Zurich",2011,10,10,6,1,2));
+
+ QTest::newRow( "tz conflict" ) << e1 << e2 << true;
+ }
}
-void KCalConversionTest::writeEvent()
+void KCalConversionTest::testEventConflict()
{
-
- KCalCore::Event::Ptr event(new KCalCore::Event);
- event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- KCalCore::Recurrence *recurrence = event->recurrence();
- KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
- rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- rule->setFrequency(3);
- rule->setDuration(5);
- recurrence->addRRule(rule);
-
- kDebug() << "-------------------";
- kDebug() << QString::fromStdString(Kolab::KCal::writeEvent(event));
- kDebug() << "-------------------";
+ QFETCH(Kolab::Event, e1);
+ QFETCH(Kolab::Event, e2);
+ QFETCH(bool, result);
+ QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
}
-void KCalConversionTest::roundtripReverseEvent()
+
+
+void KCalConversionTest::testTimesInInterval_data()
{
- KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
- kDebug() << "-------------------";
- kDebug() << QString::fromStdString(Kolab::KCal::writeEvent(event));
- kDebug() << "-------------------";
+ QTest::addColumn<Kolab::Event>( "event" );
+ QTest::addColumn<Kolab::DateTime>( "start" );
+ QTest::addColumn<Kolab::DateTime>( "end" );
+ QTest::addColumn< std::vector<Kolab::DateTime> >( "result" );
+ {
+ {
+ Kolab::Event event;
+ event.setStart(Kolab::DateTime(2011,1,1,1,1,1));
+ event.setEnd(Kolab::DateTime(2011,1,1,2,1,1));
+ Kolab::RecurrenceRule rrule;
+ rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+ 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));
+ result.push_back(Kolab::DateTime(2011,1,3,1,1,1));
+ result.push_back(Kolab::DateTime(2011,1,4,1,1,1));
+ result.push_back(Kolab::DateTime(2011,1,5,1,1,1));
+ QTest::newRow( "simple" ) << event << Kolab::DateTime(2011,1,1,1,1,1) << Kolab::DateTime(2011,1,5,1,1,1) << result;
+ }
+ }
}
-void KCalConversionTest::roundtripEvent()
+void KCalConversionTest::testTimesInInterval()
{
- KCalCore::Event::Ptr event(new KCalCore::Event);
- event->setDtStart(KDateTime(QDate(2006, 1, 6), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
- event->setDtEnd(KDateTime(QDate(2006, 1, 8), QTime(12, 0, 0), KTimeZone(QString::fromLatin1("US/Eastern"))));
-
- KCalCore::Recurrence *recurrence = event->recurrence();
- KCalCore::RecurrenceRule *rule = new KCalCore::RecurrenceRule();
- rule->setRecurrenceType(KCalCore::RecurrenceRule::rDaily);
- rule->setFrequency(3);
- rule->setDuration(5);
- recurrence->addRRule(rule);
-
- QString result = QString::fromStdString(Kolab::KCal::writeEvent(event));
- kDebug() << result;
- KCalCore::Event::Ptr resEvent = Kolab::KCal::readEvent(result.toStdString(), false);
- QVERIFY(resEvent);
- QCOMPARE(event->dtStart(), resEvent->dtStart());
+ QFETCH(Kolab::Event, event);
+ QFETCH(Kolab::DateTime, start);
+ QFETCH(Kolab::DateTime, end);
+ QFETCH(std::vector<Kolab::DateTime>, result);
+ QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
}
-void KCalConversionTest::BenchmarkRoundtrip()
+void KCalConversionTest::testTimesInIntervalBenchmark()
{
- KCalCore::Event::Ptr event = Kolab::KCal::readEvent("testfiles/icalEvent.xml");
- std::string result;
+ Kolab::Event event;
+ event.setStart(Kolab::DateTime(2011,1,1,1,1,1));
+ event.setEnd(Kolab::DateTime(2011,1,1,2,1,1));
+ Kolab::RecurrenceRule rrule;
+ rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+ rrule.setInterval(1);
+ rrule.setCount(500);
+ event.setRecurrenceRule(rrule);
+
QBENCHMARK {
- result = Kolab::KCal::writeEvent(event);
- Kolab::KCal::readEvent(result, false);
+ Kolab::Calendaring::timeInInterval(event, Kolab::DateTime(2011,1,1,1,1,1), Kolab::DateTime(2013,1,1,1,1,1));
}
-}*/
+ const std::vector<Kolab::DateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::DateTime(2011,1,1,1,1,1), Kolab::DateTime(2013,1,1,1,1,1));
+ QVERIFY(result.size() == 500);
+// qDebug() << QTest::toString(result);
+}
diff --git a/c++/tests/kcalconversiontest.h b/c++/tests/kcalconversiontest.h
index d029e11..5ef6be6 100644
--- a/c++/tests/kcalconversiontest.h
+++ b/c++/tests/kcalconversiontest.h
@@ -17,12 +17,16 @@ class KCalConversionTest : public QObject
void testDate_data();
void testDate();
-/*
- void readEvent();
- void writeEvent();
- void roundtripEvent();
- void roundtripReverseEvent();
- void BenchmarkRoundtrip();*/
+
+ void testDateTZ_data();
+ void testDateTZ();
+
+ void testEventConflict_data();
+ void testEventConflict();
+
+ void testTimesInInterval_data();
+ void testTimesInInterval();
+ void testTimesInIntervalBenchmark();
};
#endif
\ No newline at end of file
diff --git a/c++/tests/serializers.h b/c++/tests/serializers.h
index c7f67d7..f6bcae6 100644
--- a/c++/tests/serializers.h
+++ b/c++/tests/serializers.h
@@ -22,7 +22,7 @@ namespace QTest {
{
QByteArray ba = "vector<Kolab::DateTime>(";
for (int i = 0; i < v.size(); i++) {
- ba += QByteArray(toString(v.at(i)))+ ", ";
+ ba += QByteArray(toString(v.at(i)))+ "\n";
}
ba += ")";
return qstrdup(ba.data());
diff --git a/c++/tests/testfiles/icalEvent.xml b/c++/tests/testfiles/icalEvent.xml
index f18773e..89f99a5 100644
--- a/c++/tests/testfiles/icalEvent.xml
+++ b/c++/tests/testfiles/icalEvent.xml
@@ -27,7 +27,7 @@
</dtstamp>
<dtstart>
<parameters>
- <tzid><text>/kolab.org/US/Eastern</text></tzid>
+ <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
</parameters>
<date-time>2006-01-02T12:00:00</date-time>
</dtstart>
@@ -42,7 +42,7 @@
</rrule>
<rdate>
<parameters>
- <tzid><text>/kolab.org/US/Eastern</text></tzid>
+ <tzid><text>/kolab.org/Europe/Zurich</text></tzid>
</parameters>
<date-time>2007-02-06T00:11:21</date-time>
<!-- <period>
@@ -67,7 +67,7 @@ Test.</text>
</dtstamp>
<dtstart>
<parameters>
- <tzid><text>US/Eastern</text></tzid>
+ <tzid><text>Europe/Zurich</text></tzid>
</parameters>
<date-time>2006-01-04T14:00:00</date-time>
</dtstart>
@@ -76,7 +76,7 @@ Test.</text>
</duration>
<recurrence-id>
<parameters>
- <tzid><text>US/Eastern</text></tzid>
+ <tzid><text>Europe/Zurich</text></tzid>
</parameters>
<date-time>2006-01-04T12:00:00</date-time>
</recurrence-id>
commit bc9dc0eafce9bea7c2302907033e18e632ebf325
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Feb 29 17:59:44 2012 +0100
Almost complete Kolab::Event to KCalCore conversion
diff --git a/c++/lib/kolabkcalconversion.cpp b/c++/lib/kolabkcalconversion.cpp
index 4a54c62..1c24bbe 100644
--- a/c++/lib/kolabkcalconversion.cpp
+++ b/c++/lib/kolabkcalconversion.cpp
@@ -134,6 +134,44 @@ QStringList toStringList(const std::vector<std::string> &l)
return list;
}
+KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
+{
+ switch (p) {
+ case PartNeedsAction:
+ return KCalCore::Attendee::NeedsAction;
+ case PartAccepted:
+ return KCalCore::Attendee::Accepted;
+ case PartDeclined:
+ return KCalCore::Attendee::Declined;
+ case PartTentative:
+ return KCalCore::Attendee::Tentative;
+ case PartDelegated:
+ return KCalCore::Attendee::Delegated;
+ default:
+ qWarning() << "unhandled";
+ Q_ASSERT(0);
+ }
+ return KCalCore::Attendee::NeedsAction;
+}
+
+KCalCore::Attendee::Role toRole(Kolab::Role r)
+{
+ switch (r) {
+ case Required:
+ return KCalCore::Attendee::ReqParticipant;
+ case Chair:
+ return KCalCore::Attendee::Chair;
+ case Optional:
+ return KCalCore::Attendee::OptParticipant;
+ case NonParticipant:
+ return KCalCore::Attendee::NonParticipant;
+ default:
+ qWarning() << "unhandled";
+ Q_ASSERT(0);
+ }
+ return KCalCore::Attendee::ReqParticipant;
+}
+
void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
{
if (!e.uid().empty()) {
@@ -152,17 +190,34 @@ void setIncidence(KCalCore::Incidence &i, const Kolab::Event &e)
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();
-// i.addAttendee();
-// i.addAttachment();
-// i.addAlarm();
-// i.setCustomProperties();
+ 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()),
+ a.rsvp(),
+ toPartStat(a.partStat()),
+ toRole(a.role()),
+ QString::fromStdString(a.uid()) )));
+ }
+ foreach (const Kolab::Attachment a, e.attachments()) {
+ KCalCore::Attachment::Ptr ptr;
+ if (!a.uri().empty()) {
+ ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QString::fromStdString(a.uri()), QString::fromStdString(a.mimetype())));
+ } else {
+ ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()), QString::fromStdString(a.mimetype())));
+ }
+ if (!a.label().empty()) {
+ ptr->setLabel(QString::fromStdString(a.label()));
+ }
+ i.addAttachment(ptr);
+ }
+// i.addAlarm(); //TODO
+// i.setCustomProperties(); //TODO
}
void getIncidence(Event &i, const KCalCore::Event &e)
@@ -171,7 +226,61 @@ void getIncidence(Event &i, const KCalCore::Event &e)
// i.setCreated(fromDate(e.created()));
}
+int toWeekDay(Kolab::Weekday wday)
+{
+ switch (wday) {
+ case Kolab::Monday:
+ return 1;
+ case Kolab::Tuesday:
+ return 2;
+ case Kolab::Wednesday:
+ return 3;
+ case Kolab::Thursday:
+ return 4;
+ case Kolab::Friday:
+ return 5;
+ case Kolab::Saturday:
+ return 6;
+ case Kolab::Sunday:
+ return 7;
+ default:
+ qWarning() << "unhandled";
+ Q_ASSERT(0);
+ }
+ return 1;
+}
+
+KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
+{
+ switch(freq) {
+ case Kolab::RecurrenceRule::None:
+ qWarning() << "no recurrence?";
+ break;
+ case Kolab::RecurrenceRule::Yearly:
+ return KCalCore::RecurrenceRule::rYearly;
+ case Kolab::RecurrenceRule::Monthly:
+ return KCalCore::RecurrenceRule::rMonthly;
+ case Kolab::RecurrenceRule::Weekly:
+ return KCalCore::RecurrenceRule::rWeekly;
+ case Kolab::RecurrenceRule::Daily:
+ return KCalCore::RecurrenceRule::rDaily;
+ case Kolab::RecurrenceRule::Hourly:
+ return KCalCore::RecurrenceRule::rHourly;
+ case Kolab::RecurrenceRule::Minutely:
+ return KCalCore::RecurrenceRule::rMinutely;
+ case Kolab::RecurrenceRule::Secondly:
+ return KCalCore::RecurrenceRule::rSecondly;
+ default:
+ qWarning() << "unhandled";
+ Q_ASSERT(0);
+ }
+ return KCalCore::RecurrenceRule::rNone;
+}
+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)
{
@@ -185,8 +294,63 @@ KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
} else {
e->setTransparency(KCalCore::Event::Opaque);
}
-// e->recurrence();
+ const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
+ if (rrule.isValid()) {
+ 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
+ } else {
+ rec->setDuration(rrule.count());
+ }
+
+ if (!rrule.bysecond().empty()) {
+ defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
+ }
+ if (!rrule.byminute().empty()) {
+ defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
+ }
+ if (!rrule.byhour().empty()) {
+ defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
+ }
+ if (!rrule.byday().empty()) {
+ QList<KCalCore::RecurrenceRule::WDayPos> daypos;
+ foreach(const Kolab::DayPos &dp, rrule.byday()) {
+ daypos.append(toWeekDayPos(dp));
+ }
+ defaultRR->setByDays(daypos);
+ }
+ if (!rrule.bymonthday().empty()) {
+ defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
+ }
+ if (!rrule.byyearday().empty()) {
+ defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
+ }
+ if (!rrule.byweekno().empty()) {
+ defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
+ }
+ if (!rrule.bymonth().empty()) {
+ defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
+ }
+ }
+ foreach (const Kolab::DateTime &dt, event.recurrenceDates()) {
+ e->recurrence()->addRDateTime(toDate(dt));//TODO date/datetime
+ }
+ foreach (const Kolab::DateTime &dt, event.exceptionDates()) {
+ e->recurrence()->addExDateTime(toDate(dt));//TODO date/datetime
+ }
+ if (event.recurrenceID().isValid()) {
+ e->setRecurrenceId(toDate(event.recurrenceID()));
+ }
+
return e;
}
diff --git a/c++/tests/kcalconversiontest.cpp b/c++/tests/kcalconversiontest.cpp
index 80adff7..b8b9fdd 100644
--- a/c++/tests/kcalconversiontest.cpp
+++ b/c++/tests/kcalconversiontest.cpp
@@ -27,6 +27,76 @@ namespace QTest {
ba += ")";
return qstrdup(ba.data());
}
+
+ template<>
+ char *toString(const KCalCore::Attendee &at)
+ {
+ QByteArray ba = "Attendee(";
+ ba += at.name().toAscii() + ", ";
+ ba += at.email().toAscii() + ", ";
+ ba += QString::number(at.role()) + ", ";
+ ba += QString::number(at.status()) + ", ";
+ ba += QString::number(at.RSVP()) + ", ";
+ ba += at.delegate().toAscii() + ", ";
+ ba += at.delegator().toAscii() + ", ";
+ ba += at.uid().toAscii() + ", ";
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+
+
+ template<>
+ char *toString(const QList<int> &l)
+ {
+ QByteArray ba = "QList<int>(";
+ foreach(int i, l) {
+ ba += QString::number(i) + ", ";
+ }
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+
+ template<>
+ char *toString(const QList<KCalCore::RecurrenceRule::WDayPos> &l)
+ {
+ QByteArray ba = "QList<int>(";
+ foreach(const KCalCore::RecurrenceRule::WDayPos &i, l) {
+ ba += QString::number(i.pos()) + " ";
+ ba += QString::number(i.day()) + ", ";
+ }
+ ba += ")";
+ return qstrdup(ba.data());
+ }
+
+ template<>
+ char *toString(const KCalCore::Recurrence &at)
+ {
+ at.dump();
+ KCalCore::RecurrenceRule *r = at.defaultRRule();
+ QByteArray ba;
+ if (!r) {
+ ba += "Recurrence( )";
+ } else {
+ Q_ASSERT(r);
+ 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 += ")";
+ }
+ return qstrdup(ba.data());
+ }
}
void KCalConversionTest::testDate_data()
@@ -60,6 +130,16 @@ void KCalConversionTest::testConversion_data()
QTest::addColumn<Kolab::Event>( "kolab" );
Kolab::DateTime date(2011,2,2,12,11,10);
+ Kolab::DateTime date2(2011,2,2,12,12,10);
+ Kolab::DateTime date3(2012,2,2,12,12,10);
+ std::vector<int> intVector;
+ intVector.push_back(1);
+ intVector.push_back(-3);
+ intVector.push_back(2);
+ std::vector<std::string> stringVector;
+ stringVector.push_back("cat1");
+ stringVector.push_back("cat2");
+ stringVector.push_back("parent/child");
KCalCore::Event kcal;
kcal.setUid("uid");
@@ -67,7 +147,45 @@ void KCalConversionTest::testConversion_data()
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");
@@ -75,8 +193,50 @@ void KCalConversionTest::testConversion_data()
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;
}
@@ -98,7 +258,7 @@ void KCalConversionTest::testConversion()
QCOMPARE(e->dtEnd(), kcal.dtEnd());
QCOMPARE(e->duration(), kcal.duration());
QCOMPARE(e->transparency(), kcal.transparency());
- QCOMPARE(e->recurrence(), kcal.recurrence());
+ QCOMPARE(*e->recurrence(), *kcal.recurrence());
QCOMPARE(e->recurrenceId(), kcal.recurrenceId());
QCOMPARE(e->recurrenceType(), kcal.recurrenceType());
QCOMPARE(e->summary(), kcal.summary());
@@ -106,10 +266,22 @@ void KCalConversionTest::testConversion()
QCOMPARE(e->priority(), kcal.priority());
QCOMPARE(e->status(), kcal.status());
QCOMPARE(e->location(), kcal.location());
- QCOMPARE(e->organizer(), kcal.organizer());
- QCOMPARE(e->attendees(), kcal.attendees());
- QCOMPARE(e->attachments(), kcal.attachments());
- QCOMPARE(e->alarms(), kcal.alarms());
+ 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));
+ }
+
+// QCOMPARE(e->alarms(), kcal.alarms()); //TODO
+//TODO custom properties
+
+ const Kolab::Event &b = fromKCalCore(kcal);
+ QCOMPARE(b.uid(), kolab.uid());
}
/*
@@ -248,195 +420,6 @@ void KCalConversionTest::BenchmarkRoundtrip()
-#if 0
-class KCalConversionTest : public QObject
-{
- Q_OBJECT
- private slots:
-
- void testConversion_data()
- {
- QTest::addColumn<QString>( "kcalrecurrence" );
- QTest::addColumn<QString>( "result" );
-
- QTest::newRow( "test1" );
- }
-
- void testConversion()
- {
-
- }
-
-/*
- void testContacts_data()
- {
- createContactsTestSet();
- }
-
- void testContacts()
- {
- QFETCH( QString, vcardFileName );
- QFETCH( QString, mimeFileName );
-
- KolabHandler *handler = KolabHandler::createHandler( "contact", Collection() );
- QVERIFY( handler );
-
- // mime -> vcard conversion
- const Item kolabItem = readMimeFile( mimeFileName );
- QVERIFY( kolabItem.hasPayload() );
-
- Item::List vcardItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
- QCOMPARE( vcardItems.size(), 1 );
- QVERIFY( vcardItems.first().hasPayload<KABC::Addressee>() );
- KABC::Addressee convertedAddressee = vcardItems.first().payload<KABC::Addressee>();
-
- QFile vcardFile( vcardFileName );
- QVERIFY( vcardFile.open( QFile::ReadOnly ) );
- KABC::VCardConverter converter;
- const KABC::Addressee realAddressee = converter.parseVCard( vcardFile.readAll() );
-
- // fix up the converted addressee for comparisson
- convertedAddressee.setName( realAddressee.name() ); // name() apparently is something strange
- QVERIFY( !convertedAddressee.custom( "KOLAB", "CreationDate" ).isEmpty() );
- convertedAddressee.removeCustom( "KOLAB", "CreationDate" ); // that's conversion time !?
- QVERIFY( normalizePhoneNumbers( convertedAddressee, realAddressee ) ); // phone number ids are random
- QVERIFY( normalizeAddresses( convertedAddressee, realAddressee ) ); // same here
-
-// qDebug() << convertedAddressee.toString();
-// qDebug() << realAddressee.toString();
- QCOMPARE( realAddressee, convertedAddressee );
-
-
- // and now the other way around
- Item convertedKolabItem;
- Item vcardItem( "text/directory" );
- vcardItem.setPayload( realAddressee );
- handler->toKolabFormat( vcardItem, convertedKolabItem );
- QVERIFY( convertedKolabItem.hasPayload<KMime::Message::Ptr>() );
-
- const KMime::Message::Ptr convertedMime = convertedKolabItem.payload<KMime::Message::Ptr>();
- const KMime::Message::Ptr realMime = kolabItem.payload<KMime::Message::Ptr>();
-
-// qDebug() << convertedMime->encodedContent();
-// qDebug() << realMime->encodedContent();
- QVERIFY( compareMimeMessage( convertedMime, realMime ) );
-
- delete handler;
- }
-
- void testIncidences_data()
- {
- createIndidenceTestSet();
- }
-
- void testIncidences()
- {
- QFETCH( QString, type );
- QFETCH( QString, icalFileName );
- QFETCH( QString, mimeFileName );
-
- KolabHandler *handler = KolabHandler::createHandler( type.toLatin1(), Collection() );
- QVERIFY( handler );
-
- // mime -> vcard conversion
- const Item kolabItem = readMimeFile( mimeFileName );
- QVERIFY( kolabItem.hasPayload() );
-
- Item::List icalItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
- QCOMPARE( icalItems.size(), 1 );
- QVERIFY( icalItems.first().hasPayload<KCalCore::Incidence::Ptr>() );
- KCalCore::Incidence::Ptr convertedIncidence = icalItems.first().payload<KCalCore::Incidence::Ptr>();
-
- QFile icalFile( icalFileName );
- QVERIFY( icalFile.open( QFile::ReadOnly ) );
- KCalCore::ICalFormat format;
- const KCalCore::Incidence::Ptr realIncidence( format.fromString( QString::fromUtf8( icalFile.readAll() ) ) );
-
- // fix up the converted incidence for comparisson
- foreach ( KCalCore::Attendee::Ptr a, convertedIncidence->attendees() )
- a->setUid( QString() ); // contains random values
- foreach ( KCalCore::Attendee::Ptr a, realIncidence->attendees() )
- a->setUid( QString() ); // contains random values
- if ( type == "task" ) {
- QVERIFY( icalItems.first().hasPayload<KCalCore::Todo::Ptr>() );
- KCalCore::Todo::Ptr todo = icalItems.first().payload<KCalCore::Todo::Ptr>();
- if ( !todo->hasDueDate() && !todo->hasStartDate() )
- convertedIncidence->setAllDay( realIncidence->allDay() ); // all day has no meaning if there are no start and due dates but may differ nevertheless
- }
- // recurrence objects are created on demand, but KCalCore::Incidence::operator==() doesn't take that into account
- // so make sure both incidences have one
- realIncidence->recurrence();
- convertedIncidence->recurrence();
-
- if ( *(realIncidence.data()) != *(convertedIncidence.data()) ) {
- qDebug() << "REAL: " << format.toString( realIncidence );
- qDebug() << "CONVERTED: " << format.toString( convertedIncidence );
- }
- QVERIFY( *(realIncidence.data()) == *(convertedIncidence.data()) );
-
-
- // and now the other way around
- Item convertedKolabItem;
- Item icalItem;
- switch ( realIncidence->type() ) {
- case KCalCore::IncidenceBase::TypeEvent: icalItem.setMimeType( KCalCore::Event::eventMimeType() ); return;
- case KCalCore::IncidenceBase::TypeTodo: icalItem.setMimeType( KCalCore::Todo::todoMimeType() ); return;
- case KCalCore::IncidenceBase::TypeJournal: icalItem.setMimeType( KCalCore::Journal::journalMimeType() ); return;
- default: QFAIL( "incidence type not supported" );
- }
- icalItem.setPayload( realIncidence );
- handler->toKolabFormat( icalItem, convertedKolabItem );
- QVERIFY( convertedKolabItem.hasPayload<KMime::Message::Ptr>() );
-
- const KMime::Message::Ptr convertedMime = convertedKolabItem.payload<KMime::Message::Ptr>();
- const KMime::Message::Ptr realMime = kolabItem.payload<KMime::Message::Ptr>();
-
-// qDebug() << convertedMime->encodedContent();
-// qDebug() << realMime->encodedContent();
- QVERIFY( compareMimeMessage( convertedMime, realMime ) );
-
- delete handler;
- }
-
- void benchmarkContactsLoading_data()
- {
- createContactsTestSet();
- }
-
- void benchmarkContactsLoading()
- {
- QFETCH( QString, vcardFileName );
- QFETCH( QString, mimeFileName );
-
- QBENCHMARK {
- KolabHandler *handler = KolabHandler::createHandler( "contact", Collection() );
- const Item kolabItem = readMimeFile( mimeFileName );
- const Item::List vcardItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
- delete handler;
- }
- }
-
- void benchmarkIncidenceLoading_data()
- {
- createIndidenceTestSet();
- }
-
- void benchmarkIncidenceLoading()
- {
- QFETCH( QString, type );
- QFETCH( QString, mimeFileName );
-
- QBENCHMARK {
- KolabHandler *handler = KolabHandler::createHandler( type.toLatin1(), Collection() );
- const Item kolabItem = readMimeFile( mimeFileName );
- const Item::List icalItems = handler->translateItems( Akonadi::Item::List() << kolabItem );
- delete handler;
- }
- }*/
-};
-#endif
-
-
QTEST_MAIN( KCalConversionTest )
#include "kcalconversiontest.moc"
commit 80e4ac5442f989c869861319cb5192ce753d26d5
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date: Wed Feb 29 13:51:58 2012 +0100
make XMLParserWrapper threadsafe.
Creates one xerces instance per thread, so memory usage is probably not ideal.
diff --git a/c++/compiled/XMLParserWrapper.cpp b/c++/compiled/XMLParserWrapper.cpp
index ce38d2c..169599a 100644
--- a/c++/compiled/XMLParserWrapper.cpp
+++ b/c++/compiled/XMLParserWrapper.cpp
@@ -40,6 +40,8 @@
#include <xsd/cxx/tree/error-handler.hxx>
+#include <boost/thread.hpp>
+
#include "kolabformat-xcal-schema.hxx"
#include "grammar-input-stream.hxx"
@@ -64,6 +66,18 @@ XMLParserWrapper::~XMLParserWrapper()
}
+boost::thread_specific_ptr<XMLParserWrapper> ptr;
+
+XMLParserWrapper& XMLParserWrapper::inst()
+{
+ XMLParserWrapper *t = ptr.get();
+ if (!t) {
+ t = new XMLParserWrapper();
+ ptr.reset(t);
+ }
+ return *t;
+}
+
void XMLParserWrapper::init()
{
diff --git a/c++/compiled/XMLParserWrapper.h b/c++/compiled/XMLParserWrapper.h
index 1c8b7ee..03640cd 100644
--- a/c++/compiled/XMLParserWrapper.h
+++ b/c++/compiled/XMLParserWrapper.h
@@ -57,10 +57,11 @@ public:
XMLParserWrapper();
~XMLParserWrapper();
- static XMLParserWrapper &inst(){
- static XMLParserWrapper instance;
- return instance;
- };
+ /**
+ * Threadsafe singleton. One Xerces instance is created per thread (threadlocal).
+ * Access via singleton to reuse parser.
+ */
+ static XMLParserWrapper &inst();
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseFile(const std::string &url);
xml_schema::dom::auto_ptr<xercesc::DOMDocument> parseString(const std::string &s);
More information about the commits
mailing list