2 commits - calendaring/calendaring.cpp calendaring/calendaring.h calendaring/calendaring.i calendaring/CMakeLists.txt calendaring/python CMakeLists.txt cmake/modules conversion/commonconversion.cpp conversion/commonconversion.h tests/calendaringtest.cpp tests/calendaringtest.h tests/CMakeLists.txt tests/kcalconversiontest.cpp tests/kcalconversiontest.h tests/testhelpers.h

Christian Mollekopf mollekopf at kolabsys.com
Mon May 21 12:13:17 CEST 2012


 CMakeLists.txt                    |   17 +-
 calendaring/CMakeLists.txt        |    7 
 calendaring/calendaring.cpp       |   95 +++++++++--
 calendaring/calendaring.h         |   60 ++++++-
 calendaring/calendaring.i         |   10 -
 calendaring/python/CMakeLists.txt |   46 +++++
 cmake/modules/FindSWIG.cmake      |    9 +
 conversion/commonconversion.cpp   |   37 ++--
 conversion/commonconversion.h     |    4 
 tests/CMakeLists.txt              |    4 
 tests/calendaringtest.cpp         |  311 ++++++++++++++++++++++++++++++++++++++
 tests/calendaringtest.h           |   42 +++++
 tests/kcalconversiontest.cpp      |  290 -----------------------------------
 tests/kcalconversiontest.h        |    6 
 tests/testhelpers.h               |  200 ++++++++++++++++++++++++
 15 files changed, 793 insertions(+), 345 deletions(-)

New commits:
commit 512b2ef019fd637d17e97993619e84636ccd9210
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon May 21 12:13:11 2012 +0200

    Some calendaring functionality including python bindings.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 449a453..2e88b78 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,10 +3,22 @@ project(Libkolab)
 cmake_minimum_required(VERSION 2.6.4)
 
 option( BUILD_TESTS "Build the tests" TRUE )
+option( PYTHON_BINDINGS "Build bindings for python" FALSE )
 
 set(Libkolab_MODULE_DIR ${Libkolab_SOURCE_DIR}/cmake/modules)
 set(CMAKE_MODULE_PATH ${Libkolab_MODULE_DIR})
 
+# only available from cmake-2.8.0
+if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7)
+    cmake_policy(SET CMP0012 NEW)
+endif()
+
+# only available from cmake-2.8.4
+if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND
+    ${CMAKE_PATCH_VERSION} GREATER 3)
+    cmake_policy(SET CMP0017 NEW)
+endif()
+
 # Versioning
 # x.y.z scheme
 # Development versions are only x.y
