aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2015-03-17 15:23:49 +0000
committerCI Train Bot <ci-train-bot@canonical.com>2015-03-17 15:23:49 +0000
commitddde67df581dea8c5a261e43d5b12a3821f06ed1 (patch)
treee3c2859c54b0bba9c72ad221ea41c95ed8f5a70f
parent15ec7f61fa84a9a8b40c1c9fcfa6c2a268d3232b (diff)
parent273c3b3829c9a3e853d0b6b0a32ae87cc3c6852b (diff)
downloadayatana-indicator-datetime-ddde67df581dea8c5a261e43d5b12a3821f06ed1.tar.gz
ayatana-indicator-datetime-ddde67df581dea8c5a261e43d5b12a3821f06ed1.tar.bz2
ayatana-indicator-datetime-ddde67df581dea8c5a261e43d5b12a3821f06ed1.zip
Fix bug that prevented clicking on calendar days where DST sprang forward. Fixes: #1429388
Approved by: Ted Gould, PS Jenkins bot
-rw-r--r--include/datetime/date-time.h20
-rw-r--r--src/actions-live.cpp5
-rw-r--r--src/actions.cpp12
-rw-r--r--src/alarm-queue-simple.cpp2
-rw-r--r--src/clock-live.cpp2
-rw-r--r--src/date-time.cpp113
-rw-r--r--src/menu.cpp4
-rw-r--r--src/planner-month.cpp9
-rw-r--r--src/planner-upcoming.cpp2
-rw-r--r--tests/CMakeLists.txt1
-rw-r--r--tests/manual-test-snap.cpp8
-rw-r--r--tests/test-actions.cpp33
-rw-r--r--tests/test-alarm-queue.cpp19
-rw-r--r--tests/test-datetime.cpp143
-rw-r--r--tests/test-formatter.cpp89
-rw-r--r--tests/test-live-actions.cpp33
-rw-r--r--tests/test-menus.cpp8
-rw-r--r--tests/test-planner.cpp20
-rw-r--r--tests/test-snap.cpp9
19 files changed, 348 insertions, 184 deletions
diff --git a/include/datetime/date-time.h b/include/datetime/date-time.h
index 4be35f7..7dfc207 100644
--- a/include/datetime/date-time.h
+++ b/include/datetime/date-time.h
@@ -36,15 +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);
- explicit DateTime(GDateTime* in=nullptr);
- DateTime& operator=(GDateTime* in);
+ 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 add_full(int years, int months, int days, int hours, int minutes, double seconds) const;
- void reset(GDateTime* in=nullptr);
+ 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 year, int month, int day, int hour, int minute, double seconds) const;
GDateTime* get() const;
GDateTime* operator()() const {return get();}
@@ -66,9 +72,11 @@ public:
static bool is_same_day(const DateTime& a, const DateTime& b);
static bool is_same_minute(const DateTime& a, const DateTime& b);
- bool is_set() const { return m_dt != nullptr; }
+ bool is_set() const { return m_tz && m_dt; }
private:
+ void reset(GTimeZone*, GDateTime*);
+ std::shared_ptr<GTimeZone> m_tz;
std::shared_ptr<GDateTime> m_dt;
};
diff --git a/src/actions-live.cpp b/src/actions-live.cpp
index 7efc2b2..4d1f770 100644
--- a/src/actions-live.cpp
+++ b/src/actions-live.cpp
@@ -119,9 +119,8 @@ void LiveActions::desktop_open_appointment(const Appointment& appt)
void LiveActions::desktop_open_calendar_app(const DateTime& dt)
{
- const auto day_begins = dt.add_full(0, 0, 0, -dt.hour(), -dt.minute(), -dt.seconds());
- const auto gmt = day_begins.to_timezone("UTC");
- auto cmd = gmt.format("evolution \"calendar:///?startdate=%Y%m%dT%H%M%SZ\"");
+ const auto utc = dt.start_of_day().to_timezone("UTC");
+ auto cmd = utc.format("evolution \"calendar:///?startdate=%Y%m%dT%H%M%SZ\"");
execute_command(cmd.c_str());
}
diff --git a/src/actions.cpp b/src/actions.cpp
index 1b665cc..839c9cd 100644
--- a/src/actions.cpp
+++ b/src/actions.cpp
@@ -143,9 +143,7 @@ void on_calendar_activated(GSimpleAction * /*action*/,
g_return_if_fail(t != 0);
- // the client gave us a date; remove the HMS component from the resulting DateTime
- auto dt = DateTime(t);
- dt = dt.add_full (0, 0, 0, -dt.hour(), -dt.minute(), -dt.seconds());
+ auto dt = DateTime(t).start_of_day();
static_cast<Actions*>(gself)->set_calendar_date(dt);
}
@@ -225,18 +223,26 @@ Actions::Actions(const std::shared_ptr<State>& state):
auto v = create_default_header_state();
auto a = g_simple_action_new_stateful("desktop-header", nullptr, v);
g_action_map_add_action(gam, G_ACTION(a));
+ g_object_unref(a);
+
a = g_simple_action_new_stateful("desktop_greeter-header", nullptr, v);
g_action_map_add_action(gam, G_ACTION(a));
+ g_object_unref(a);
+
a = g_simple_action_new_stateful("phone-header", nullptr, v);
g_action_map_add_action(gam, G_ACTION(a));
+ g_object_unref(a);
+
a = g_simple_action_new_stateful("phone_greeter-header", nullptr, v);
g_action_map_add_action(gam, G_ACTION(a));
+ g_object_unref(a);
// add the calendar action
v = create_calendar_state(state);
a = g_simple_action_new_stateful("calendar", G_VARIANT_TYPE_INT64, v);
g_action_map_add_action(gam, G_ACTION(a));
g_signal_connect(a, "activate", G_CALLBACK(on_calendar_activated), this);
+ g_object_unref(a);
///
/// Keep our GActionGroup's action's states in sync with m_state
diff --git a/src/alarm-queue-simple.cpp b/src/alarm-queue-simple.cpp
index fa6c0bc..f45e61a 100644
--- a/src/alarm-queue-simple.cpp
+++ b/src/alarm-queue-simple.cpp
@@ -102,7 +102,7 @@ bool SimpleAlarmQueue::find_next_alarm(Appointment& setme) const
bool found = false;
Appointment tmp;
const auto now = m_clock->localtime();
- const auto beginning_of_minute = now.add_full (0, 0, 0, 0, 0, -now.seconds());
+ const auto beginning_of_minute = now.start_of_minute();
const auto appointments = m_planner->appointments().get();
g_debug ("planner has %zu appointments in it", (size_t)appointments.size());
diff --git a/src/clock-live.cpp b/src/clock-live.cpp
index 7f8bd1b..89541ae 100644
--- a/src/clock-live.cpp
+++ b/src/clock-live.cpp
@@ -68,7 +68,7 @@ public:
g_assert(m_gtimezone != nullptr);
auto gdt = g_date_time_new_now(m_gtimezone);
- DateTime ret(gdt);
+ DateTime ret(m_gtimezone, gdt);
g_date_time_unref(gdt);
return ret;
}
diff --git a/src/date-time.cpp b/src/date-time.cpp
index a139ea9..689688c 100644
--- a/src/date-time.cpp
+++ b/src/date-time.cpp
@@ -27,43 +27,58 @@ namespace datetime {
****
***/
-DateTime::DateTime(GDateTime* gdt)
+DateTime::DateTime()
{
- reset(gdt);
}
-DateTime& DateTime::operator=(GDateTime* gdt)
+DateTime::DateTime(GTimeZone* gtz, GDateTime* gdt)
{
- reset(gdt);
- return *this;
+ g_return_if_fail(gtz!=nullptr);
+ g_return_if_fail(gdt!=nullptr);
+
+ 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;
m_dt = that.m_dt;
return *this;
}
DateTime::DateTime(time_t t)
{
+ auto gtz = g_time_zone_new_local();
auto gdt = g_date_time_new_from_unix_local(t);
- reset(gdt);
+ reset(gtz, gdt);
+ g_time_zone_unref(gtz);
g_date_time_unref(gdt);
}
DateTime DateTime::NowLocal()
{
- auto gdt = g_date_time_new_now_local();
- DateTime dt(gdt);
+ auto gtz = g_time_zone_new_local();
+ auto gdt = g_date_time_new_now(gtz);
+ DateTime dt(gtz, gdt);
+ g_time_zone_unref(gtz);
g_date_time_unref(gdt);
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 gdt = g_date_time_new_local (year, month, day, hour, minute, seconds);
- DateTime dt(gdt);
- g_date_time_unref(gdt);
+ auto gtz = g_time_zone_new_local();
+ DateTime dt(gtz, year, month, day, hour, minute, seconds);
+ g_time_zone_unref(gtz);
return dt;
}
@@ -71,20 +86,66 @@ DateTime DateTime::to_timezone(const std::string& zone) const
{
auto gtz = g_time_zone_new(zone.c_str());
auto gdt = g_date_time_to_timezone(get(), gtz);
- DateTime dt(gdt);
+ DateTime dt(gtz, gdt);
g_time_zone_unref(gtz);
g_date_time_unref(gdt);
return dt;
}
-DateTime DateTime::add_full(int years, int months, int days, int hours, int minutes, double seconds) const
+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 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 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 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);
- DateTime dt(gdt);
+ 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;
}
+DateTime DateTime::add_days(int days) const
+{
+ return add_full(0, 0, days, 0, 0, 0);
+}
+
GDateTime* DateTime::get() const
{
g_assert(m_dt);
@@ -135,18 +196,16 @@ int64_t DateTime::to_unix() const
return g_date_time_to_unix(get());
}
-void DateTime::reset(GDateTime* in)
+void DateTime::reset(GTimeZone* gtz, GDateTime* gdt)
{
- if (in)
- {
- auto deleter = [](GDateTime* dt){g_date_time_unref(dt);};
- m_dt = std::shared_ptr<GDateTime>(g_date_time_ref(in), deleter);
- g_assert(m_dt);
- }
- else
- {
- m_dt.reset();
- }
+ g_return_if_fail (gdt!=nullptr);
+ g_return_if_fail (gtz!=nullptr);
+
+ auto tz_deleter = [](GTimeZone* tz){g_time_zone_unref(tz);};
+ m_tz = std::shared_ptr<GTimeZone>(g_time_zone_ref(gtz), tz_deleter);
+
+ auto dt_deleter = [](GDateTime* dt){g_date_time_unref(dt);};
+ m_dt = std::shared_ptr<GDateTime>(g_date_time_ref(gdt), dt_deleter);
}
bool DateTime::operator<(const DateTime& that) const
diff --git a/src/menu.cpp b/src/menu.cpp
index f11de77..ff894bc 100644
--- a/src/menu.cpp
+++ b/src/menu.cpp
@@ -152,9 +152,9 @@ protected:
const auto now = m_state->clock->localtime();
const auto calendar_day = m_state->calendar_month->month().get();
if ((profile() == Desktop) && !DateTime::is_same_day(now, calendar_day))
- begin = calendar_day.add_full (0, 0, 0, -calendar_day.hour(), -calendar_day.minute(), -calendar_day.seconds());
+ begin = calendar_day.start_of_day();
else
- begin = now.add_full (0, 0, 0, 0, 0, -now.seconds());
+ begin = now.start_of_minute();
std::vector<Appointment> upcoming;
for(const auto& a : m_state->calendar_upcoming->appointments().get())
diff --git a/src/planner-month.cpp b/src/planner-month.cpp
index 5920daa..cdae26f 100644
--- a/src/planner-month.cpp
+++ b/src/planner-month.cpp
@@ -32,13 +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.add_full(0, // no years
- 0, // no months
- -(m.day_of_month()-1),
- -m.hour(),
- -m.minute(),
- -m.seconds());
- 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/src/planner-upcoming.cpp b/src/planner-upcoming.cpp
index ed45955..338329c 100644
--- a/src/planner-upcoming.cpp
+++ b/src/planner-upcoming.cpp
@@ -33,7 +33,7 @@ UpcomingPlanner::UpcomingPlanner(const std::shared_ptr<RangePlanner>& range_plan
{
date().changed().connect([this](const DateTime& dt){
// set the range to the upcoming month
- const auto b = dt.add_full(0, 0, -1, -dt.hour(), -dt.minute(), -dt.seconds());
+ const auto b = dt.add_days(-1).start_of_day();
const auto e = b.add_full(0, 1, 0, 0, 0, 0);
g_debug("%p setting date range to [%s..%s]", this, b.format("%F %T").c_str(), e.format("%F %T").c_str());
m_range_planner->range().set(std::pair<DateTime,DateTime>(b,e));
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 e0aad89..22ef137 100644
--- a/tests/manual-test-snap.cpp
+++ b/tests/manual-test-snap.cpp
@@ -70,12 +70,8 @@ int main(int argc, const char* argv[])
a.url = "alarm:///hello-world";
a.uid = "D4B57D50247291478ED31DED17FF0A9838DED402";
a.type = Appointment::UBUNTU_ALARM;
- auto begin = g_date_time_new_local(2014,12,25,0,0,0);
- auto end = g_date_time_add_full(begin,0,0,1,0,0,-1);
- a.begin = begin;
- a.end = end;
- g_date_time_unref(end);
- g_date_time_unref(begin);
+ a.begin = DateTime::Local(2014, 12, 25, 0, 0, 0);
+ 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-actions.cpp b/tests/test-actions.cpp
index fc89426..2a8e370 100644
--- a/tests/test-actions.cpp
+++ b/tests/test-actions.cpp
@@ -30,9 +30,7 @@ class ActionsFixture: public StateFixture
std::vector<Appointment> build_some_appointments()
{
const auto now = m_state->clock->localtime();
- auto gdt_tomorrow = g_date_time_add_days(now.get(), 1);
- const auto tomorrow = DateTime(gdt_tomorrow);
- g_date_time_unref(gdt_tomorrow);
+ const auto tomorrow = now.add_days(1);
Appointment a1; // an alarm clock appointment
a1.color = "red";
@@ -255,9 +253,7 @@ TEST_F(ActionsFixture, SetCalendarDate)
EXPECT_TRUE(g_action_group_has_action(action_group, action_name));
// pick an arbitrary DateTime...
- auto tmp = g_date_time_new_local(2010, 1, 2, 3, 4, 5);
- const auto now = DateTime(tmp);
- g_date_time_unref(tmp);
+ auto now = DateTime::Local(2010, 1, 2, 3, 4, 5);
// confirm that Planner.time gets changed to that date when we
// activate the 'calendar' action with that date's time_t as the arg
@@ -265,6 +261,18 @@ TEST_F(ActionsFixture, SetCalendarDate)
auto v = g_variant_new_int64(now.to_unix());
g_action_group_activate_action (action_group, action_name, v);
EXPECT_TRUE(DateTime::is_same_day (now, m_state->calendar_month->month().get()));
+
+ // DST change in US
+ now = DateTime::Local(2015, 3, 8, 9, 0, 0);
+ v = g_variant_new_int64(now.to_unix());
+ g_action_group_activate_action (action_group, action_name, v);
+ EXPECT_TRUE(DateTime::is_same_day (now, m_state->calendar_month->month().get()));
+
+ // DST change in Europe
+ now = DateTime::Local(2015, 3, 29, 9, 0, 0);
+ v = g_variant_new_int64(now.to_unix());
+ g_action_group_activate_action (action_group, action_name, v);
+ EXPECT_TRUE(DateTime::is_same_day (now, m_state->calendar_month->month().get()));
}
TEST_F(ActionsFixture, ActivatingTheCalendarResetsItsDate)
@@ -280,16 +288,14 @@ TEST_F(ActionsFixture, ActivatingTheCalendarResetsItsDate)
// move calendar-date a week into the future...
const auto now = m_state->clock->localtime();
- auto next_week = g_date_time_add_weeks(now.get(), 1);
- const auto next_week_unix = g_date_time_to_unix(next_week);
+ const auto next_week = now.add_days(7);
+ const auto next_week_unix = next_week.to_unix();
g_action_group_activate_action (action_group, "calendar", g_variant_new_int64(next_week_unix));
// confirm the planner and calendar action state moved a week into the future
// but that m_state->clock is unchanged
- auto expected = g_date_time_add_full (next_week, 0, 0, 0, -g_date_time_get_hour(next_week),
- -g_date_time_get_minute(next_week),
- -g_date_time_get_seconds(next_week));
- const auto expected_unix = g_date_time_to_unix(expected);
+ auto expected = next_week.start_of_day();
+ const auto expected_unix = expected.to_unix();
EXPECT_EQ(expected_unix, m_state->calendar_month->month().get().to_unix());
EXPECT_EQ(now, m_state->clock->localtime());
auto calendar_state = g_action_group_get_action_state(action_group, "calendar");
@@ -301,9 +307,6 @@ TEST_F(ActionsFixture, ActivatingTheCalendarResetsItsDate)
g_clear_pointer(&v, g_variant_unref);
g_clear_pointer(&calendar_state, g_variant_unref);
- g_date_time_unref(expected);
- g_date_time_unref(next_week);
-
///
/// Now the actual test.
/// We set the state of 'calendar-active' to true, which should reset the calendar date.
diff --git a/tests/test-alarm-queue.cpp b/tests/test-alarm-queue.cpp
index 12ffe92..3fdf787 100644
--- a/tests/test-alarm-queue.cpp
+++ b/tests/test-alarm-queue.cpp
@@ -68,12 +68,8 @@ protected:
std::vector<Appointment> build_some_appointments()
{
const auto now = m_state->clock->localtime();
- auto tomorrow = g_date_time_add_days (now.get(), 1);
- auto tomorrow_begin = g_date_time_add_full (tomorrow, 0, 0, 0,
- -g_date_time_get_hour(tomorrow),
- -g_date_time_get_minute(tomorrow),
- -g_date_time_get_seconds(tomorrow));
- auto tomorrow_end = g_date_time_add_full (tomorrow_begin, 0, 0, 1, 0, 0, -1);
+ const auto tomorrow_begin = now.add_days(1).start_of_day();
+ const auto tomorrow_end = tomorrow_begin.end_of_day();
Appointment a1; // an alarm clock appointment
a1.color = "red";
@@ -84,8 +80,8 @@ protected:
a1.begin = tomorrow_begin;
a1.end = tomorrow_end;
- auto ubermorgen_begin = g_date_time_add_days (tomorrow, 1);
- auto ubermorgen_end = g_date_time_add_full (tomorrow_begin, 0, 0, 1, 0, 0, -1);
+ const auto ubermorgen_begin = now.add_days(2).start_of_day();
+ const auto ubermorgen_end = ubermorgen_begin.end_of_day();
Appointment a2; // a non-alarm appointment
a2.color = "green";
@@ -96,13 +92,6 @@ protected:
a2.begin = ubermorgen_begin;
a2.end = ubermorgen_end;
- // cleanup
- g_date_time_unref(ubermorgen_end);
- g_date_time_unref(ubermorgen_begin);
- g_date_time_unref(tomorrow_end);
- g_date_time_unref(tomorrow_begin);
- g_date_time_unref(tomorrow);
-
return std::vector<Appointment>({a1, a2});
}
};
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-formatter.cpp b/tests/test-formatter.cpp
index d011fea..75c5600 100644
--- a/tests/test-formatter.cpp
+++ b/tests/test-formatter.cpp
@@ -89,9 +89,8 @@ class FormatterFixture: public GlibFixture
*/
TEST_F(FormatterFixture, TestPhoneHeader)
{
- auto now = g_date_time_new_local(2020, 10, 31, 18, 30, 59);
- auto clock = std::make_shared<MockClock>(DateTime(now));
- g_date_time_unref(now);
+ auto now = DateTime::Local(2020, 10, 31, 18, 30, 59);
+ auto clock = std::make_shared<MockClock>(now);
// test the default value in a 24h locale
if(Set24hLocale())
@@ -142,9 +141,8 @@ TEST_F(FormatterFixture, TestDesktopHeader)
{ true, true, true, true, "%a %b %e %Y" EM_SPACE "%l:%M %p" }
};
- auto now = g_date_time_new_local(2020, 10, 31, 18, 30, 59);
- auto clock = std::make_shared<MockClock>(DateTime(now));
- g_date_time_unref(now);
+ auto now = DateTime::Local(2020, 10, 31, 18, 30, 59);
+ auto clock = std::make_shared<MockClock>(now);
for(const auto& test_case : test_cases)
{
@@ -166,45 +164,40 @@ TEST_F(FormatterFixture, TestDesktopHeader)
*/
TEST_F(FormatterFixture, TestUpcomingTimes)
{
- auto a = g_date_time_new_local(2020, 10, 31, 18, 30, 59);
+ auto a = DateTime::Local(2020, 10, 31, 18, 30, 59);
struct {
gboolean is_12h;
- GDateTime* now;
- GDateTime* then;
+ DateTime now;
+ DateTime then;
const char* expected_format_string;
} test_cases[] = {
- { true, g_date_time_ref(a), g_date_time_ref(a), "%l:%M %p" }, // identical time
- { true, g_date_time_ref(a), g_date_time_add_hours(a,1), "%l:%M %p" }, // later today
- { true, g_date_time_ref(a), g_date_time_add_days(a,1), "Tomorrow" EM_SPACE "%l:%M %p" }, // tomorrow
- { true, g_date_time_ref(a), g_date_time_add_days(a,2), "%a" EM_SPACE "%l:%M %p" },
- { true, g_date_time_ref(a), g_date_time_add_days(a,6), "%a" EM_SPACE "%l:%M %p" },
- { true, g_date_time_ref(a), g_date_time_add_days(a,7), "%a %d %b" EM_SPACE "%l:%M %p" }, // over one week away
-
- { false, g_date_time_ref(a), g_date_time_ref(a), "%H:%M" }, // identical time
- { false, g_date_time_ref(a), g_date_time_add_hours(a,1), "%H:%M" }, // later today
- { false, g_date_time_ref(a), g_date_time_add_days(a,1), "Tomorrow" EM_SPACE "%H:%M" }, // tomorrow
- { false, g_date_time_ref(a), g_date_time_add_days(a,2), "%a" EM_SPACE "%H:%M" },
- { false, g_date_time_ref(a), g_date_time_add_days(a,6), "%a" EM_SPACE "%H:%M" },
- { false, g_date_time_ref(a), g_date_time_add_days(a,7), "%a %d %b" EM_SPACE "%H:%M" } // over one week away
+ { true, a, a, "%l:%M %p" }, // identical time
+ { true, a, a.add_full(0,0,0,1,0,0), "%l:%M %p" }, // later today
+ { true, a, a.add_days(1), "Tomorrow" EM_SPACE "%l:%M %p" }, // tomorrow
+ { true, a, a.add_days(2), "%a" EM_SPACE "%l:%M %p" },
+ { true, a, a.add_days(6), "%a" EM_SPACE "%l:%M %p" },
+ { true, a, a.add_days(7), "%a %d %b" EM_SPACE "%l:%M %p" }, // over one week away
+
+ { false, a, a, "%H:%M" }, // identical time
+ { false, a, a.add_full(0,0,0,1,0,0), "%H:%M" }, // later today
+ { false, a, a.add_days(1), "Tomorrow" EM_SPACE "%H:%M" }, // tomorrow
+ { false, a, a.add_days(2), "%a" EM_SPACE "%H:%M" },
+ { false, a, a.add_days(6), "%a" EM_SPACE "%H:%M" },
+ { false, a, a.add_days(7), "%a %d %b" EM_SPACE "%H:%M" } // over one week away
};
for(const auto& test_case : test_cases)
{
if (test_case.is_12h ? Set12hLocale() : Set24hLocale())
{
- auto clock = std::make_shared<MockClock>(DateTime(test_case.now));
+ auto clock = std::make_shared<MockClock>(test_case.now);
DesktopFormatter f(clock, m_settings);
- const auto fmt = f.relative_format(test_case.then);
+ const auto fmt = f.relative_format(test_case.then.get());
ASSERT_EQ(test_case.expected_format_string, fmt);
-
- g_clear_pointer(&test_case.now, g_date_time_unref);
- g_clear_pointer(&test_case.then, g_date_time_unref);
}
}
-
- g_date_time_unref(a);
}
@@ -213,44 +206,34 @@ TEST_F(FormatterFixture, TestUpcomingTimes)
*/
TEST_F(FormatterFixture, TestEventTimes)
{
- auto day = g_date_time_new_local(2013, 1, 1, 13, 0, 0);
- auto day_begin = g_date_time_new_local(2013, 1, 1, 13, 0, 0);
- auto day_end = g_date_time_add_days(day_begin, 1);
- auto tomorrow_begin = g_date_time_add_days(day_begin, 1);
- auto tomorrow_end = g_date_time_add_days(tomorrow_begin, 1);
+ auto day = DateTime::Local(2013, 1, 1, 13, 0, 0);
+ auto day_begin = DateTime::Local(2013, 1, 1, 13, 0, 0);
+ auto day_end = day_begin.add_days(1);
+ auto tomorrow_begin = day_begin.add_days(1);
+ auto tomorrow_end = tomorrow_begin.add_days(1);
struct {
bool is_12h;
- GDateTime* now;
- GDateTime* then;
- GDateTime* then_end;
+ DateTime now;
+ DateTime then;
+ DateTime then_end;
const char* expected_format_string;
} test_cases[] = {
- { false, g_date_time_ref(day), g_date_time_ref(day_begin), g_date_time_ref(day_end), _("Today") },
- { true, g_date_time_ref(day), g_date_time_ref(day_begin), g_date_time_ref(day_end), _("Today") },
- { false, g_date_time_ref(day), g_date_time_ref(tomorrow_begin), g_date_time_ref(tomorrow_end), _("Tomorrow") },
- { true, g_date_time_ref(day), g_date_time_ref(tomorrow_begin), g_date_time_ref(tomorrow_end), _("Tomorrow") }
+ { false, day, day_begin, day_end, _("Today") },
+ { true, day, day_begin, day_end, _("Today") },
+ { false, day, tomorrow_begin, tomorrow_end, _("Tomorrow") },
+ { true, day, tomorrow_begin, tomorrow_end, _("Tomorrow") }
};
for(const auto& test_case : test_cases)
{
if (test_case.is_12h ? Set12hLocale() : Set24hLocale())
{
- auto clock = std::make_shared<MockClock>(DateTime(test_case.now));
+ auto clock = std::make_shared<MockClock>(test_case.now);
DesktopFormatter f(clock, m_settings);
- const auto fmt = f.relative_format(test_case.then, test_case.then_end);
+ const auto fmt = f.relative_format(test_case.then.get(), test_case.then_end.get());
ASSERT_STREQ(test_case.expected_format_string, fmt.c_str());
-
- g_clear_pointer(&test_case.now, g_date_time_unref);
- g_clear_pointer(&test_case.then, g_date_time_unref);
- g_clear_pointer(&test_case.then_end, g_date_time_unref);
}
}
-
- g_date_time_unref(tomorrow_end);
- g_date_time_unref(tomorrow_begin);
- g_date_time_unref(day_end);
- g_date_time_unref(day_begin);
- g_date_time_unref(day);
}
diff --git a/tests/test-live-actions.cpp b/tests/test-live-actions.cpp
index 1197e3e..1a34511 100644
--- a/tests/test-live-actions.cpp
+++ b/tests/test-live-actions.cpp
@@ -346,9 +346,7 @@ TEST_F(LiveActionsFixture, PhoneOpenSettingsApp)
TEST_F(LiveActionsFixture, CalendarState)
{
// init the clock
- auto tmp = g_date_time_new_local (2014, 1, 1, 0, 0, 0);
- const DateTime now (tmp);
- g_date_time_unref (tmp);
+ auto now = DateTime::Local(2014, 1, 1, 0, 0, 0);
m_mock_state->mock_clock->set_localtime (now);
m_state->calendar_month->month().set(now);
//m_state->planner->time.set(now);
@@ -388,12 +386,9 @@ TEST_F(LiveActionsFixture, CalendarState)
/// Now add appointments to the planner and confirm that the state keeps in sync
///
- auto tomorrow = g_date_time_add_days (now.get(), 1);
- auto tomorrow_begin = g_date_time_add_full (tomorrow, 0, 0, 0,
- -g_date_time_get_hour(tomorrow),
- -g_date_time_get_minute(tomorrow),
- -g_date_time_get_seconds(tomorrow));
- auto tomorrow_end = g_date_time_add_full (tomorrow_begin, 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";
@@ -402,15 +397,16 @@ TEST_F(LiveActionsFixture, CalendarState)
a1.begin = tomorrow_begin;
a1.end = tomorrow_end;
- auto next_begin = g_date_time_add_days (tomorrow_begin, 1);
- auto next_end = g_date_time_add_full (next_begin, 0, 0, 1, 0, 0, -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}));
@@ -424,19 +420,12 @@ TEST_F(LiveActionsFixture, CalendarState)
EXPECT_TRUE (v != nullptr);
int i;
g_variant_get_child (v, 0, "i", &i);
- EXPECT_EQ (g_date_time_get_day_of_month(a1.begin.get()), i);
+ EXPECT_EQ (a1.begin.day_of_month(), i);
g_variant_get_child (v, 1, "i", &i);
- EXPECT_EQ (g_date_time_get_day_of_month(a2.begin.get()), i);
+ EXPECT_EQ (a2.begin.day_of_month(), i);
g_clear_pointer(&v, g_variant_unref);
g_clear_pointer(&calendar_state, g_variant_unref);
- // cleanup this step
- g_date_time_unref (next_end);
- g_date_time_unref (next_begin);
- g_date_time_unref (tomorrow_end);
- g_date_time_unref (tomorrow_begin);
- g_date_time_unref (tomorrow);
-
///
/// Confirm that the action state's dictionary
/// keeps in sync with settings.show_week_numbers
diff --git a/tests/test-menus.cpp b/tests/test-menus.cpp
index e0e63ac..fb9c50a 100644
--- a/tests/test-menus.cpp
+++ b/tests/test-menus.cpp
@@ -151,9 +151,7 @@ protected:
// now change the clock and see if the date label changes appropriately
- auto gdt_tomorrow = g_date_time_add_days(now.get(), 1);
- auto tomorrow = DateTime(gdt_tomorrow);
- g_date_time_unref(gdt_tomorrow);
+ auto tomorrow = now.add_days(1).start_of_day();
m_mock_state->mock_clock->set_localtime(tomorrow);
wait_msec();
@@ -182,9 +180,7 @@ private:
std::vector<Appointment> build_some_appointments()
{
const auto now = m_state->clock->localtime();
- auto gdt_tomorrow = g_date_time_add_days(now.get(), 1);
- const auto tomorrow = DateTime(gdt_tomorrow);
- g_date_time_unref(gdt_tomorrow);
+ const auto tomorrow = now.add_days(1);
Appointment a1; // an alarm clock appointment
a1.color = "red";
diff --git a/tests/test-planner.cpp b/tests/test-planner.cpp
index 8f1590c..1e8ac66 100644
--- a/tests/test-planner.cpp
+++ b/tests/test-planner.cpp
@@ -39,30 +39,30 @@ typedef GlibFixture PlannerFixture;
TEST_F(PlannerFixture, HelloWorld)
{
- auto halloween = g_date_time_new_local(2020, 10, 31, 18, 30, 59);
- auto christmas = g_date_time_new_local(2020, 12, 25, 0, 0, 0);
+ auto halloween = DateTime::Local(2020, 10, 31, 18, 30, 59);
+ auto christmas = DateTime::Local(2020, 12, 25, 0, 0, 0);
Appointment a;
a.summary = "Test";
a.begin = halloween;
- a.end = g_date_time_add_hours(halloween, 1);
+ a.end = a.begin.add_full(0,0,0,1,0,0);
const Appointment b = a;
a.summary = "Foo";
EXPECT_EQ(a.summary, "Foo");
EXPECT_EQ(b.summary, "Test");
- EXPECT_EQ(0, g_date_time_compare(a.begin(), b.begin()));
- EXPECT_EQ(0, g_date_time_compare(a.end(), b.end()));
+ EXPECT_EQ(a.begin, b.begin);
+ EXPECT_EQ(a.end, b.end);
Appointment c;
c.begin = christmas;
- c.end = g_date_time_add_hours(christmas, 1);
+ c.end = c.begin.add_days(1);
Appointment d;
d = c;
- EXPECT_EQ(0, g_date_time_compare(c.begin(), d.begin()));
- EXPECT_EQ(0, g_date_time_compare(c.end(), d.end()));
+ EXPECT_EQ(c.begin, d.begin);
+ EXPECT_EQ(c.end, d.end);
a = d;
- EXPECT_EQ(0, g_date_time_compare(d.begin(), a.begin()));
- EXPECT_EQ(0, g_date_time_compare(d.end(), a.end()));
+ EXPECT_EQ(d.begin, a.begin);
+ EXPECT_EQ(d.end, a.end);
}
diff --git a/tests/test-snap.cpp b/tests/test-snap.cpp
index 972c493..3dd4501 100644
--- a/tests/test-snap.cpp
+++ b/tests/test-snap.cpp
@@ -109,12 +109,9 @@ protected:
appt.url = "alarm:///hello-world";
appt.uid = "D4B57D50247291478ED31DED17FF0A9838DED402";
appt.type = Appointment::EVENT;
- auto begin = g_date_time_new_local(2014,12,25,0,0,0);
- auto end = g_date_time_add_full(begin,0,0,1,0,0,-1);
- appt.begin = begin;
- appt.end = end;
- g_date_time_unref(end);
- g_date_time_unref(begin);
+ 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);