diff options
-rw-r--r-- | include/datetime/date-time.h | 8 | ||||
-rw-r--r-- | src/date-time.cpp | 60 | ||||
-rw-r--r-- | src/planner-month.cpp | 4 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/manual-test-snap.cpp | 2 | ||||
-rw-r--r-- | tests/test-alarm-queue.cpp | 4 | ||||
-rw-r--r-- | tests/test-datetime.cpp | 143 | ||||
-rw-r--r-- | tests/test-live-actions.cpp | 14 | ||||
-rw-r--r-- | tests/test-snap.cpp | 7 |
9 files changed, 208 insertions, 35 deletions
diff --git a/include/datetime/date-time.h b/include/datetime/date-time.h index 8fa1569..7dfc207 100644 --- a/include/datetime/date-time.h +++ b/include/datetime/date-time.h @@ -36,17 +36,21 @@ class DateTime { public: static DateTime NowLocal(); - static DateTime Local(int years, int months, int days, int hours, int minutes, int seconds); + static DateTime Local(int year, int month, int day, int hour, int minute, double seconds); DateTime(); explicit DateTime(time_t t); DateTime(GTimeZone* tz, GDateTime* dt); + DateTime(GTimeZone* tz, int year, int month, int day, int hour, int minute, double seconds); DateTime& operator=(const DateTime& in); DateTime to_timezone(const std::string& zone) const; + DateTime start_of_month() const; DateTime start_of_day() const; DateTime start_of_minute() const; + DateTime end_of_day() const; + DateTime end_of_month() const; DateTime add_days(int days) const; - DateTime add_full(int years, int months, int days, int hours, int minutes, double seconds) const; + DateTime add_full(int year, int month, int day, int hour, int minute, double seconds) const; GDateTime* get() const; GDateTime* operator()() const {return get();} diff --git a/src/date-time.cpp b/src/date-time.cpp index 4176d06..689688c 100644 --- a/src/date-time.cpp +++ b/src/date-time.cpp @@ -39,6 +39,15 @@ DateTime::DateTime(GTimeZone* gtz, GDateTime* gdt) reset(gtz, gdt); } +DateTime::DateTime(GTimeZone* gtz, int year, int month, int day, int hour, int minute, double seconds) +{ + g_return_if_fail(gtz!=nullptr); + + auto gdt = g_date_time_new(gtz, year, month, day, hour, minute, seconds); + reset(gtz, gdt); + g_date_time_unref(gdt); +} + DateTime& DateTime::operator=(const DateTime& that) { m_tz = that.m_tz; @@ -65,13 +74,11 @@ DateTime DateTime::NowLocal() return dt; } -DateTime DateTime::Local(int year, int month, int day, int hour, int minute, int seconds) +DateTime DateTime::Local(int year, int month, int day, int hour, int minute, double seconds) { auto gtz = g_time_zone_new_local(); - auto gdt = g_date_time_new(gtz, year, month, day, hour, minute, seconds); - DateTime dt(gtz, gdt); + DateTime dt(gtz, year, month, day, hour, minute, seconds); g_time_zone_unref(gtz); - g_date_time_unref(gdt); return dt; } @@ -85,33 +92,50 @@ DateTime DateTime::to_timezone(const std::string& zone) const return dt; } +DateTime DateTime::end_of_day() const +{ + g_assert(is_set()); + + return add_days(1).start_of_day().add_full(0,0,0,0,0,-1); +} + +DateTime DateTime::end_of_month() const +{ + g_assert(is_set()); + + return add_full(0,1,0,0,0,0).start_of_month().add_full(0,0,0,0,0,-1); +} + +DateTime DateTime::start_of_month() const +{ + g_assert(is_set()); + + int year=0, month=0, day=0; + ymd(year, month, day); + return DateTime(m_tz.get(), year, month, 1, 0, 0, 0); +} + DateTime DateTime::start_of_day() const { g_assert(is_set()); - int y=0, m=0, d=0; - ymd(y, m, d); - auto gdt = g_date_time_new(m_tz.get(), y, m, d, 0, 0, 0); - DateTime dt(m_tz.get(), gdt); - g_date_time_unref(gdt); - return dt; + int year=0, month=0, day=0; + ymd(year, month, day); + return DateTime(m_tz.get(), year, month, day, 0, 0, 0); } DateTime DateTime::start_of_minute() const { g_assert(is_set()); - int y=0, m=0, d=0; - ymd(y, m, d); - auto gdt = g_date_time_new(m_tz.get(), y, m, d, hour(), minute(), 0); - DateTime dt(m_tz.get(), gdt); - g_date_time_unref(gdt); - return dt; + int year=0, month=0, day=0; + ymd(year, month, day); + return DateTime(m_tz.get(), year, month, day, hour(), minute(), 0); } -DateTime DateTime::add_full(int years, int months, int days, int hours, int minutes, double seconds) const +DateTime DateTime::add_full(int year, int month, int day, int hour, int minute, double seconds) const { - auto gdt = g_date_time_add_full(get(), years, months, days, hours, minutes, seconds); + auto gdt = g_date_time_add_full(get(), year, month, day, hour, minute, seconds); DateTime dt(m_tz.get(), gdt); g_date_time_unref(gdt); return dt; diff --git a/src/planner-month.cpp b/src/planner-month.cpp index fd8a568..cdae26f 100644 --- a/src/planner-month.cpp +++ b/src/planner-month.cpp @@ -32,8 +32,8 @@ MonthPlanner::MonthPlanner(const std::shared_ptr<RangePlanner>& range_planner, m_range_planner(range_planner) { month().changed().connect([this](const DateTime& m){ - auto month_begin = m.start_of_day().add_full(0, 0, -(m.day_of_month()-1), 0, 0, 0); - auto month_end = month_begin.add_full(0, 1, 0, 0, 0, -0.1); + auto month_begin = m.start_of_month(); + auto month_end = m.end_of_month(); g_debug("PlannerMonth %p setting calendar month range: [%s..%s]", this, month_begin.format("%F %T").c_str(), month_end.format("%F %T").c_str()); m_range_planner->range().set(std::pair<DateTime,DateTime>(month_begin,month_end)); }); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 20e744a..25fe5dc 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -47,6 +47,7 @@ function(add_test_by_name name) add_dependencies (${TEST_NAME} libindicatordatetimeservice) target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${DBUSTEST_LIBRARIES} ${SERVICE_DEPS_LIBRARIES} ${GTEST_LIBS}) endfunction() +add_test_by_name(test-datetime) add_test_by_name(test-snap) add_test_by_name(test-actions) add_test_by_name(test-alarm-queue) diff --git a/tests/manual-test-snap.cpp b/tests/manual-test-snap.cpp index 94c1ded..22ef137 100644 --- a/tests/manual-test-snap.cpp +++ b/tests/manual-test-snap.cpp @@ -71,7 +71,7 @@ int main(int argc, const char* argv[]) a.uid = "D4B57D50247291478ED31DED17FF0A9838DED402"; a.type = Appointment::UBUNTU_ALARM; a.begin = DateTime::Local(2014, 12, 25, 0, 0, 0); - a.end = a.begin.add_full(0,0,1,0,0,-1); + a.end = a.begin.end_of_day(); auto loop = g_main_loop_new(nullptr, false); auto on_snooze = [loop](const Appointment& appt){ diff --git a/tests/test-alarm-queue.cpp b/tests/test-alarm-queue.cpp index 0492539..3fdf787 100644 --- a/tests/test-alarm-queue.cpp +++ b/tests/test-alarm-queue.cpp @@ -69,7 +69,7 @@ protected: { const auto now = m_state->clock->localtime(); const auto tomorrow_begin = now.add_days(1).start_of_day(); - const auto tomorrow_end = tomorrow_begin.add_full(0, 0, 1, 0, 0, -1); + const auto tomorrow_end = tomorrow_begin.end_of_day(); Appointment a1; // an alarm clock appointment a1.color = "red"; @@ -81,7 +81,7 @@ protected: a1.end = tomorrow_end; const auto ubermorgen_begin = now.add_days(2).start_of_day(); - const auto ubermorgen_end = ubermorgen_begin.add_full(0, 0, 1, 0, 0, -1); + const auto ubermorgen_end = ubermorgen_begin.end_of_day(); Appointment a2; // a non-alarm appointment a2.color = "green"; diff --git a/tests/test-datetime.cpp b/tests/test-datetime.cpp new file mode 100644 index 0000000..41f78fb --- /dev/null +++ b/tests/test-datetime.cpp @@ -0,0 +1,143 @@ +/* + * Copyright 2015 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Charles Kerr <charles.kerr@canonical.com> + */ + +#include <datetime/date-time.h> + +#include "glib-fixture.h" + +using namespace unity::indicator::datetime; + +/*** +**** +***/ + +class DateTimeFixture: public GlibFixture +{ + public: + + DateTimeFixture() =default; + virtual ~DateTimeFixture() =default; + + private: + + typedef GlibFixture super; + + protected: + + GRand * m_rand = nullptr; + + virtual void SetUp() override + { + super::SetUp(); + + m_rand = g_rand_new(); + } + + virtual void TearDown() override + { + g_clear_pointer(&m_rand, g_rand_free); + + super::TearDown(); + } + + DateTime random_day() + { + return DateTime::Local(g_rand_int_range(m_rand, 1970, 3000), + g_rand_int_range(m_rand, 1, 13), + g_rand_int_range(m_rand, 1, 29), + g_rand_int_range(m_rand, 0, 24), + g_rand_int_range(m_rand, 0, 60), + g_rand_double_range(m_rand, 0, 60.0)); + } +}; + +/*** +**** +***/ + +TEST_F(DateTimeFixture, StartAndEnd) +{ + const int n_iterations{10000}; + + for (int i{0}; i<n_iterations; ++i) + { + const auto day = random_day(); + int dayy{0}, daym{0}, dayd{0}; + day.ymd(dayy, daym, dayd); + + // test start-of-month + auto test = day.start_of_month(); + int testy{0}, testm{0}, testd{0}; + test.ymd(testy, testm, testd); + EXPECT_EQ(dayy, testy); + EXPECT_EQ(daym, testm); + EXPECT_EQ(1, testd); + EXPECT_EQ(0, test.hour()); + EXPECT_EQ(0, test.minute()); + EXPECT_EQ(0, (int)test.seconds()); + + // test start-of-day + test = day.start_of_day(); + testy = -1; + testm = -1; + testd = -1; + test.ymd(testy, testm, testd); + EXPECT_EQ(dayy, testy); + EXPECT_EQ(daym, testm); + EXPECT_EQ(dayd, testd); + EXPECT_EQ(0, test.hour()); + EXPECT_EQ(0, test.minute()); + EXPECT_EQ(0, (int)test.seconds()); + + // test start-of-minute + test = day.start_of_minute(); + testy = -1; + testm = -1; + testd = -1; + test.ymd(testy, testm, testd); + EXPECT_EQ(dayy, testy); + EXPECT_EQ(daym, testm); + EXPECT_EQ(dayd, testd); + EXPECT_EQ(day.hour(), test.hour()); + EXPECT_EQ(day.minute(), test.minute()); + EXPECT_EQ(0, (int)test.seconds()); + + // test end-of-day + test = day.end_of_day(); + testy = -1; + testm = -1; + testd = -1; + test.ymd(testy, testm, testd); + EXPECT_EQ(dayy, testy); + EXPECT_EQ(daym, testm); + EXPECT_EQ(dayd, testd); + EXPECT_EQ(day.add_days(1).start_of_day(), test.add_full(0,0,0,0,0,1)); + + // test end-of-month + test = day.end_of_month(); + testy = -1; + testm = -1; + testd = -1; + test.ymd(testy, testm, testd); + EXPECT_EQ(dayy, testy); + EXPECT_EQ(daym, testm); + EXPECT_EQ(day.add_days(31).start_of_month(), test.add_full(0,0,0,0,0,1)); + } +} + diff --git a/tests/test-live-actions.cpp b/tests/test-live-actions.cpp index 98e9c58..1a34511 100644 --- a/tests/test-live-actions.cpp +++ b/tests/test-live-actions.cpp @@ -386,8 +386,9 @@ TEST_F(LiveActionsFixture, CalendarState) /// Now add appointments to the planner and confirm that the state keeps in sync /// - auto tomorrow_begin = now.add_days(1).start_of_day(); - auto tomorrow_end = tomorrow_begin.add_full(0,0,1,0,0,-1); + auto tomorrow = now.add_days(1); + auto tomorrow_begin = tomorrow.start_of_day(); + auto tomorrow_end = tomorrow.end_of_day(); Appointment a1; a1.color = "green"; a1.summary = "write unit tests"; @@ -396,15 +397,16 @@ TEST_F(LiveActionsFixture, CalendarState) a1.begin = tomorrow_begin; a1.end = tomorrow_end; - auto next_begin = now.add_days(2).start_of_day(); - auto next_end = next_begin.add_days(1); + auto ubermorgen = now.add_days(2); + auto ubermorgen_begin = ubermorgen.start_of_day(); + auto ubermorgen_end = ubermorgen.end_of_day(); Appointment a2; a2.color = "orange"; a2.summary = "code review"; a2.url = "http://www.ubuntu.com/"; a2.uid = "2756ff7de3745bbffd65d2e4779c37c7ca60d843"; - a2.begin = next_begin; - a2.end = next_end; + a2.begin = ubermorgen_begin; + a2.end = ubermorgen_end; m_state->calendar_month->appointments().set(std::vector<Appointment>({a1, a2})); diff --git a/tests/test-snap.cpp b/tests/test-snap.cpp index e7161d3..3dd4501 100644 --- a/tests/test-snap.cpp +++ b/tests/test-snap.cpp @@ -109,10 +109,9 @@ protected: appt.url = "alarm:///hello-world"; appt.uid = "D4B57D50247291478ED31DED17FF0A9838DED402"; appt.type = Appointment::EVENT; - auto begin = DateTime::Local(2014,12,25,0,0,0); - auto end = begin.add_full(0,0,1,0,0,-1); - appt.begin = begin; - appt.end = end; + const auto christmas = DateTime::Local(2015,12,25,0,0,0); + appt.begin = christmas.start_of_day(); + appt.end = christmas.end_of_day(); service = dbus_test_service_new(nullptr); |