@@ -52,8 +64,9 @@ configure_file(libkolab-version.h.cmake "${CMAKE_BINARY_DIR}/libkolab-version.h"
 
 add_subdirectory(kolabformatV2)
 add_subdirectory(conversion)
+add_subdirectory(calendaring)
 
-set(KOLAB_SRCS kolabformat/kolabobject.cpp kolabformat/errorhandler.cpp mime/mimeutils.cpp ${CONVERSION_SRCS} ${kolabformatv2_SRCS})
+set(KOLAB_SRCS kolabformat/kolabobject.cpp kolabformat/errorhandler.cpp mime/mimeutils.cpp ${CONVERSION_SRCS} ${kolabformatv2_SRCS} ${CALENDARING_SRCS})
 set(KOLAB_LINK_LIBRARIES ${Libkolabxml_LIBRARIES} ${KDEPIMLIBS_KCALCORE_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_KMIME_LIBS} ${KDEPIMLIBS_AKONADI_LIBS} ${KDEPIMLIBS_AKONADI_NOTES_LIBS} ${QT_QTCORE_LIBRARY} ${QT_QTXML_LIBRARY} ${QT_QTGUI_LIBRARY} ${KDE4_KDECORE_LIBRARY} ${KDE4_KIO_LIBRARY})
 if(BUILD_TESTS)
     #for tests only
diff --git a/calendaring/CMakeLists.txt b/calendaring/CMakeLists.txt
new file mode 100644
index 0000000..1d6db75
--- /dev/null
+++ b/calendaring/CMakeLists.txt
@@ -0,0 +1,7 @@
+set (CALENDARING_SRCS
+    ${CMAKE_CURRENT_SOURCE_DIR}/calendaring.cpp PARENT_SCOPE)
+
+if(PYTHON_BINDINGS)
+    message("building python bindings")
+    add_subdirectory(python)
+endif(PYTHON_BINDINGS)
\ No newline at end of file
diff --git a/calendaring/calendaring.cpp b/calendaring/calendaring.cpp
index e35af0e..119d328 100644
--- a/calendaring/calendaring.cpp
+++ b/calendaring/calendaring.cpp
@@ -20,35 +20,92 @@
 #include <kcalcore/event.h>
 #include <KDE/KCalCore/Todo>
 #include <Qt/qdebug.h>
+#include <kolabevent.h>
 
-#include "kolabkcalconversion.h"
+#include "conversion/kcalconversion.h"
+#include "conversion/commonconversion.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;
+bool conflicts(const Kolab::Event &e1, const Kolab::Event &e2)
+{
+    KCalCore::Event::Ptr k1 = Kolab::Conversion::toKCalCore(e1);
+    KCalCore::Event::Ptr k2 = Kolab::Conversion::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< std::vector< Kolab::Event > > getConflictingSets(const std::vector< Event > &events)
+{
+    std::vector< std::vector< Kolab::Event > > ret;
+    for(int i = 0; i < events.size(); i++) {
+        std::vector<Kolab::Event> set;
+        const Kolab::Event &event = events.at(i);
+        set.push_back(event);
+        for(int q = i+1; q < events.size(); q++) {
+            const Kolab::Event &e2 = events.at(q);
+            if (conflicts(event, e2)) {
+                set.push_back(e2);
             }
-            return true;
         }
+        if (set.size() > 1) {
+            ret.push_back(set);
+        }
+    }
+    return ret;
+}
 
-        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &e, const Kolab::cDateTime &start, const Kolab::cDateTime &end)
-        {
-            KCalCore::Event::Ptr k = KCalConversion::toKCalCore(e);
-            KCalCore::DateTimeList list = k->recurrence()->timesInInterval(KCalConversion::toDate(start), KCalConversion::toDate(end));
-            std::vector<Kolab::cDateTime> dtList;
-            foreach(const KDateTime &dt, list) {
-                dtList.push_back(KCalConversion::fromDate(dt));
-            }
-            return dtList;
+
+std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &e, const Kolab::cDateTime &start, const Kolab::cDateTime &end)
+{
+    KCalCore::Event::Ptr k = Kolab::Conversion::toKCalCore(e);
+    KCalCore::DateTimeList list = k->recurrence()->timesInInterval(Kolab::Conversion::toDate(start), Kolab::Conversion::toDate(end));
+    std::vector<Kolab::cDateTime> dtList;
+    foreach(const KDateTime &dt, list) {
+        dtList.push_back(Kolab::Conversion::fromDate(dt));
+    }
+    return dtList;
+}
+
+Calendar::Calendar()
+:   mCalendar(new KCalCore::MemoryCalendar(Kolab::Conversion::getTimeSpec(true, std::string()))) //Always utc as it doesn't change anything anyways
+{
+}
+
+void Calendar::addEvent(const Kolab::Event &event)
+{
+    KCalCore::Event::Ptr k = Kolab::Conversion::toKCalCore(event);
+    if (!mCalendar->addEvent(k)) {
+        qWarning() << "failed to add event";
+    }
+}
+
+
+std::vector<Kolab::Event> Calendar::getEvents(const Kolab::cDateTime& start, const Kolab::cDateTime& end, bool sort)
+{
+    const KDateTime s = Kolab::Conversion::toDate(start);
+    const KDateTime e = Kolab::Conversion::toDate(end);
+    const KDateTime::Spec timeSpec = s.timeSpec();
+    KCalCore::Event::List list = mCalendar->events(s.date(), e.date(), timeSpec, true);
+    if (sort) {
+        list = mCalendar->sortEvents(list, KCalCore::EventSortStartDate, KCalCore::SortDirectionAscending);
+    }
+    std::vector<Kolab::Event> eventlist;
+    foreach (const KCalCore::Event::Ptr &event, list) {
+        //We have to filter the list by time
+        if (event->dtEnd().compare(s) != KDateTime::Before && e.compare(event->dtStart()) != KDateTime::Before) {
+            eventlist.push_back(Kolab::Conversion::fromKCalCore(*event));
         }
+    }
+    return eventlist;
+}
+
 
     } //Namespace
 } //Namespace
\ No newline at end of file
diff --git a/calendaring/calendaring.h b/calendaring/calendaring.h
index 12d7c53..ffee9a6 100644
--- a/calendaring/calendaring.h
+++ b/calendaring/calendaring.h
@@ -18,18 +18,62 @@
 #ifndef KOLABCALENDARING_H
 #define KOLABCALENDARING_H
 
-#include "kolabevent.h"
+#ifndef SWIG
+#include "kolab_export.h"
+#else
+/* No export/import SWIG interface files */
+#define KOLAB_EXPORT
+#endif
+
 #include <kcalcore/event.h>
+#include <kcalcore/memorycalendar.h>
+#include <boost/scoped_ptr.hpp>
+#include <kolabevent.h>
 
 namespace Kolab {
     namespace Calendaring {
-        /**
-         * Returns true if the events conflict (overlap)
-         */
-        bool conflicts(const Kolab::Event &, const Kolab::Event &);
+/**
+ * Returns true if the events conflict (overlap)
+ * Start and end date/time is inclusive.
+ */
+KOLAB_EXPORT bool conflicts(const Kolab::Event &, const Kolab::Event &);
+
+/**
+ * Returns sets of the events which are directly conflicting with each other
+ * The same event may appear in multiple sets.
+ * Non-conflicting events are not returned.
+ * conflicts() is used for conflict detection.
+ */
+KOLAB_EXPORT std::vector< std::vector<Kolab::Event> > getConflictingSets(const std::vector<Kolab::Event> &);
 
-        std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &, const Kolab::cDateTime &start, const Kolab::cDateTime &end);
-    };
+/**
+ * Returns the dates in which the event recurs within the specified timespan.
+ */
+KOLAB_EXPORT std::vector<Kolab::cDateTime> timeInInterval(const Kolab::Event &, const Kolab::cDateTime &start, const Kolab::cDateTime &end);
+
+/**
+ * In-Memory Calendar Cache
+ */
+class KOLAB_EXPORT Calendar {
+public:
+    explicit Calendar();
+    /**
+     * Add an event to the in-memory calendar.
+     */
+    void addEvent(const Kolab::Event &);
+    /**
+     * Returns all events within the specified interval (start and end inclusive).
+     *
+     * @param sort controls if the resulting event set is sorted in ascending order according to the start date
+     */
+    std::vector<Kolab::Event> getEvents(const Kolab::cDateTime &start, const Kolab::cDateTime &end, bool sort);
+private:
+    Calendar(const Calendar &);
+    void operator=(const Calendar &);
+    boost::scoped_ptr<KCalCore::MemoryCalendar> mCalendar;
 };
 
-#endif
\ No newline at end of file
+    }; //Namespace
+}; //Namespace
+
+#endif
diff --git a/calendaring/calendaring.i b/calendaring/calendaring.i
index 45410e4..e9c986e 100644
--- a/calendaring/calendaring.i
+++ b/calendaring/calendaring.i
@@ -1,5 +1,5 @@
 /* calendaring.i */
-%module kolabcalendaring
+%module calendaring
 %{
 
     /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */
@@ -8,16 +8,12 @@
     #include "calendaring.h"
 %}
 
-/*
 %include "std_string.i"
 %include "std_vector.i"
 
 namespace std {
-    %template(vectori) vector<int>;
-    %template(vectors) vector<string>;
-    %template(vectordate) vector<Kolab::DateTime>;
-    %template(vectordaypos) vector<Kolab::DayPos>;
-};*/
+    %template(vectordatetime) vector<Kolab::cDateTime>;
+};
 
 /*%apply const std::string& {std::string* foo};*/
 
diff --git a/calendaring/python/CMakeLists.txt b/calendaring/python/CMakeLists.txt
new file mode 100644
index 0000000..4743335
--- /dev/null
+++ b/calendaring/python/CMakeLists.txt
@@ -0,0 +1,46 @@
+include_directories(../)
+find_package(SWIG REQUIRED)
+
+# Compile Python Bindings
+
+find_package(PythonLibs)
+
+if (NOT PYTHONLIBS_FOUND)
+    message("python libs not found, not building python bindings")
+    return()
+endif()
+message("found python include dirs: ${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}")
+
+set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${CMAKE_CURRENT_BINARY_DIR}/python_calendaring_wrapper.cpp)
+set(KOLAB_SWIG_PYTHON_HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/calendaring.py)
+
+add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE} ${KOLAB_SWIG_PYTHON_HEADER_FILE}
+    COMMAND ${SWIG} -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} ../calendaring.i
+    COMMENT "Generating python bindings"
+    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+    DEPENDS ../calendaring.i kolab
+    VERBATIM
+    )
+
+SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1)
+
+#${PYTHON_INCLUDE_PATH} is for backwards compatibility (el6)
+include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH})
+
+set(PYTHON_MODULE_PREFIX "_")
+python_add_module(calendaring ${KOLAB_SWIG_PYTHON_SOURCE_FILE})
+
+#cmake 2.6.4 fails to respect the module prefix
+SET_TARGET_PROPERTIES(calendaring PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}")
+
+target_link_libraries(calendaring kolab ${PYTHON_LIBRARIES})
+# configure_file(test.py ${CMAKE_CURRENT_BINARY_DIR} COPYONLY)
+
+set(PYTHON_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/pythonbindings" CACHE STRING "Install directory for python bindings.")
+
+install(TARGETS calendaring LIBRARY DESTINATION ${PYTHON_INSTALL_DIR})
+
+install( FILES
+        ${KOLAB_SWIG_PYTHON_HEADER_FILE}
+        DESTINATION ${PYTHON_INSTALL_DIR}
+    )
\ No newline at end of file
diff --git a/cmake/modules/FindSWIG.cmake b/cmake/modules/FindSWIG.cmake
new file mode 100644
index 0000000..f2476a6
--- /dev/null
+++ b/cmake/modules/FindSWIG.cmake
@@ -0,0 +1,9 @@
+find_program(SWIG swig /usr/bin/)
+if(SWIG)
+    set(SWIG_FOUND ON)
+    message("SWIG found")
+endif()
+
+#abort if any of the requireds are missing
+find_package_handle_standard_args(SWIG  DEFAULT_MSG
+                                  SWIG_FOUND SWIG)
\ No newline at end of file
diff --git a/conversion/commonconversion.cpp b/conversion/commonconversion.cpp
index 804e7f0..d91accf 100644
--- a/conversion/commonconversion.cpp
+++ b/conversion/commonconversion.cpp
@@ -23,6 +23,27 @@
 
 namespace Kolab {
     namespace Conversion {
+
+KDateTime::Spec getTimeSpec(bool isUtc, const std::string& timezone)
+{
+    if (isUtc) { //UTC
+        return KDateTime::Spec(KDateTime::UTC);
+    }
+    if (timezone.empty()) { //Floating
+        return  KDateTime::Spec(KDateTime::ClockTime);
+    }
+    //Timezone
+    KTimeZone tz = KSystemTimeZones::zone(QString::fromStdString(timezone)); //Needs ktimezoned (timezone daemon running) http://api.kde.org/4.x-api/kdelibs-apidocs/kdecore/html/classKSystemTimeZones.html
+    if (!tz.isValid()) {
+        Error() << "timezone not found" << QString::fromStdString(timezone);
+        if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
+            Error() << "ktimezoned is not available and required for timezone interpretation";
+        }
+        tz = KTimeZone::utc(); //Don't crash
+    }
+    return KDateTime::Spec(tz);
+}
+
         
 KDateTime toDate(const Kolab::cDateTime &dt)
 {
@@ -38,21 +59,7 @@ KDateTime toDate(const Kolab::cDateTime &dt)
     } else {
         date.setDate(QDate(dt.year(), dt.month(), dt.day()));
         date.setTime(QTime(dt.hour(), dt.minute(), dt.second()));
-        if (dt.isUTC()) { //UTC
-            date.setTimeSpec(KDateTime::Spec(KDateTime::UTC));
-        } else if (!dt.timezone().empty()) { //Timezone
-            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()) {
-                Error() << "timezone not found" << QString::fromStdString(dt.timezone());
-                if (!KSystemTimeZones::isTimeZoneDaemonAvailable()) {
-                    Error() << "ktimezoned is not available and required for timezone interpretation";
-                }
-                tz = KTimeZone::utc(); //Don't crash
-            }
-            date.setTimeSpec(KDateTime::Spec(tz));
-        } else { //Floating
-            date.setTimeSpec(KDateTime::Spec(KDateTime::ClockTime));
-        }
+        date.setTimeSpec(getTimeSpec(dt.isUTC(), dt.timezone()));
     }
     Q_ASSERT(date.timeSpec().isValid());
     Q_ASSERT(date.isValid());
diff --git a/conversion/commonconversion.h b/conversion/commonconversion.h
index 301e54a..7a3bc82 100644
--- a/conversion/commonconversion.h
+++ b/conversion/commonconversion.h
@@ -29,6 +29,10 @@ namespace Kolab {
         cDateTime fromDate(const KDateTime &dt);
         QStringList toStringList(const std::vector<std::string> &l);
         std::vector<std::string> fromStringList(const QStringList &l);
+        /**
+         * Returns a UTC, Floating Time or Timezone
+         */
+        KDateTime::Spec getTimeSpec(bool isUtc, const std::string &timezone);
     };
 };
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c7aedad..7a87fc2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -16,3 +16,7 @@ target_link_libraries(upgradetest ${QT_QTTEST_LIBRARY} kolab_static)
 QT4_AUTOMOC(kcalconversiontest.cpp)
 add_executable(kcalconversiontest kcalconversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
 target_link_libraries(kcalconversiontest ${QT_QTTEST_LIBRARY} kolab_static)
+
+QT4_AUTOMOC(calendaringtest.cpp)
+add_executable(calendaringtest calendaringtest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC})
+target_link_libraries(calendaringtest ${QT_QTTEST_LIBRARY} kolab_static)
diff --git a/tests/calendaringtest.cpp b/tests/calendaringtest.cpp
new file mode 100644
index 0000000..1971587
--- /dev/null
+++ b/tests/calendaringtest.cpp
@@ -0,0 +1,311 @@
+/*
+    Copyright (C) 2012  <Christian Mollekopf> <mollekopf at kolabsys.com>
+
+    This library 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 2.1 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include "calendaringtest.h"
+
+#include <QTest>
+#include <kolabevent.h>
+
+#include "calendaring/calendaring.h"
+
+#include "testhelpers.h"
+
+
+Kolab::Event createEvent(const Kolab::cDateTime &start, const Kolab::cDateTime &end)
+{
+    Kolab::Event event;
+    event.setStart(start);
+    event.setEnd(end);
+    return event;
+}
+
+void compareEvents(const std::vector<Kolab::Event> &list1, const std::vector<Kolab::Event> &list2)
+{
+    QCOMPARE(list1.size(), list2.size());
+    for (int i = 0; i < list1.size(); i++) {
+        const Kolab::Event &e1 = list1.at(i);
+        const Kolab::Event &e2 = list2.at(i);
+//         qDebug() << i;
+        QCOMPARE(e1.start(), e2.start());
+        QCOMPARE(e1.end(), e2.end());
+    }
+}
+
+
+void CalendaringTest::testEventConflict_data()
+{
+    QTest::addColumn<Kolab::Event>( "e1" );
+    QTest::addColumn<Kolab::Event>( "e2" );
+    QTest::addColumn<bool>( "result" );
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
+
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1,true));
+        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1,true));
+
+        QTest::newRow( "after" ) << e1 << e2 << false;
+    }
+
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
+
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1,true));
+        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1,true));
+
+        QTest::newRow( "before" ) << e1 << e2 << false;
+    }
+
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
+        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
+
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
+        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
+
+        QTest::newRow( "conflict" ) << e1 << e2 << true;
+    }
+
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
+
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
+
+        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
+    }
+
+    {
+        Kolab::Event e1;
+        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
+        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
+
+        Kolab::Event e2;
+        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
+        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
+
+        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
+    }
+}
+
+void CalendaringTest::testEventConflict()
+{
+    QFETCH(Kolab::Event, e1);
+    QFETCH(Kolab::Event, e2);
+    QFETCH(bool, result);
+    QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
+}
+
+void CalendaringTest::testEventConflictSet()
+{
+    std::vector<Kolab::Event> events;
+    events.push_back(createEvent(Kolab::cDateTime(2011,10,6,12,1,1,true), Kolab::cDateTime(2011,10,8,12,1,1,true)));
+    events.push_back(createEvent(Kolab::cDateTime(2011,10,7,12,1,1,true), Kolab::cDateTime(2011,10,10,12,1,1,true)));
+    events.push_back(createEvent(Kolab::cDateTime(2011,10,9,12,1,1,true), Kolab::cDateTime(2011,10,11,12,1,1,true)));
+    const std::vector< std::vector<Kolab::Event> > &result = Kolab::Calendaring::getConflictingSets(events);
+
+
+    std::vector< std::vector<Kolab::Event> > expectedResult;
+    std::vector<Kolab::Event> r1;
+    r1.push_back(createEvent(Kolab::cDateTime(2011,10,6,12,1,1,true), Kolab::cDateTime(2011,10,8,12,1,1,true)));
+    r1.push_back(createEvent(Kolab::cDateTime(2011,10,7,12,1,1,true), Kolab::cDateTime(2011,10,10,12,1,1,true)));
+    expectedResult.push_back(r1);
+    std::vector<Kolab::Event> r2;
+    r2.push_back(createEvent(Kolab::cDateTime(2011,10,7,12,1,1,true), Kolab::cDateTime(2011,10,10,12,1,1,true)));
+    r2.push_back(createEvent(Kolab::cDateTime(2011,10,9,12,1,1,true), Kolab::cDateTime(2011,10,11,12,1,1,true)));
+    expectedResult.push_back(r2);
+
+    for (int i = 0; i < result.size(); i++) {
+        const std::vector<Kolab::Event> &list = result.at(i);
+        
+        qDebug() << "---------_Set--------------";
+        foreach(const Kolab::Event &event, list) {
+            qDebug() << QTest::toString(event.start()) << QTest::toString(event.end());
+        }
+        compareEvents(result.at(i), expectedResult.at(i));
+    }
+
+    
+}
+
+void CalendaringTest::testTimesInInterval_data()
+{
+    QTest::addColumn<Kolab::Event>( "event" );
+    QTest::addColumn<Kolab::cDateTime>( "start" );
+    QTest::addColumn<Kolab::cDateTime>( "end" );
+    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
+    {
+        {
+            Kolab::Event event;
+            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1,true));
+            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1,true));
+            Kolab::RecurrenceRule rrule;
+            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+            rrule.setInterval(1);
+            rrule.setCount(5);
+            event.setRecurrenceRule(rrule);
+
+            std::vector<Kolab::cDateTime> result;
+            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1,true));
+            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1,true));
+            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1,true));
+            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1,true));
+            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1,true));
+            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1,true) << Kolab::cDateTime(2011,1,5,1,1,1,true) << result;
+        }
+    }
+}
+
+void CalendaringTest::testTimesInInterval()
+{
+    QFETCH(Kolab::Event, event);
+    QFETCH(Kolab::cDateTime, start);
+    QFETCH(Kolab::cDateTime, end);
+    QFETCH(std::vector<Kolab::cDateTime>, result);
+    QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
+}
+
+void CalendaringTest::testTimesInIntervalBenchmark()
+{
+    Kolab::Event event;
+    event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
+    event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
+    Kolab::RecurrenceRule rrule;
+    rrule.setFrequency(Kolab::RecurrenceRule::Daily);
+    rrule.setInterval(1);
+    rrule.setCount(500);
+    event.setRecurrenceRule(rrule);
+
+    QBENCHMARK {
+        Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+    }
+    const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
+    QVERIFY(result.size() == 500);
+//     qDebug() << QTest::toString(result);
+}
+
+void CalendaringTest::testCalendar_data()
+{
+    QTest::addColumn< std::vector<Kolab::Event> >( "inputevents" );
+    QTest::addColumn<Kolab::cDateTime>( "start" );
+    QTest::addColumn<Kolab::cDateTime>( "end" );
+    QTest::addColumn< std::vector<Kolab::Event> >( "expectedResult" );
+
+    {
+        std::vector<Kolab::Event> inputevents;
+        for (int day = 1; day < 28; day++) {
+            for (int hour = 1; hour < 20; hour+=2) {
+                inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,day,hour,4,4, true), Kolab::cDateTime(2012,5,day,hour+1,4,4, true)));
+            }
+        }
+        std::vector<Kolab::Event> expectedResult;
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,3,4,4, true), Kolab::cDateTime(2012,5,5,3+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,5,4,4, true), Kolab::cDateTime(2012,5,5,5+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,7,4,4, true), Kolab::cDateTime(2012,5,5,7+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,9,4,4, true), Kolab::cDateTime(2012,5,5,9+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,11,4,4, true), Kolab::cDateTime(2012,5,5,11+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,13,4,4, true), Kolab::cDateTime(2012,5,5,13+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,15,4,4, true), Kolab::cDateTime(2012,5,5,15+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,17,4,4, true), Kolab::cDateTime(2012,5,5,17+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,19,4,4, true), Kolab::cDateTime(2012,5,5,19+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,6,1,4,4, true), Kolab::cDateTime(2012,5,6,1+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,6,3,4,4, true), Kolab::cDateTime(2012,5,6,3+1,4,4, true)));
+        QTest::newRow( "simple" ) << inputevents << Kolab::cDateTime(2012,5,5,4,4,4, true) << Kolab::cDateTime(2012,5,6,4,4,4, true) << expectedResult;
+    }
+
+    { //Start and end time inclusive
+        std::vector<Kolab::Event> inputevents;
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,1,4,4, true), Kolab::cDateTime(2012,5,5,1+1,4,4, true)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,3,4,4, true), Kolab::cDateTime(2012,5,5,3+1,4,4, true)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,5,4,4, true), Kolab::cDateTime(2012,5,5,5+1,4,4, true)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,7,4,4, true), Kolab::cDateTime(2012,5,5,7+1,4,4, true)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,9,4,4, true), Kolab::cDateTime(2012,5,5,9+1,4,4, true)));
+
+        std::vector<Kolab::Event> expectedResult;
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,3,4,4, true), Kolab::cDateTime(2012,5,5,3+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,5,4,4, true), Kolab::cDateTime(2012,5,5,5+1,4,4, true)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,7,4,4, true), Kolab::cDateTime(2012,5,5,7+1,4,4, true)));
+        QTest::newRow( "startEndTimeInclusive" ) << inputevents << Kolab::cDateTime(2012,5,5,3,4,4, true) << Kolab::cDateTime(2012,5,5,7,4,4, true) << expectedResult;
+    }
+
+    { //Start and end time inclusive (floating time)
+        std::vector<Kolab::Event> inputevents;
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,1,4,4, false), Kolab::cDateTime(2012,5,5,1+1,4,4, false)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,3,4,4, false), Kolab::cDateTime(2012,5,5,3+1,4,4, false)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,5,4,4, false), Kolab::cDateTime(2012,5,5,5+1,4,4, false)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,7,4,4, false), Kolab::cDateTime(2012,5,5,7+1,4,4, false)));
+        inputevents.push_back(createEvent(Kolab::cDateTime(2012,5,5,9,4,4, false), Kolab::cDateTime(2012,5,5,9+1,4,4, false)));
+
+        std::vector<Kolab::Event> expectedResult;
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,3,4,4, false), Kolab::cDateTime(2012,5,5,3+1,4,4, false)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,5,4,4, false), Kolab::cDateTime(2012,5,5,5+1,4,4, false)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime(2012,5,5,7,4,4, false), Kolab::cDateTime(2012,5,5,7+1,4,4, false)));
+        QTest::newRow( "startEndTimeInclusive" ) << inputevents << Kolab::cDateTime(2012,5,5,3,4,4, false) << Kolab::cDateTime(2012,5,5,7,4,4, false) << expectedResult;
+    }
+
+    { //Start and end time inclusive (timezone)
+        std::vector<Kolab::Event> inputevents;
+        inputevents.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,1,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,1+1,4,4)));
+        inputevents.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,3,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,3+1,4,4)));
+        inputevents.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,5,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,5+1,4,4)));
+        inputevents.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,7,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,7+1,4,4)));
+        inputevents.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,9,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,9+1,4,4)));
+
+        std::vector<Kolab::Event> expectedResult;
+        expectedResult.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,3,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,3+1,4,4)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,5,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,5+1,4,4)));
+        expectedResult.push_back(createEvent(Kolab::cDateTime("Europe/Zurich",2012,5,5,7,4,4), Kolab::cDateTime("Europe/Zurich",2012,5,5,7+1,4,4)));
+        QTest::newRow( "startEndTimeInclusive" ) << inputevents << Kolab::cDateTime("Europe/Zurich",2012,5,5,3,4,4) << Kolab::cDateTime("Europe/Zurich",2012,5,5,7,4,4) << expectedResult;
+    }
+    
+}
+
+void CalendaringTest::testCalendar()
+{
+
+    QFETCH(std::vector<Kolab::Event>, inputevents);
+    QFETCH(Kolab::cDateTime, start);
+    QFETCH(Kolab::cDateTime, end);
+    QFETCH(std::vector<Kolab::Event>, expectedResult);
+
+    Kolab::Calendaring::Calendar cal;
+    foreach (const Kolab::Event &event, inputevents) {
+        cal.addEvent(event);
+    }
+    const std::vector<Kolab::Event> result = cal.getEvents(start, end, true);
+    foreach (const Kolab::Event &event, result) {
+        qDebug() << QTest::toString(event.start()) << QTest::toString(event.end());
+    }
+    compareEvents(result, expectedResult);
+}
+
+
+QTEST_MAIN( CalendaringTest )
+
+#include "calendaringtest.moc"
diff --git a/tests/calendaringtest.h b/tests/calendaringtest.h
new file mode 100644
index 0000000..27db5d5
--- /dev/null
+++ b/tests/calendaringtest.h
@@ -0,0 +1,42 @@
+/*
+    Copyright (C) 2012  <Christian Mollekopf> <mollekopf at kolabsys.com>
+
+    This library 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 2.1 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#ifndef CALENDARINGTEST_H
+#define CALENDARINGTEST_H
+#include <QObject>
+
+class CalendaringTest: public QObject
+{
+    Q_OBJECT
+private slots:
+
+    void testEventConflict_data();
+    void testEventConflict();
+
+    void testEventConflictSet();
+
+    void testTimesInInterval_data();
+    void testTimesInInterval();
+    void testTimesInIntervalBenchmark();
+
+    void testCalendar_data();
+    void testCalendar();
+};
+
+#endif // CALENDARINGTEST_H
diff --git a/tests/kcalconversiontest.cpp b/tests/kcalconversiontest.cpp
index 8be49c5..29a7573 100644
--- a/tests/kcalconversiontest.cpp
+++ b/tests/kcalconversiontest.cpp
@@ -11,166 +11,10 @@
 #include "conversion/kcalconversion.h"
 #include "conversion/kcalconversion.cpp"
 #include "conversion/kabcconversion.h"
-// #include <lib/calendaring.h>
+#include "testhelpers.h"
 
 using namespace Kolab::Conversion;
 
-Q_DECLARE_METATYPE(Kolab::Duration);
-Q_DECLARE_METATYPE(Kolab::cDateTime);
-Q_DECLARE_METATYPE(Kolab::Event);
-Q_DECLARE_METATYPE(Kolab::Todo);
-Q_DECLARE_METATYPE(Kolab::Journal);
-Q_DECLARE_METATYPE(Kolab::Contact);
-Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
-Q_DECLARE_METATYPE(KCalCore::Event);
-Q_DECLARE_METATYPE(KCalCore::Todo);
-Q_DECLARE_METATYPE(KCalCore::Journal);
-Q_DECLARE_METATYPE(KCalCore::Duration);
-
-namespace QTest {
-    
-    template<>
-    char *toString(const KDateTime &dt)
-    {
-        QByteArray ba = "KDateTime(";
-        ba += dt.toString().toAscii();
-        ba += dt.timeZone().name();
-        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::DateList &l)
-    {
-        QByteArray ba = "KCalCore::DateList(";
-        foreach(const QDate &i, l) {
-            ba += i.toString();
-        }
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-    
-    template<>
-    char *toString(const KCalCore::DateTimeList &l)
-    {
-        QByteArray ba = "KCalCore::DateTimeList(";
-        foreach(const KDateTime &i, l) {
-            ba += toString(i);
-        }
-        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()) + "\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 += ")\n";
-            ba += QByteArray(toString(at.exDates())) + "\n";
-            ba += QByteArray(toString(at.exDateTimes())) + "\n";
-            ba += QByteArray(toString(at.rDates())) + "\n";
-            ba += QByteArray(toString(at.rDateTimes())) + "\n";
-            
-        }
-        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<>
-    char *toString(const KCalCore::Duration &d)
-    {
-        QByteArray ba;
-        ba += "KCalCore::Duration(";
-        ba += QString::number(d.isDaily()) + ", ";
-        ba += QString::number(d.value()) + " ";
-        ba += ")";
-        return qstrdup(ba.data());
-    }
-
-}
-
 template <typename T>
 void comparePointerVectors(const QVector<T> &list, const QVector<T> &other)
 {
@@ -618,138 +462,6 @@ void KCalConversionTest::testContactConversion()
 }
 
 
-void KCalConversionTest::testEventConflict_data()
-{
-    QTest::addColumn<Kolab::Event>( "e1" );
-    QTest::addColumn<Kolab::Event>( "e2" );
-    QTest::addColumn<bool>( "result" );
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,11,10,12,1,1,true));
-        e2.setEnd(Kolab::cDateTime(2011,11,11,12,1,1,true));
-        
-        QTest::newRow( "after" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,9,10,12,1,1,true));
-        e2.setEnd(Kolab::cDateTime(2011,9,11,12,1,1,true));
-        
-        QTest::newRow( "before" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
-        e1.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime(2011,10,10,12,1,1,true));
-        e2.setEnd(Kolab::cDateTime(2011,10,11,12,1,1,true));
-        
-        QTest::newRow( "conflict" ) << e1 << e2 << true;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Zurich", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Asia/Dubai",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz non-conflict" ) << e1 << e2 << false;
-    }
-    
-    {
-        Kolab::Event e1;
-        e1.setStart(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,1));
-        e1.setEnd(Kolab::cDateTime("Europe/Berlin", 2011,10,10,6,1,2));
-        
-        Kolab::Event e2;
-        e2.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,1));
-        e2.setEnd(Kolab::cDateTime("Europe/Zurich",2011,10,10,6,1,2));
-        
-        QTest::newRow( "tz conflict" ) << e1 << e2 << true;
-    }
-}
-
-void KCalConversionTest::testEventConflict()
-{
-//     QFETCH(Kolab::Event, e1);
-//     QFETCH(Kolab::Event, e2);
-//     QFETCH(bool, result);
-//     QCOMPARE(Kolab::Calendaring::conflicts(e1,e2), result);
-}
-
-
-
-void KCalConversionTest::testTimesInInterval_data()
-{
-    QTest::addColumn<Kolab::Event>( "event" );
-    QTest::addColumn<Kolab::cDateTime>( "start" );
-    QTest::addColumn<Kolab::cDateTime>( "end" );
-    QTest::addColumn< std::vector<Kolab::cDateTime> >( "result" );
-    {
-        {
-            Kolab::Event event;
-            event.setStart(Kolab::cDateTime(2011,1,1,1,1,1,true));
-            event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1,true));
-            Kolab::RecurrenceRule rrule;
-            rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-            rrule.setInterval(1);
-            rrule.setCount(5);
-            event.setRecurrenceRule(rrule);
-
-            std::vector<Kolab::cDateTime> result;
-            result.push_back(Kolab::cDateTime(2011,1,1,1,1,1,true)); 
-            result.push_back(Kolab::cDateTime(2011,1,2,1,1,1,true));
-            result.push_back(Kolab::cDateTime(2011,1,3,1,1,1,true)); 
-            result.push_back(Kolab::cDateTime(2011,1,4,1,1,1,true));
-            result.push_back(Kolab::cDateTime(2011,1,5,1,1,1,true)); 
-            QTest::newRow( "simple" ) << event << Kolab::cDateTime(2011,1,1,1,1,1,true) << Kolab::cDateTime(2011,1,5,1,1,1,true) << result;
-        }
-    }
-}
-
-void KCalConversionTest::testTimesInInterval()
-{
-//     QFETCH(Kolab::Event, event);
-//     QFETCH(Kolab::cDateTime, start);
-//     QFETCH(Kolab::cDateTime, end);
-//     QFETCH(std::vector<Kolab::cDateTime>, result);
-//     QCOMPARE(Kolab::Calendaring::timeInInterval(event,start, end), result);
-}
-
-void KCalConversionTest::testTimesInIntervalBenchmark()
-{
-//     Kolab::Event event;
-//     event.setStart(Kolab::cDateTime(2011,1,1,1,1,1));
-//     event.setEnd(Kolab::cDateTime(2011,1,1,2,1,1));
-//     Kolab::RecurrenceRule rrule;
-//     rrule.setFrequency(Kolab::RecurrenceRule::Daily);
-//     rrule.setInterval(1);
-//     rrule.setCount(500);
-//     event.setRecurrenceRule(rrule);
-//     
-//     QBENCHMARK {
-//         Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-//     }
-//     const std::vector<Kolab::cDateTime> &result = Kolab::Calendaring::timeInInterval(event, Kolab::cDateTime(2011,1,1,1,1,1), Kolab::cDateTime(2013,1,1,1,1,1));
-//     QVERIFY(result.size() == 500);
-//     qDebug() << QTest::toString(result);    
-}
-
 // void KCalConversionTest::BenchmarkRoundtripKCAL()
 // {
 //     const Kolab::Event &event = Kolab::readEvent("../../tests/testfiles/icalEvent.xml", true);
diff --git a/tests/kcalconversiontest.h b/tests/kcalconversiontest.h
index b6df3d8..c2ac14e 100644
--- a/tests/kcalconversiontest.h
+++ b/tests/kcalconversiontest.h
@@ -31,12 +31,6 @@ class KCalConversionTest : public QObject
     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/tests/testhelpers.h b/tests/testhelpers.h
new file mode 100644
index 0000000..eece883
--- /dev/null
+++ b/tests/testhelpers.h
@@ -0,0 +1,200 @@
+/*
+ * 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 TESTHELPERS_H
+#define TESTHELPERS_H
+
+#include <contact.h>
+
+#include <QtCore/QObject>
+#include <QtTest/QtTest>
+#include <kcalcore/recurrence.h>
+#include <kabc/addressee.h>
+
+#include <kolabformat.h>
+
+Q_DECLARE_METATYPE(Kolab::Duration);
+Q_DECLARE_METATYPE(Kolab::cDateTime);
+Q_DECLARE_METATYPE(std::vector<Kolab::cDateTime>);
+Q_DECLARE_METATYPE(Kolab::Event);
+Q_DECLARE_METATYPE(std::vector<Kolab::Event>);
+Q_DECLARE_METATYPE(Kolab::Todo);
+Q_DECLARE_METATYPE(Kolab::Journal);
+Q_DECLARE_METATYPE(Kolab::Contact);
+Q_DECLARE_METATYPE(KCalCore::Event);
+Q_DECLARE_METATYPE(KCalCore::Todo);
+Q_DECLARE_METATYPE(KCalCore::Journal);
+Q_DECLARE_METATYPE(KCalCore::Duration);
+
+namespace QTest {
+
+
+    template<>
+    char *toString(const Kolab::cDateTime &dt)
+    {
+        QByteArray ba = "Kolab::cDateTime(";
+        ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", ";
+        ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", ";
+        ba += QString(dt.isUTC()?QString("UTC"):QString("TZ: "+QString::fromStdString(dt.timezone()))).toAscii();
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+    
+    template<>
+    char *toString(const KDateTime &dt)
+    {
+        QByteArray ba = "KDateTime(";
+        ba += dt.toString().toAscii();
+        ba += dt.timeZone().name();
+        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::DateList &l)
+    {
+        QByteArray ba = "KCalCore::DateList(";
+        foreach(const QDate &i, l) {
+            ba += i.toString();
+        }
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+    template<>
+    char *toString(const KCalCore::DateTimeList &l)
+    {
+        QByteArray ba = "KCalCore::DateTimeList(";
+        foreach(const KDateTime &i, l) {
+            ba += toString(i);
+        }
+        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()) + "\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 += ")\n";
+            ba += QByteArray(toString(at.exDates())) + "\n";
+            ba += QByteArray(toString(at.exDateTimes())) + "\n";
+            ba += QByteArray(toString(at.rDates())) + "\n";
+            ba += QByteArray(toString(at.rDateTimes())) + "\n";
+
+        }
+        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<>
+    char *toString(const KCalCore::Duration &d)
+    {
+        QByteArray ba;
+        ba += "KCalCore::Duration(";
+        ba += QString::number(d.isDaily()) + ", ";
+        ba += QString::number(d.value()) + " ";
+        ba += ")";
+        return qstrdup(ba.data());
+    }
+
+
+}
+
+#endif


commit 3b678def0fc5fcb9d808ab866aec134c42196619
Author: Christian Mollekopf <mollekopf at kolabsys.com>
Date:   Mon May 21 11:19:36 2012 +0200

    Set defaults for LIB_INSTALL_DIR and INCLUDE_INSTALL_DIR which can be overridden by commandline definitions.
    
    CMAKE projects should be installable without commandline options, this way we fullfill this basic requirement while still allowing for full control for packagers.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a239ba7..449a453 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,8 @@ set(Libkolab_VERSION ${Libkolab_VERSION_MAJOR}.${Libkolab_VERSION_MINOR} )
 set(Libkolab_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolab_VERSION})
 
 # set up install directories.
+set(LIB_INSTALL_DIR lib CACHE STRING "The directories where to install libraries to")
+set(INCLUDE_INSTALL_DIR include/libkolab CACHE STRING "The directories where to install headers to")
 set(CMAKECONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/cmake/Libkolab )
 
 # Do the building





More information about the commits mailing list