From dd41db685c518acab1c8e3676f4292f66e4d0476 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 22 Jan 2014 09:06:01 -0600 Subject: copyediting: rename the test/ directory's .cc files to .cpp for consistency with src/ --- tests/CMakeLists.txt | 4 +- tests/test-actions.cc | 173 ----------------- tests/test-actions.cpp | 173 +++++++++++++++++ tests/test-clock.cc | 144 -------------- tests/test-clock.cpp | 144 ++++++++++++++ tests/test-exporter.cc | 128 ------------- tests/test-exporter.cpp | 128 +++++++++++++ tests/test-formatter.cc | 256 ------------------------- tests/test-formatter.cpp | 256 +++++++++++++++++++++++++ tests/test-live-actions.cpp | 289 +++++++++++++++++++++++++++++ tests/test-locations.cc | 169 ----------------- tests/test-locations.cpp | 169 +++++++++++++++++ tests/test-menus.cc | 402 ---------------------------------------- tests/test-menus.cpp | 402 ++++++++++++++++++++++++++++++++++++++++ tests/test-planner.cc | 85 --------- tests/test-planner.cpp | 85 +++++++++ tests/test-settings.cc | 197 -------------------- tests/test-settings.cpp | 197 ++++++++++++++++++++ tests/test-timezone-file.cc | 133 ------------- tests/test-timezone-file.cpp | 133 +++++++++++++ tests/test-timezone-geoclue.cc | 97 ---------- tests/test-timezone-geoclue.cpp | 97 ++++++++++ tests/test-timezones.cc | 124 ------------- tests/test-timezones.cpp | 124 +++++++++++++ tests/test-utils.cc | 74 -------- tests/test-utils.cpp | 74 ++++++++ 26 files changed, 2273 insertions(+), 1984 deletions(-) delete mode 100644 tests/test-actions.cc create mode 100644 tests/test-actions.cpp delete mode 100644 tests/test-clock.cc create mode 100644 tests/test-clock.cpp delete mode 100644 tests/test-exporter.cc create mode 100644 tests/test-exporter.cpp delete mode 100644 tests/test-formatter.cc create mode 100644 tests/test-formatter.cpp create mode 100644 tests/test-live-actions.cpp delete mode 100644 tests/test-locations.cc create mode 100644 tests/test-locations.cpp delete mode 100644 tests/test-menus.cc create mode 100644 tests/test-menus.cpp delete mode 100644 tests/test-planner.cc create mode 100644 tests/test-planner.cpp delete mode 100644 tests/test-settings.cc create mode 100644 tests/test-settings.cpp delete mode 100644 tests/test-timezone-file.cc create mode 100644 tests/test-timezone-file.cpp delete mode 100644 tests/test-timezone-geoclue.cc create mode 100644 tests/test-timezone-geoclue.cpp delete mode 100644 tests/test-timezones.cc create mode 100644 tests/test-timezones.cpp delete mode 100644 tests/test-utils.cc create mode 100644 tests/test-utils.cpp (limited to 'tests') diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c8dd6aa..c909e0e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,7 +35,7 @@ add_definitions (-DSANDBOX="${CMAKE_CURRENT_BINARY_DIR}") function(add_test_by_name name) set (TEST_NAME ${name}) - add_executable (${TEST_NAME} ${TEST_NAME}.cc) + add_executable (${TEST_NAME} ${TEST_NAME}.cpp) add_test (${TEST_NAME} ${TEST_NAME}) add_dependencies (${TEST_NAME} libindicatordatetimeservice) target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${SERVICE_DEPS_LIBRARIES} ${GTEST_LIBS}) @@ -55,7 +55,7 @@ add_test_by_name(test-utils) function(add_dbusmock_test_by_name name) set (TEST_NAME ${name}) - add_executable (${TEST_NAME} ${TEST_NAME}.cc) + add_executable (${TEST_NAME} ${TEST_NAME}.cpp) add_test (${TEST_NAME} ${TEST_NAME}) add_dependencies (${TEST_NAME} libindicatordatetimeservice) target_link_libraries (${TEST_NAME} indicatordatetimeservice gtest ${SERVICE_DEPS_LIBRARIES} ${DBUSTEST_LIBRARIES} ${GTEST_LIBS}) diff --git a/tests/test-actions.cc b/tests/test-actions.cc deleted file mode 100644 index 4329608..0000000 --- a/tests/test-actions.cc +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - -#include - -#include "state-fixture.h" - -using namespace unity::indicator::datetime; - -typedef StateFixture ActionsFixture; - -TEST_F(ActionsFixture, ActionsExist) -{ - EXPECT_TRUE(m_actions != nullptr); - - const char* names[] = { "desktop-header", - "calendar", - "set-location", - "activate-planner", - "activate-appointment", - "activate-phone-settings", - "activate-phone-clock-app", - "activate-desktop-settings" }; - for(const auto& name: names) - { - EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), name)); - } -} - -TEST_F(ActionsFixture, ActivateDesktopSettings) -{ - const auto action_name = "activate-desktop-settings"; - const auto expected_action = MockActions::OpenDesktopSettings; - - auto action_group = m_actions->action_group(); - auto history = m_mock_actions->history(); - EXPECT_EQ(0, history.size()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - g_action_group_activate_action(action_group, action_name, nullptr); - history = m_mock_actions->history(); - EXPECT_EQ(1, history.size()); - EXPECT_EQ(expected_action, history[0]); -} - -TEST_F(ActionsFixture, ActivatePhoneSettings) -{ - const auto action_name = "activate-phone-settings"; - const auto expected_action = MockActions::OpenPhoneSettings; - - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - g_action_group_activate_action(action_group, action_name, nullptr); - auto history = m_mock_actions->history(); - EXPECT_EQ(1, history.size()); - EXPECT_EQ(expected_action, history[0]); -} - -TEST_F(ActionsFixture, ActivatePhoneClockApp) -{ - const auto action_name = "activate-phone-clock-app"; - const auto expected_action = MockActions::OpenPhoneClockApp; - - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - g_action_group_activate_action(action_group, action_name, nullptr); - auto history = m_mock_actions->history(); - EXPECT_EQ(1, history.size()); - EXPECT_EQ(expected_action, history[0]); -} - -TEST_F(ActionsFixture, ActivatePlanner) -{ - const auto action_name = "activate-planner"; - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - const auto expected_action = MockActions::OpenPlanner; - auto v = g_variant_new_int64(0); - g_action_group_activate_action(action_group, action_name, v); - auto history = m_mock_actions->history(); - EXPECT_EQ(1, history.size()); - EXPECT_EQ(expected_action, history[0]); -} - -TEST_F(ActionsFixture, ActivatePlannerAt) -{ - const auto action_name = "activate-planner"; - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - const auto now = DateTime::NowLocal(); - auto v = g_variant_new_int64(now.to_unix()); - g_action_group_activate_action(action_group, action_name, v); - const auto a = MockActions::OpenPlannerAt; - EXPECT_EQ(std::vector({a}), m_mock_actions->history()); - EXPECT_EQ(now.to_unix(), m_mock_actions->date_time().to_unix()); -} - -TEST_F(ActionsFixture, SetLocation) -{ - const auto action_name = "set-location"; - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - auto v = g_variant_new_string("America/Chicago Oklahoma City"); - g_action_group_activate_action(action_group, action_name, v); - const auto expected_action = MockActions::SetLocation; - ASSERT_EQ(1, m_mock_actions->history().size()); - EXPECT_EQ(expected_action, m_mock_actions->history()[0]); - EXPECT_EQ("America/Chicago", m_mock_actions->zone()); - EXPECT_EQ("Oklahoma City", m_mock_actions->name()); -} - -TEST_F(ActionsFixture, SetCalendarDate) -{ - const auto action_name = "calendar"; - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - auto unix = m_state->clock->localtime().to_unix(); - auto v = g_variant_new_int64(unix); - g_action_group_activate_action(action_group, action_name, v); - const auto expected_action = MockActions::SetCalendarDate; - ASSERT_EQ(1, m_mock_actions->history().size()); - EXPECT_EQ(expected_action, m_mock_actions->history()[0]); - EXPECT_EQ(unix, m_mock_actions->date_time().to_unix()); -} - -TEST_F(ActionsFixture, OpenAppointment) -{ - Appointment appt; - appt.uid = "some arbitrary uid"; - appt.url = "http://www.canonical.com/"; - m_state->planner->upcoming.set(std::vector({appt})); - - const auto action_name = "activate-appointment"; - auto action_group = m_actions->action_group(); - EXPECT_TRUE(m_mock_actions->history().empty()); - EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); - - auto v = g_variant_new_string(appt.uid.c_str()); - g_action_group_activate_action(action_group, action_name, v); - const auto a = MockActions::OpenAppointment; - ASSERT_EQ(1, m_mock_actions->history().size()); - ASSERT_EQ(a, m_mock_actions->history()[0]); - EXPECT_EQ(appt.url, m_mock_actions->url()); -} - diff --git a/tests/test-actions.cpp b/tests/test-actions.cpp new file mode 100644 index 0000000..4329608 --- /dev/null +++ b/tests/test-actions.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include + +#include "state-fixture.h" + +using namespace unity::indicator::datetime; + +typedef StateFixture ActionsFixture; + +TEST_F(ActionsFixture, ActionsExist) +{ + EXPECT_TRUE(m_actions != nullptr); + + const char* names[] = { "desktop-header", + "calendar", + "set-location", + "activate-planner", + "activate-appointment", + "activate-phone-settings", + "activate-phone-clock-app", + "activate-desktop-settings" }; + for(const auto& name: names) + { + EXPECT_TRUE(g_action_group_has_action(m_actions->action_group(), name)); + } +} + +TEST_F(ActionsFixture, ActivateDesktopSettings) +{ + const auto action_name = "activate-desktop-settings"; + const auto expected_action = MockActions::OpenDesktopSettings; + + auto action_group = m_actions->action_group(); + auto history = m_mock_actions->history(); + EXPECT_EQ(0, history.size()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + g_action_group_activate_action(action_group, action_name, nullptr); + history = m_mock_actions->history(); + EXPECT_EQ(1, history.size()); + EXPECT_EQ(expected_action, history[0]); +} + +TEST_F(ActionsFixture, ActivatePhoneSettings) +{ + const auto action_name = "activate-phone-settings"; + const auto expected_action = MockActions::OpenPhoneSettings; + + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + g_action_group_activate_action(action_group, action_name, nullptr); + auto history = m_mock_actions->history(); + EXPECT_EQ(1, history.size()); + EXPECT_EQ(expected_action, history[0]); +} + +TEST_F(ActionsFixture, ActivatePhoneClockApp) +{ + const auto action_name = "activate-phone-clock-app"; + const auto expected_action = MockActions::OpenPhoneClockApp; + + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + g_action_group_activate_action(action_group, action_name, nullptr); + auto history = m_mock_actions->history(); + EXPECT_EQ(1, history.size()); + EXPECT_EQ(expected_action, history[0]); +} + +TEST_F(ActionsFixture, ActivatePlanner) +{ + const auto action_name = "activate-planner"; + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + const auto expected_action = MockActions::OpenPlanner; + auto v = g_variant_new_int64(0); + g_action_group_activate_action(action_group, action_name, v); + auto history = m_mock_actions->history(); + EXPECT_EQ(1, history.size()); + EXPECT_EQ(expected_action, history[0]); +} + +TEST_F(ActionsFixture, ActivatePlannerAt) +{ + const auto action_name = "activate-planner"; + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + const auto now = DateTime::NowLocal(); + auto v = g_variant_new_int64(now.to_unix()); + g_action_group_activate_action(action_group, action_name, v); + const auto a = MockActions::OpenPlannerAt; + EXPECT_EQ(std::vector({a}), m_mock_actions->history()); + EXPECT_EQ(now.to_unix(), m_mock_actions->date_time().to_unix()); +} + +TEST_F(ActionsFixture, SetLocation) +{ + const auto action_name = "set-location"; + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + auto v = g_variant_new_string("America/Chicago Oklahoma City"); + g_action_group_activate_action(action_group, action_name, v); + const auto expected_action = MockActions::SetLocation; + ASSERT_EQ(1, m_mock_actions->history().size()); + EXPECT_EQ(expected_action, m_mock_actions->history()[0]); + EXPECT_EQ("America/Chicago", m_mock_actions->zone()); + EXPECT_EQ("Oklahoma City", m_mock_actions->name()); +} + +TEST_F(ActionsFixture, SetCalendarDate) +{ + const auto action_name = "calendar"; + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + auto unix = m_state->clock->localtime().to_unix(); + auto v = g_variant_new_int64(unix); + g_action_group_activate_action(action_group, action_name, v); + const auto expected_action = MockActions::SetCalendarDate; + ASSERT_EQ(1, m_mock_actions->history().size()); + EXPECT_EQ(expected_action, m_mock_actions->history()[0]); + EXPECT_EQ(unix, m_mock_actions->date_time().to_unix()); +} + +TEST_F(ActionsFixture, OpenAppointment) +{ + Appointment appt; + appt.uid = "some arbitrary uid"; + appt.url = "http://www.canonical.com/"; + m_state->planner->upcoming.set(std::vector({appt})); + + const auto action_name = "activate-appointment"; + auto action_group = m_actions->action_group(); + EXPECT_TRUE(m_mock_actions->history().empty()); + EXPECT_TRUE(g_action_group_has_action(action_group, action_name)); + + auto v = g_variant_new_string(appt.uid.c_str()); + g_action_group_activate_action(action_group, action_name, v); + const auto a = MockActions::OpenAppointment; + ASSERT_EQ(1, m_mock_actions->history().size()); + ASSERT_EQ(a, m_mock_actions->history()[0]); + EXPECT_EQ(appt.url, m_mock_actions->url()); +} + diff --git a/tests/test-clock.cc b/tests/test-clock.cc deleted file mode 100644 index 142ccad..0000000 --- a/tests/test-clock.cc +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - -#include -#include - -#include "test-dbus-fixture.h" - -/*** -**** -***/ - -using namespace unity::indicator::datetime; - -class ClockFixture: public TestDBusFixture -{ - private: - typedef TestDBusFixture super; - - public: - void emitPrepareForSleep() - { - g_dbus_connection_emit_signal(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr), - NULL, - "/org/freedesktop/login1", // object path - "org.freedesktop.login1.Manager", // interface - "PrepareForSleep", // signal name - g_variant_new("(b)", FALSE), - NULL); - } -}; - -/** - * Confirm that normal time passing doesn't trigger a skew event. - * that idling changing the clock's time triggers a skew event - */ -TEST_F(ClockFixture, IdleDoesNotTriggerSkew) -{ - std::shared_ptr zones(new Timezones); - zones->timezone.set("America/New_York"); - LiveClock clock(zones); - wait_msec(500); // wait for the bus to set up - - bool skewed = false; - clock.skewDetected.connect([&skewed](){ - skewed = true; - g_warn_if_reached(); - return G_SOURCE_REMOVE; - }); - - const unsigned int intervalSec = 3; - clock.skewTestIntervalSec.set(intervalSec); - wait_msec(intervalSec * 2.5 * 1000); - EXPECT_FALSE(skewed); -} - -/*** -**** -***/ - -#define TIMEZONE_FILE (SANDBOX"/timezone") - -TEST_F(ClockFixture, HelloFixture) -{ - std::shared_ptr zones(new Timezones); - zones->timezone.set("America/New_York"); - LiveClock clock(zones); -} - - -TEST_F(ClockFixture, TimezoneChangeTriggersSkew) -{ - std::shared_ptr zones(new Timezones); - zones->timezone.set("America/New_York"); - LiveClock clock(zones); - - auto tz_nyc = g_time_zone_new("America/New_York"); - auto now_nyc = g_date_time_new_now(tz_nyc); - auto now = clock.localtime(); - EXPECT_EQ(g_date_time_get_utc_offset(now_nyc), g_date_time_get_utc_offset(now.get())); - EXPECT_LE(abs(g_date_time_difference(now_nyc,now.get())), G_USEC_PER_SEC); - g_date_time_unref(now_nyc); - g_time_zone_unref(tz_nyc); - - /// change the timezones! - clock.skewDetected.connect([this](){ - g_main_loop_quit(loop); - }); - g_idle_add([](gpointer gs){ - static_cast(gs)->timezone.set("America/Los_Angeles"); - return G_SOURCE_REMOVE; - }, zones.get()); - g_main_loop_run(loop); - - auto tz_la = g_time_zone_new("America/Los_Angeles"); - auto now_la = g_date_time_new_now(tz_la); - now = clock.localtime(); - EXPECT_EQ(g_date_time_get_utc_offset(now_la), g_date_time_get_utc_offset(now.get())); - EXPECT_LE(abs(g_date_time_difference(now_la,now.get())), G_USEC_PER_SEC); - g_date_time_unref(now_la); - g_time_zone_unref(tz_la); -} - -/** - * Confirm that a "PrepareForSleep" event wil trigger a skew event - */ -TEST_F(ClockFixture, SleepTriggersSkew) -{ - std::shared_ptr zones(new Timezones); - zones->timezone.set("America/New_York"); - LiveClock clock(zones); - wait_msec(500); // wait for the bus to set up - - bool skewed = false; - clock.skewDetected.connect([&skewed, this](){ - skewed = true; - g_main_loop_quit(loop); - return G_SOURCE_REMOVE; - }); - - g_idle_add([](gpointer gself){ - static_cast(gself)->emitPrepareForSleep(); - return G_SOURCE_REMOVE; - }, this); - - g_main_loop_run(loop); - EXPECT_TRUE(skewed); -} diff --git a/tests/test-clock.cpp b/tests/test-clock.cpp new file mode 100644 index 0000000..142ccad --- /dev/null +++ b/tests/test-clock.cpp @@ -0,0 +1,144 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include +#include + +#include "test-dbus-fixture.h" + +/*** +**** +***/ + +using namespace unity::indicator::datetime; + +class ClockFixture: public TestDBusFixture +{ + private: + typedef TestDBusFixture super; + + public: + void emitPrepareForSleep() + { + g_dbus_connection_emit_signal(g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr), + NULL, + "/org/freedesktop/login1", // object path + "org.freedesktop.login1.Manager", // interface + "PrepareForSleep", // signal name + g_variant_new("(b)", FALSE), + NULL); + } +}; + +/** + * Confirm that normal time passing doesn't trigger a skew event. + * that idling changing the clock's time triggers a skew event + */ +TEST_F(ClockFixture, IdleDoesNotTriggerSkew) +{ + std::shared_ptr zones(new Timezones); + zones->timezone.set("America/New_York"); + LiveClock clock(zones); + wait_msec(500); // wait for the bus to set up + + bool skewed = false; + clock.skewDetected.connect([&skewed](){ + skewed = true; + g_warn_if_reached(); + return G_SOURCE_REMOVE; + }); + + const unsigned int intervalSec = 3; + clock.skewTestIntervalSec.set(intervalSec); + wait_msec(intervalSec * 2.5 * 1000); + EXPECT_FALSE(skewed); +} + +/*** +**** +***/ + +#define TIMEZONE_FILE (SANDBOX"/timezone") + +TEST_F(ClockFixture, HelloFixture) +{ + std::shared_ptr zones(new Timezones); + zones->timezone.set("America/New_York"); + LiveClock clock(zones); +} + + +TEST_F(ClockFixture, TimezoneChangeTriggersSkew) +{ + std::shared_ptr zones(new Timezones); + zones->timezone.set("America/New_York"); + LiveClock clock(zones); + + auto tz_nyc = g_time_zone_new("America/New_York"); + auto now_nyc = g_date_time_new_now(tz_nyc); + auto now = clock.localtime(); + EXPECT_EQ(g_date_time_get_utc_offset(now_nyc), g_date_time_get_utc_offset(now.get())); + EXPECT_LE(abs(g_date_time_difference(now_nyc,now.get())), G_USEC_PER_SEC); + g_date_time_unref(now_nyc); + g_time_zone_unref(tz_nyc); + + /// change the timezones! + clock.skewDetected.connect([this](){ + g_main_loop_quit(loop); + }); + g_idle_add([](gpointer gs){ + static_cast(gs)->timezone.set("America/Los_Angeles"); + return G_SOURCE_REMOVE; + }, zones.get()); + g_main_loop_run(loop); + + auto tz_la = g_time_zone_new("America/Los_Angeles"); + auto now_la = g_date_time_new_now(tz_la); + now = clock.localtime(); + EXPECT_EQ(g_date_time_get_utc_offset(now_la), g_date_time_get_utc_offset(now.get())); + EXPECT_LE(abs(g_date_time_difference(now_la,now.get())), G_USEC_PER_SEC); + g_date_time_unref(now_la); + g_time_zone_unref(tz_la); +} + +/** + * Confirm that a "PrepareForSleep" event wil trigger a skew event + */ +TEST_F(ClockFixture, SleepTriggersSkew) +{ + std::shared_ptr zones(new Timezones); + zones->timezone.set("America/New_York"); + LiveClock clock(zones); + wait_msec(500); // wait for the bus to set up + + bool skewed = false; + clock.skewDetected.connect([&skewed, this](){ + skewed = true; + g_main_loop_quit(loop); + return G_SOURCE_REMOVE; + }); + + g_idle_add([](gpointer gself){ + static_cast(gself)->emitPrepareForSleep(); + return G_SOURCE_REMOVE; + }, this); + + g_main_loop_run(loop); + EXPECT_TRUE(skewed); +} diff --git a/tests/test-exporter.cc b/tests/test-exporter.cc deleted file mode 100644 index ea62cd3..0000000 --- a/tests/test-exporter.cc +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - -#include "actions-mock.h" -#include "state-mock.h" -#include "glib-fixture.h" - -#include -#include -#include - -#include -#include - -using namespace unity::indicator::datetime; - -class ExporterFixture: public GlibFixture -{ -private: - - typedef GlibFixture super; - - static void on_bus_closed(GObject * object, - GAsyncResult * res, - gpointer gself) - { - auto self = static_cast(gself); - GError* err = nullptr; - g_dbus_connection_close_finish(G_DBUS_CONNECTION(object), res, &err); - g_assert_no_error(err); - g_main_loop_quit(self->loop); - } - -protected: - - GTestDBus* bus = nullptr; - - void SetUp() - { - super::SetUp(); - - // bring up the test bus - bus = g_test_dbus_new(G_TEST_DBUS_NONE); - g_test_dbus_up(bus); - const auto address = g_test_dbus_get_bus_address(bus); - g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true); - g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true); - } - - void TearDown() - { - GDBusConnection* connection = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, nullptr); - g_dbus_connection_close(connection, nullptr, on_bus_closed, this); - g_main_loop_run(loop); - g_clear_object(&connection); - g_test_dbus_down(bus); - g_clear_object(&bus); - - super::TearDown(); - } -}; - -TEST_F(ExporterFixture, HelloWorld) -{ - // confirms that the Test DBus SetUp() and TearDown() works -} - -TEST_F(ExporterFixture, Publish) -{ - std::shared_ptr state(new MockState); - std::shared_ptr actions(new MockActions(state)); - std::vector> menus; - - Exporter exporter; - exporter.publish(actions, menus); - wait_msec(); - - auto connection = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, nullptr); - auto exported = g_dbus_action_group_get (connection, BUS_NAME, BUS_PATH); - auto names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported)); - - // wait for the exported ActionGroup to be populated - if (g_strv_length(names_strv) == 0) - { - g_strfreev(names_strv); - wait_for_signal(exported, "action-added"); - names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported)); - } - - // convert it to a std::set for easy prodding - std::set names; - for(int i=0; names_strv && names_strv[i]; i++) - names.insert(names_strv[i]); - - // confirm the actions that we expect - EXPECT_EQ(1, names.count("activate-appointment")); - EXPECT_EQ(1, names.count("activate-desktop-settings")); - EXPECT_EQ(1, names.count("activate-phone-clock-app")); - EXPECT_EQ(1, names.count("activate-phone-settings")); - EXPECT_EQ(1, names.count("activate-planner")); - EXPECT_EQ(1, names.count("calendar")); - EXPECT_EQ(1, names.count("desktop-greeter-header")); - EXPECT_EQ(1, names.count("desktop-header")); - EXPECT_EQ(1, names.count("phone-greeter-header")); - EXPECT_EQ(1, names.count("phone-header")); - EXPECT_EQ(1, names.count("set-location")); - - // cleanup - g_strfreev(names_strv); - g_clear_object(&exported); - g_clear_object(&connection); -} diff --git a/tests/test-exporter.cpp b/tests/test-exporter.cpp new file mode 100644 index 0000000..ea62cd3 --- /dev/null +++ b/tests/test-exporter.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include "actions-mock.h" +#include "state-mock.h" +#include "glib-fixture.h" + +#include +#include +#include + +#include +#include + +using namespace unity::indicator::datetime; + +class ExporterFixture: public GlibFixture +{ +private: + + typedef GlibFixture super; + + static void on_bus_closed(GObject * object, + GAsyncResult * res, + gpointer gself) + { + auto self = static_cast(gself); + GError* err = nullptr; + g_dbus_connection_close_finish(G_DBUS_CONNECTION(object), res, &err); + g_assert_no_error(err); + g_main_loop_quit(self->loop); + } + +protected: + + GTestDBus* bus = nullptr; + + void SetUp() + { + super::SetUp(); + + // bring up the test bus + bus = g_test_dbus_new(G_TEST_DBUS_NONE); + g_test_dbus_up(bus); + const auto address = g_test_dbus_get_bus_address(bus); + g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true); + g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true); + } + + void TearDown() + { + GDBusConnection* connection = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, nullptr); + g_dbus_connection_close(connection, nullptr, on_bus_closed, this); + g_main_loop_run(loop); + g_clear_object(&connection); + g_test_dbus_down(bus); + g_clear_object(&bus); + + super::TearDown(); + } +}; + +TEST_F(ExporterFixture, HelloWorld) +{ + // confirms that the Test DBus SetUp() and TearDown() works +} + +TEST_F(ExporterFixture, Publish) +{ + std::shared_ptr state(new MockState); + std::shared_ptr actions(new MockActions(state)); + std::vector> menus; + + Exporter exporter; + exporter.publish(actions, menus); + wait_msec(); + + auto connection = g_bus_get_sync (G_BUS_TYPE_SESSION, nullptr, nullptr); + auto exported = g_dbus_action_group_get (connection, BUS_NAME, BUS_PATH); + auto names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported)); + + // wait for the exported ActionGroup to be populated + if (g_strv_length(names_strv) == 0) + { + g_strfreev(names_strv); + wait_for_signal(exported, "action-added"); + names_strv = g_action_group_list_actions(G_ACTION_GROUP(exported)); + } + + // convert it to a std::set for easy prodding + std::set names; + for(int i=0; names_strv && names_strv[i]; i++) + names.insert(names_strv[i]); + + // confirm the actions that we expect + EXPECT_EQ(1, names.count("activate-appointment")); + EXPECT_EQ(1, names.count("activate-desktop-settings")); + EXPECT_EQ(1, names.count("activate-phone-clock-app")); + EXPECT_EQ(1, names.count("activate-phone-settings")); + EXPECT_EQ(1, names.count("activate-planner")); + EXPECT_EQ(1, names.count("calendar")); + EXPECT_EQ(1, names.count("desktop-greeter-header")); + EXPECT_EQ(1, names.count("desktop-header")); + EXPECT_EQ(1, names.count("phone-greeter-header")); + EXPECT_EQ(1, names.count("phone-header")); + EXPECT_EQ(1, names.count("set-location")); + + // cleanup + g_strfreev(names_strv); + g_clear_object(&exported); + g_clear_object(&connection); +} diff --git a/tests/test-formatter.cc b/tests/test-formatter.cc deleted file mode 100644 index 9950453..0000000 --- a/tests/test-formatter.cc +++ /dev/null @@ -1,256 +0,0 @@ - -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "glib-fixture.h" - -#include -#include -#include - -#include - -#include -#include - -using namespace unity::indicator::datetime; - -/*** -**** -***/ - -class FormatterFixture: public GlibFixture -{ - private: - - typedef GlibFixture super; - gchar* m_original_locale = nullptr; - - protected: - - std::shared_ptr m_settings; - - virtual void SetUp() - { - super::SetUp(); - - m_settings.reset(new Settings); - m_original_locale = g_strdup(setlocale(LC_TIME, nullptr)); - } - - virtual void TearDown() - { - m_settings.reset(); - - setlocale(LC_TIME, m_original_locale); - g_clear_pointer(&m_original_locale, g_free); - - super::TearDown(); - } - - bool SetLocale(const char* expected_locale, const char* name) - { - setlocale(LC_TIME, expected_locale); - const auto actual_locale = setlocale(LC_TIME, nullptr); - if (!g_strcmp0(expected_locale, actual_locale)) - { - return true; - } - else - { - g_warning("Unable to set locale to %s; skipping %s locale tests.", expected_locale, name); - return false; - } - } - - inline bool Set24hLocale() { return SetLocale("C", "24h"); } - inline bool Set12hLocale() { return SetLocale("en_US.utf8", "12h"); } -}; - - -/** - * Test the phone header format - */ -TEST_F(FormatterFixture, TestPhoneHeader) -{ - auto now = g_date_time_new_local(2020, 10, 31, 18, 30, 59); - std::shared_ptr clock(new MockClock(DateTime(now))); - g_date_time_unref(now); - - // test the default value in a 24h locale - if(Set24hLocale()) - { - PhoneFormatter formatter(clock); - EXPECT_EQ(std::string("%H:%M"), formatter.headerFormat.get()); - EXPECT_EQ(std::string("18:30"), formatter.header.get()); - } - - // test the default value in a 12h locale - if(Set12hLocale()) - { - PhoneFormatter formatter(clock); - EXPECT_EQ(std::string("%l:%M %p"), formatter.headerFormat.get()); - EXPECT_EQ(std::string(" 6:30 PM"), formatter.header.get()); - } -} - -#define EM_SPACE "\u2003" - -/** - * Test the default values of the desktop header format - */ -TEST_F(FormatterFixture, TestDesktopHeader) -{ - struct { - bool is_12h; - bool show_day; - bool show_date; - bool show_year; - const char* expected_format_string; - } test_cases[] = { - { false, false, false, false, "%H:%M" }, - { false, false, false, true, "%H:%M" }, // show_year is ignored iff show_date is false - { false, false, true, false, "%b %e" EM_SPACE "%H:%M" }, - { false, false, true, true, "%b %e %Y" EM_SPACE "%H:%M" }, - { false, true, false, false, "%a" EM_SPACE "%H:%M" }, - { false, true, false, true, "%a" EM_SPACE "%H:%M" }, // show_year is ignored iff show_date is false - { false, true, true, false, "%a %b %e" EM_SPACE "%H:%M" }, - { false, true, true, true, "%a %b %e %Y" EM_SPACE "%H:%M" }, - { true, false, false, false, "%l:%M %p" }, - { true, false, false, true, "%l:%M %p" }, // show_year is ignored iff show_date is false - { true, false, true, false, "%b %e" EM_SPACE "%l:%M %p" }, - { true, false, true, true, "%b %e %Y" EM_SPACE "%l:%M %p" }, - { true, true, false, false, "%a" EM_SPACE "%l:%M %p" }, - { true, true, false, true, "%a" EM_SPACE "%l:%M %p" }, // show_year is ignored iff show_date is false - { true, true, true, false, "%a %b %e" EM_SPACE "%l:%M %p" }, - { 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); - std::shared_ptr clock(new MockClock(DateTime(now))); - g_date_time_unref(now); - - for(const auto& test_case : test_cases) - { - if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) - { - DesktopFormatter f(clock, m_settings); - - m_settings->show_day.set(test_case.show_day); - m_settings->show_date.set(test_case.show_date); - m_settings->show_year.set(test_case.show_year); - - ASSERT_STREQ(test_case.expected_format_string, f.headerFormat.get().c_str()); - } - } -} - -/** - * Test the default values of the desktop header format - */ -TEST_F(FormatterFixture, TestUpcomingTimes) -{ - auto a = g_date_time_new_local(2020, 10, 31, 18, 30, 59); - - struct { - gboolean is_12h; - GDateTime* now; - GDateTime* 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 - }; - - for(const auto& test_case : test_cases) - { - if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) - { - std::shared_ptr clock (new MockClock(DateTime(test_case.now))); - DesktopFormatter f(clock, m_settings); - - const auto fmt = f.getRelativeFormat(test_case.then); - 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); -} - - -/** - * Test the default values of the desktop header format - */ -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); - - struct { - bool is_12h; - GDateTime* now; - GDateTime* then; - GDateTime* 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") } - }; - - for(const auto& test_case : test_cases) - { - if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) - { - std::shared_ptr clock(new MockClock(DateTime(test_case.now))); - DesktopFormatter f(clock, m_settings); - - const auto fmt = f.getRelativeFormat(test_case.then, test_case.then_end); - 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-formatter.cpp b/tests/test-formatter.cpp new file mode 100644 index 0000000..9950453 --- /dev/null +++ b/tests/test-formatter.cpp @@ -0,0 +1,256 @@ + +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "glib-fixture.h" + +#include +#include +#include + +#include + +#include +#include + +using namespace unity::indicator::datetime; + +/*** +**** +***/ + +class FormatterFixture: public GlibFixture +{ + private: + + typedef GlibFixture super; + gchar* m_original_locale = nullptr; + + protected: + + std::shared_ptr m_settings; + + virtual void SetUp() + { + super::SetUp(); + + m_settings.reset(new Settings); + m_original_locale = g_strdup(setlocale(LC_TIME, nullptr)); + } + + virtual void TearDown() + { + m_settings.reset(); + + setlocale(LC_TIME, m_original_locale); + g_clear_pointer(&m_original_locale, g_free); + + super::TearDown(); + } + + bool SetLocale(const char* expected_locale, const char* name) + { + setlocale(LC_TIME, expected_locale); + const auto actual_locale = setlocale(LC_TIME, nullptr); + if (!g_strcmp0(expected_locale, actual_locale)) + { + return true; + } + else + { + g_warning("Unable to set locale to %s; skipping %s locale tests.", expected_locale, name); + return false; + } + } + + inline bool Set24hLocale() { return SetLocale("C", "24h"); } + inline bool Set12hLocale() { return SetLocale("en_US.utf8", "12h"); } +}; + + +/** + * Test the phone header format + */ +TEST_F(FormatterFixture, TestPhoneHeader) +{ + auto now = g_date_time_new_local(2020, 10, 31, 18, 30, 59); + std::shared_ptr clock(new MockClock(DateTime(now))); + g_date_time_unref(now); + + // test the default value in a 24h locale + if(Set24hLocale()) + { + PhoneFormatter formatter(clock); + EXPECT_EQ(std::string("%H:%M"), formatter.headerFormat.get()); + EXPECT_EQ(std::string("18:30"), formatter.header.get()); + } + + // test the default value in a 12h locale + if(Set12hLocale()) + { + PhoneFormatter formatter(clock); + EXPECT_EQ(std::string("%l:%M %p"), formatter.headerFormat.get()); + EXPECT_EQ(std::string(" 6:30 PM"), formatter.header.get()); + } +} + +#define EM_SPACE "\u2003" + +/** + * Test the default values of the desktop header format + */ +TEST_F(FormatterFixture, TestDesktopHeader) +{ + struct { + bool is_12h; + bool show_day; + bool show_date; + bool show_year; + const char* expected_format_string; + } test_cases[] = { + { false, false, false, false, "%H:%M" }, + { false, false, false, true, "%H:%M" }, // show_year is ignored iff show_date is false + { false, false, true, false, "%b %e" EM_SPACE "%H:%M" }, + { false, false, true, true, "%b %e %Y" EM_SPACE "%H:%M" }, + { false, true, false, false, "%a" EM_SPACE "%H:%M" }, + { false, true, false, true, "%a" EM_SPACE "%H:%M" }, // show_year is ignored iff show_date is false + { false, true, true, false, "%a %b %e" EM_SPACE "%H:%M" }, + { false, true, true, true, "%a %b %e %Y" EM_SPACE "%H:%M" }, + { true, false, false, false, "%l:%M %p" }, + { true, false, false, true, "%l:%M %p" }, // show_year is ignored iff show_date is false + { true, false, true, false, "%b %e" EM_SPACE "%l:%M %p" }, + { true, false, true, true, "%b %e %Y" EM_SPACE "%l:%M %p" }, + { true, true, false, false, "%a" EM_SPACE "%l:%M %p" }, + { true, true, false, true, "%a" EM_SPACE "%l:%M %p" }, // show_year is ignored iff show_date is false + { true, true, true, false, "%a %b %e" EM_SPACE "%l:%M %p" }, + { 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); + std::shared_ptr clock(new MockClock(DateTime(now))); + g_date_time_unref(now); + + for(const auto& test_case : test_cases) + { + if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) + { + DesktopFormatter f(clock, m_settings); + + m_settings->show_day.set(test_case.show_day); + m_settings->show_date.set(test_case.show_date); + m_settings->show_year.set(test_case.show_year); + + ASSERT_STREQ(test_case.expected_format_string, f.headerFormat.get().c_str()); + } + } +} + +/** + * Test the default values of the desktop header format + */ +TEST_F(FormatterFixture, TestUpcomingTimes) +{ + auto a = g_date_time_new_local(2020, 10, 31, 18, 30, 59); + + struct { + gboolean is_12h; + GDateTime* now; + GDateTime* 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 + }; + + for(const auto& test_case : test_cases) + { + if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) + { + std::shared_ptr clock (new MockClock(DateTime(test_case.now))); + DesktopFormatter f(clock, m_settings); + + const auto fmt = f.getRelativeFormat(test_case.then); + 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); +} + + +/** + * Test the default values of the desktop header format + */ +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); + + struct { + bool is_12h; + GDateTime* now; + GDateTime* then; + GDateTime* 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") } + }; + + for(const auto& test_case : test_cases) + { + if (test_case.is_12h ? Set12hLocale() : Set24hLocale()) + { + std::shared_ptr clock(new MockClock(DateTime(test_case.now))); + DesktopFormatter f(clock, m_settings); + + const auto fmt = f.getRelativeFormat(test_case.then, test_case.then_end); + 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 new file mode 100644 index 0000000..d3d7720 --- /dev/null +++ b/tests/test-live-actions.cpp @@ -0,0 +1,289 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include + +#include "state-mock.h" +#include "glib-fixture.h" + +/*** +**** +***/ + +class MockLiveActions: public LiveActions +{ +public: + std::string last_cmd; + std::string last_url; + MockLiveActions(const std::shared_ptr& state_in): LiveActions(state_in) {} + virtual ~MockLiveActions() {} + +protected: + void dispatch_url(const std::string& url) { last_url = url; } + void execute_command(const std::string& cmd) { last_cmd = cmd; } +}; + +/*** +**** +***/ + +using namespace unity::indicator::datetime; + +class LiveActionsFixture: public GlibFixture +{ +private: + + typedef GlibFixture super; + + static void on_bus_acquired(GDBusConnection* conn, + const gchar* name, + gpointer gself) + { + auto self = static_cast(gself); + g_debug("bus acquired: %s, connection is %p", name, conn); + + // Set up a mock GSD. + // All it really does is wait for calls to GetDevice and + // returns the get_devices_retval variant + static const GDBusInterfaceVTable vtable = { + timedate1_handle_method_call, + nullptr, /* GetProperty */ + nullptr, /* SetProperty */ + }; + + self->connection = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(conn))); + + GError* error = nullptr; + self->object_register_id = g_dbus_connection_register_object( + conn, + "/org/freedesktop/timedate1", + self->node_info->interfaces[0], + &vtable, + self, + nullptr, + &error); + g_assert_no_error(error); + } + + static void on_name_acquired(GDBusConnection* /*conn*/, + const gchar* /*name*/, + gpointer gself) + { + auto self = static_cast(gself); + self->name_acquired = true; + g_main_loop_quit(self->loop); + } + + static void on_name_lost(GDBusConnection* /*conn*/, + const gchar* /*name*/, + gpointer gself) + { + auto self = static_cast(gself); + self->name_acquired = false; + } + + static void on_bus_closed(GObject* /*object*/, + GAsyncResult* res, + gpointer gself) + { + auto self = static_cast(gself); + GError* err = nullptr; + g_dbus_connection_close_finish(self->connection, res, &err); + g_assert_no_error(err); + g_main_loop_quit(self->loop); + } + + static void + timedate1_handle_method_call(GDBusConnection * /*connection*/, + const gchar * /*sender*/, + const gchar * /*object_path*/, + const gchar * /*interface_name*/, + const gchar * method_name, + GVariant * parameters, + GDBusMethodInvocation * invocation, + gpointer gself) + { + g_assert(!g_strcmp0(method_name, "SetTimezone")); + g_assert(g_variant_is_of_type(parameters, G_VARIANT_TYPE_TUPLE)); + g_assert(2 == g_variant_n_children(parameters)); + + auto child = g_variant_get_child_value(parameters, 0); + g_assert(g_variant_is_of_type(child, G_VARIANT_TYPE_STRING)); + auto self = static_cast(gself); + self->attempted_tzid = g_variant_get_string(child, nullptr); + g_variant_unref(child); + + g_dbus_method_invocation_return_value(invocation, nullptr); + g_main_loop_quit(self->loop); + } + +protected: + + std::shared_ptr m_mock_state; + std::shared_ptr m_state; + std::shared_ptr m_live_actions; + std::shared_ptr m_actions; + + bool name_acquired; + std::string attempted_tzid; + + GTestDBus* bus; + guint own_name; + GDBusConnection* connection; + GDBusNodeInfo* node_info; + int object_register_id; + + void SetUp() + { + super::SetUp(); + + name_acquired = false; + attempted_tzid.clear(); + connection = nullptr; + node_info = nullptr; + object_register_id = 0; + own_name = 0; + + // bring up the test bus + bus = g_test_dbus_new(G_TEST_DBUS_NONE); + g_test_dbus_up(bus); + const auto address = g_test_dbus_get_bus_address(bus); + g_setenv("DBUS_SYSTEM_BUS_ADDRESS", address, true); + g_setenv("DBUS_SESSION_BUS_ADDRESS", address, true); + g_debug("test_dbus's address is %s", address); + + // parse the org.freedesktop.timedate1 interface + const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + ""; + node_info = g_dbus_node_info_new_for_xml(introspection_xml, nullptr); + ASSERT_TRUE(node_info != nullptr); + ASSERT_TRUE(node_info->interfaces != nullptr); + ASSERT_TRUE(node_info->interfaces[0] != nullptr); + ASSERT_TRUE(node_info->interfaces[1] == nullptr); + ASSERT_STREQ("org.freedesktop.timedate1", node_info->interfaces[0]->name); + + // own the bus + own_name = g_bus_own_name(G_BUS_TYPE_SYSTEM, + "org.freedesktop.timedate1", + G_BUS_NAME_OWNER_FLAGS_NONE, + on_bus_acquired, on_name_acquired, on_name_lost, + this, nullptr); + ASSERT_TRUE(object_register_id == 0); + ASSERT_FALSE(name_acquired); + ASSERT_TRUE(connection == nullptr); + g_main_loop_run(loop); + ASSERT_TRUE(object_register_id != 0); + ASSERT_TRUE(name_acquired); + ASSERT_TRUE(G_IS_DBUS_CONNECTION(connection)); + + // create the State and Actions + m_mock_state.reset(new MockState); + m_mock_state->settings.reset(new Settings); + m_state = std::dynamic_pointer_cast(m_mock_state); + m_live_actions.reset(new MockLiveActions(m_state)); + m_actions = std::dynamic_pointer_cast(m_live_actions); + } + + void TearDown() + { + m_actions.reset(); + m_live_actions.reset(); + m_state.reset(); + m_mock_state.reset(); + + g_dbus_connection_unregister_object(connection, object_register_id); + g_dbus_node_info_unref(node_info); + g_bus_unown_name(own_name); + g_dbus_connection_close(connection, nullptr, on_bus_closed, this); + g_main_loop_run(loop); + g_clear_object(&connection); + g_test_dbus_down(bus); + g_clear_object(&bus); + + super::TearDown(); + } +}; + +/*** +**** +***/ + +TEST_F(LiveActionsFixture, HelloWorld) +{ + EXPECT_TRUE(true); +} + +TEST_F(LiveActionsFixture, SetLocation) +{ + const std::string tzid = "America/Chicago"; + const std::string name = "Oklahoma City"; + const std::string expected = tzid + " " + name; + + EXPECT_NE(expected, m_state->settings->timezone_name.get()); + + m_actions->set_location(tzid, name); + g_main_loop_run(loop); + EXPECT_EQ(attempted_tzid, tzid); + wait_msec(); + + EXPECT_EQ(expected, m_state->settings->timezone_name.get()); +} + +TEST_F(LiveActionsFixture, OpenDesktopSettings) +{ + m_actions->open_desktop_settings(); + const std::string expected_substr = "control-center"; + EXPECT_NE(m_live_actions->last_cmd.find(expected_substr), std::string::npos); +} + +TEST_F(LiveActionsFixture, OpenPlanner) +{ + m_actions->open_planner(); + const std::string expected = "evolution -c calendar"; + EXPECT_EQ(expected, m_live_actions->last_cmd); +} + +TEST_F(LiveActionsFixture, OpenPhoneSettings) +{ + m_actions->open_phone_settings(); + const std::string expected = "settings:///system/time-date"; + EXPECT_EQ(expected, m_live_actions->last_url); +} + +TEST_F(LiveActionsFixture, OpenPhoneClockApp) +{ + m_actions->open_phone_clock_app(); + const std::string expected = "appid://com.ubuntu.clock/clock/current-user-version"; + EXPECT_EQ(expected, m_live_actions->last_url); +} + +TEST_F(LiveActionsFixture, OpenPlannerAt) +{ + const auto now = DateTime::NowLocal(); + m_actions->open_planner_at(now); + const std::string expected = now.format("evolution \"calendar:///?startdate=%Y%m%d\""); + EXPECT_EQ(expected, m_live_actions->last_cmd); +} diff --git a/tests/test-locations.cc b/tests/test-locations.cc deleted file mode 100644 index 65adbc7..0000000 --- a/tests/test-locations.cc +++ /dev/null @@ -1,169 +0,0 @@ - - -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "glib-fixture.h" - -#include - -using unity::indicator::datetime::Location; -using unity::indicator::datetime::Locations; -using unity::indicator::datetime::Settings; -using unity::indicator::datetime::SettingsLocations; -using unity::indicator::datetime::Timezones; - -/*** -**** -***/ - -class LocationsFixture: public GlibFixture -{ - private: - - typedef GlibFixture super; - - protected: - - //GSettings * settings = nullptr; - std::shared_ptr m_settings; - std::shared_ptr m_timezones; - const std::string nyc = "America/New_York"; - const std::string chicago = "America/Chicago"; - - virtual void SetUp() - { - super::SetUp(); - - m_settings.reset(new Settings); - m_settings->show_locations.set(true); - m_settings->locations.set({"America/Los_Angeles Oakland", - "America/Chicago Chicago", - "America/Chicago Oklahoma City", - "America/Toronto Toronto", - "Europe/London London", - "Europe/Berlin Berlin"}); - - m_timezones.reset(new Timezones); - m_timezones->timezone.set(chicago); - m_timezones->timezones.set(std::set({ nyc, chicago })); - } - - virtual void TearDown() - { - m_timezones.reset(); - m_settings.reset(); - - super::TearDown(); - } -}; - -TEST_F(LocationsFixture, Timezones) -{ - m_settings->show_locations.set(false); - - SettingsLocations locations(m_settings, m_timezones); - const auto l = locations.locations.get(); - EXPECT_EQ(2, l.size()); - EXPECT_STREQ("Chicago", l[0].name().c_str()); - EXPECT_EQ(chicago, l[0].zone()); - EXPECT_EQ("New York", l[1].name()); - EXPECT_EQ(nyc, l[1].zone()); -} - -TEST_F(LocationsFixture, SettingsLocations) -{ - SettingsLocations locations(m_settings, m_timezones); - - const auto l = locations.locations.get(); - EXPECT_EQ(7, l.size()); - EXPECT_EQ("Chicago", l[0].name()); - EXPECT_EQ(chicago, l[0].zone()); - EXPECT_EQ("New York", l[1].name()); - EXPECT_EQ(nyc, l[1].zone()); - EXPECT_EQ("Oakland", l[2].name()); - EXPECT_EQ("America/Los_Angeles", l[2].zone()); - EXPECT_EQ("Oklahoma City", l[3].name()); - EXPECT_EQ("America/Chicago", l[3].zone()); - EXPECT_EQ("Toronto", l[4].name()); - EXPECT_EQ("America/Toronto", l[4].zone()); - EXPECT_EQ("London", l[5].name()); - EXPECT_EQ("Europe/London", l[5].zone()); - EXPECT_EQ("Berlin", l[6].name()); - EXPECT_EQ("Europe/Berlin", l[6].zone()); -} - -TEST_F(LocationsFixture, ChangeLocationStrings) -{ - SettingsLocations locations(m_settings, m_timezones); - - bool locations_changed = false; - locations.locations.changed().connect([&locations_changed, this](const std::vector&){ - locations_changed = true; - g_main_loop_quit(loop); - }); - - g_idle_add([](gpointer settings){ - static_cast(settings)->locations.set({"America/Los_Angeles Oakland", "Europe/London London", "Europe/Berlin Berlin"}); - return G_SOURCE_REMOVE; - }, m_settings.get()); - - g_main_loop_run(loop); - - EXPECT_TRUE(locations_changed); - const auto l = locations.locations.get(); - EXPECT_EQ(5, l.size()); - EXPECT_EQ("Chicago", l[0].name()); - EXPECT_EQ(chicago, l[0].zone()); - EXPECT_EQ("New York", l[1].name()); - EXPECT_EQ(nyc, l[1].zone()); - EXPECT_EQ("Oakland", l[2].name()); - EXPECT_EQ("America/Los_Angeles", l[2].zone()); - EXPECT_EQ("London", l[3].name()); - EXPECT_EQ("Europe/London", l[3].zone()); - EXPECT_EQ("Berlin", l[4].name()); - EXPECT_EQ("Europe/Berlin", l[4].zone()); - locations_changed = false; -} - -TEST_F(LocationsFixture, ChangeLocationVisibility) -{ - SettingsLocations locations(m_settings, m_timezones); - - bool locations_changed = false; - locations.locations.changed().connect([&locations_changed, this](const std::vector&){ - locations_changed = true; - g_main_loop_quit(loop); - }); - - g_idle_add([](gpointer settings){ - static_cast(settings)->show_locations.set(false); - return G_SOURCE_REMOVE; - }, m_settings.get()); - - g_main_loop_run(loop); - - EXPECT_TRUE(locations_changed); - const auto l = locations.locations.get(); - EXPECT_EQ(2, l.size()); - EXPECT_EQ("Chicago", l[0].name()); - EXPECT_EQ(chicago, l[0].zone()); - EXPECT_EQ("New York", l[1].name()); - EXPECT_EQ(nyc, l[1].zone()); -} diff --git a/tests/test-locations.cpp b/tests/test-locations.cpp new file mode 100644 index 0000000..65adbc7 --- /dev/null +++ b/tests/test-locations.cpp @@ -0,0 +1,169 @@ + + +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "glib-fixture.h" + +#include + +using unity::indicator::datetime::Location; +using unity::indicator::datetime::Locations; +using unity::indicator::datetime::Settings; +using unity::indicator::datetime::SettingsLocations; +using unity::indicator::datetime::Timezones; + +/*** +**** +***/ + +class LocationsFixture: public GlibFixture +{ + private: + + typedef GlibFixture super; + + protected: + + //GSettings * settings = nullptr; + std::shared_ptr m_settings; + std::shared_ptr m_timezones; + const std::string nyc = "America/New_York"; + const std::string chicago = "America/Chicago"; + + virtual void SetUp() + { + super::SetUp(); + + m_settings.reset(new Settings); + m_settings->show_locations.set(true); + m_settings->locations.set({"America/Los_Angeles Oakland", + "America/Chicago Chicago", + "America/Chicago Oklahoma City", + "America/Toronto Toronto", + "Europe/London London", + "Europe/Berlin Berlin"}); + + m_timezones.reset(new Timezones); + m_timezones->timezone.set(chicago); + m_timezones->timezones.set(std::set({ nyc, chicago })); + } + + virtual void TearDown() + { + m_timezones.reset(); + m_settings.reset(); + + super::TearDown(); + } +}; + +TEST_F(LocationsFixture, Timezones) +{ + m_settings->show_locations.set(false); + + SettingsLocations locations(m_settings, m_timezones); + const auto l = locations.locations.get(); + EXPECT_EQ(2, l.size()); + EXPECT_STREQ("Chicago", l[0].name().c_str()); + EXPECT_EQ(chicago, l[0].zone()); + EXPECT_EQ("New York", l[1].name()); + EXPECT_EQ(nyc, l[1].zone()); +} + +TEST_F(LocationsFixture, SettingsLocations) +{ + SettingsLocations locations(m_settings, m_timezones); + + const auto l = locations.locations.get(); + EXPECT_EQ(7, l.size()); + EXPECT_EQ("Chicago", l[0].name()); + EXPECT_EQ(chicago, l[0].zone()); + EXPECT_EQ("New York", l[1].name()); + EXPECT_EQ(nyc, l[1].zone()); + EXPECT_EQ("Oakland", l[2].name()); + EXPECT_EQ("America/Los_Angeles", l[2].zone()); + EXPECT_EQ("Oklahoma City", l[3].name()); + EXPECT_EQ("America/Chicago", l[3].zone()); + EXPECT_EQ("Toronto", l[4].name()); + EXPECT_EQ("America/Toronto", l[4].zone()); + EXPECT_EQ("London", l[5].name()); + EXPECT_EQ("Europe/London", l[5].zone()); + EXPECT_EQ("Berlin", l[6].name()); + EXPECT_EQ("Europe/Berlin", l[6].zone()); +} + +TEST_F(LocationsFixture, ChangeLocationStrings) +{ + SettingsLocations locations(m_settings, m_timezones); + + bool locations_changed = false; + locations.locations.changed().connect([&locations_changed, this](const std::vector&){ + locations_changed = true; + g_main_loop_quit(loop); + }); + + g_idle_add([](gpointer settings){ + static_cast(settings)->locations.set({"America/Los_Angeles Oakland", "Europe/London London", "Europe/Berlin Berlin"}); + return G_SOURCE_REMOVE; + }, m_settings.get()); + + g_main_loop_run(loop); + + EXPECT_TRUE(locations_changed); + const auto l = locations.locations.get(); + EXPECT_EQ(5, l.size()); + EXPECT_EQ("Chicago", l[0].name()); + EXPECT_EQ(chicago, l[0].zone()); + EXPECT_EQ("New York", l[1].name()); + EXPECT_EQ(nyc, l[1].zone()); + EXPECT_EQ("Oakland", l[2].name()); + EXPECT_EQ("America/Los_Angeles", l[2].zone()); + EXPECT_EQ("London", l[3].name()); + EXPECT_EQ("Europe/London", l[3].zone()); + EXPECT_EQ("Berlin", l[4].name()); + EXPECT_EQ("Europe/Berlin", l[4].zone()); + locations_changed = false; +} + +TEST_F(LocationsFixture, ChangeLocationVisibility) +{ + SettingsLocations locations(m_settings, m_timezones); + + bool locations_changed = false; + locations.locations.changed().connect([&locations_changed, this](const std::vector&){ + locations_changed = true; + g_main_loop_quit(loop); + }); + + g_idle_add([](gpointer settings){ + static_cast(settings)->show_locations.set(false); + return G_SOURCE_REMOVE; + }, m_settings.get()); + + g_main_loop_run(loop); + + EXPECT_TRUE(locations_changed); + const auto l = locations.locations.get(); + EXPECT_EQ(2, l.size()); + EXPECT_EQ("Chicago", l[0].name()); + EXPECT_EQ(chicago, l[0].zone()); + EXPECT_EQ("New York", l[1].name()); + EXPECT_EQ(nyc, l[1].zone()); +} diff --git a/tests/test-menus.cc b/tests/test-menus.cc deleted file mode 100644 index fe1e86e..0000000 --- a/tests/test-menus.cc +++ /dev/null @@ -1,402 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - - -#include "actions-mock.h" -#include "state-fixture.h" - -#include -#include -#include -#include - -#include - -using namespace unity::indicator::datetime; - -class MenuFixture: public StateFixture -{ -private: - typedef StateFixture super; - -protected: - std::shared_ptr m_menu_factory; - std::vector> m_menus; - - virtual void SetUp() - { - super::SetUp(); - - // build the menus on top of the actions and state - m_menu_factory.reset(new MenuFactory(m_actions, m_state)); - for(int i=0; ibuildMenu(Menu::Profile(i))); - } - - virtual void TearDown() - { - m_menus.clear(); - m_menu_factory.reset(); - - super::TearDown(); - } - - void InspectHeader(GMenuModel* menu_model, const std::string& name) - { - // check that there's a header menuitem - EXPECT_EQ(1,g_menu_model_get_n_items(menu_model)); - gchar* str = nullptr; - g_menu_model_get_item_attribute(menu_model, 0, "x-canonical-type", "s", &str); - EXPECT_STREQ("com.canonical.indicator.root", str); - g_clear_pointer(&str, g_free); - g_menu_model_get_item_attribute(menu_model, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); - const auto action_name = name + "-header"; - EXPECT_EQ(std::string("indicator.")+action_name, str); - g_clear_pointer(&str, g_free); - - // check the header - auto dict = g_action_group_get_action_state(m_actions->action_group(), action_name.c_str()); - EXPECT_TRUE(dict != nullptr); - EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT)); - auto v = g_variant_lookup_value(dict, "accessible-desc", G_VARIANT_TYPE_STRING); - EXPECT_TRUE(v != nullptr); - g_variant_unref(v); - v = g_variant_lookup_value(dict, "label", G_VARIANT_TYPE_STRING); - EXPECT_TRUE(v != nullptr); - g_variant_unref(v); - v = g_variant_lookup_value(dict, "title", G_VARIANT_TYPE_STRING); - EXPECT_TRUE(v != nullptr); - g_variant_unref(v); - v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN); - EXPECT_TRUE(v != nullptr); - g_variant_unref(v); - g_variant_unref(dict); - } - - void InspectCalendar(GMenuModel* menu_model, Menu::Profile profile) - { - gchar* str = nullptr; - const auto actions_expected = (profile == Menu::Desktop) || (profile == Menu::Phone); - const auto calendar_expected = (profile == Menu::Desktop) || (profile == Menu::DesktopGreeter); - - // get the calendar section - auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); - auto section = g_menu_model_get_item_link(submenu, Menu::Calendar, G_MENU_LINK_SECTION); - - // should be one or two items: a date label and maybe a calendar - ASSERT_TRUE(section != nullptr); - auto n_expected = calendar_expected ? 2 : 1; - EXPECT_EQ(n_expected, g_menu_model_get_n_items(section)); - - // look at the date menuitem - g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_LABEL, "s", &str); - const auto now = m_state->clock->localtime(); - EXPECT_EQ(now.format("%A, %e %B %Y"), str); - - g_clear_pointer(&str, g_free); - - g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); - if (actions_expected) - EXPECT_STREQ("indicator.activate-planner", str); - else - EXPECT_TRUE(str == nullptr); - g_clear_pointer(&str, g_free); - - // look at the calendar menuitem - if (calendar_expected) - { - g_menu_model_get_item_attribute(section, 1, "x-canonical-type", "s", &str); - EXPECT_STREQ("com.canonical.indicator.calendar", str); - g_clear_pointer(&str, g_free); - - g_menu_model_get_item_attribute(section, 1, G_MENU_ATTRIBUTE_ACTION, "s", &str); - EXPECT_STREQ("indicator.calendar", str); - g_clear_pointer(&str, g_free); - - g_menu_model_get_item_attribute(section, 1, "activation-action", "s", &str); - if (actions_expected) - EXPECT_STREQ("indicator.activate-planner", str); - else - EXPECT_TRUE(str == nullptr); - g_clear_pointer(&str, g_free); - } - - g_clear_object(§ion); - - // 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); - m_mock_state->mock_clock->set_localtime(tomorrow); - wait_msec(); - - section = g_menu_model_get_item_link(submenu, Menu::Calendar, G_MENU_LINK_SECTION); - g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_LABEL, "s", &str); - EXPECT_EQ(tomorrow.format("%A, %e %B %Y"), str); - g_clear_pointer(&str, g_free); - g_clear_object(§ion); - - // cleanup - g_object_unref(submenu); - } - - void InspectAppointments(GMenuModel* menu_model, Menu::Profile profile) - { - const bool appointments_expected = (profile == Menu::Desktop) - || (profile == Menu::Phone); - - // get the Appointments section - auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); - - // there shouldn't be any menuitems when "show events" is false - m_state->settings->show_events.set(false); - wait_msec(); - auto section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); - EXPECT_EQ(0, g_menu_model_get_n_items(section)); - g_clear_object(§ion); - - // when "show_events" is true, - // there should be an "add event" button even if there aren't any appointments - std::vector appointments; - m_state->settings->show_events.set(true); - m_state->planner->upcoming.set(appointments); - wait_msec(); - section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); - int expected_n = appointments_expected ? 1 : 0; - EXPECT_EQ(expected_n, g_menu_model_get_n_items(section)); - g_clear_object(§ion); - - // try adding a few appointments and see if the menu updates itself - - 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); - - Appointment a1; // an alarm clock appointment - a1.color = "red"; - a1.summary = "Alarm"; - a1.summary = "http://www.example.com/"; - a1.uid = "example"; - a1.has_alarms = true; - a1.begin = a1.end = tomorrow; - appointments.push_back(a1); - - Appointment a2; // a non-alarm appointment - a2.color = "green"; - a2.summary = "Other Text"; - a2.summary = "http://www.monkey.com/"; - a2.uid = "monkey"; - a2.has_alarms = false; - a2.begin = a2.end = tomorrow; - appointments.push_back(a2); - - m_state->planner->upcoming.set(appointments); - wait_msec(); // wait a moment for the menu to update - - section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); - expected_n = appointments_expected ? 3 : 0; - EXPECT_EQ(expected_n, g_menu_model_get_n_items(section)); - if (appointments_expected) - { - gchar * str = nullptr; - - // test the alarm - // - confirm it has an x-canonical-type of "alarm" - g_menu_model_get_item_attribute(section, 0, "x-canonical-type", "s", &str); - EXPECT_STREQ("com.canonical.indicator.alarm", str); - g_clear_pointer(&str, g_free); - // - confirm it has a nonempty x-canonical-time-format - g_menu_model_get_item_attribute(section, 0, "x-canonical-time-format", "s", &str); - EXPECT_TRUE(str && *str); - g_clear_pointer(&str, g_free); - // - confirm it has a serialized icon attribute - auto v = g_menu_model_get_item_attribute_value(section, 0, G_MENU_ATTRIBUTE_ICON, nullptr); - EXPECT_TRUE(v != nullptr); - auto icon = g_icon_deserialize(v); - EXPECT_TRUE(icon != nullptr); - g_clear_object(&icon); - g_clear_pointer(&v, g_variant_unref); - - // test the appointment - // - confirm it has an x-canonical-type of "appointment" - g_menu_model_get_item_attribute(section, 1, "x-canonical-type", "s", &str); - EXPECT_STREQ("com.canonical.indicator.appointment", str); - g_clear_pointer(&str, g_free); - // - confirm it has a nonempty x-canonical-time-format - g_menu_model_get_item_attribute(section, 0, "x-canonical-time-format", "s", &str); - EXPECT_TRUE(str && *str); - g_clear_pointer(&str, g_free); - // - confirm its color matches the one we fed the appointments vector - g_menu_model_get_item_attribute(section, 1, "x-canonical-color", "s", &str); - EXPECT_EQ(a2.color, str); - g_clear_pointer(&str, g_free); - } - g_clear_object(§ion); - - g_object_unref(submenu); - } - - void CompareLocationsTo(GMenuModel* menu_model, const std::vector& locations) - { - // get the Locations section - auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); - auto section = g_menu_model_get_item_link(submenu, Menu::Locations, G_MENU_LINK_SECTION); - - // confirm that section's menuitems mirror the "locations" vector - const auto n = locations.size(); - ASSERT_EQ(n, g_menu_model_get_n_items(section)); - for (guint i=0; i empty; - m_state->locations->locations.set(empty); - wait_msec(); - CompareLocationsTo(menu_model, empty); - - // add some locations and confirm the menu picked up our changes - Location l1 ("America/Chicago", "Dallas"); - Location l2 ("America/Arizona", "Phoenix"); - std::vector locations({l1, l2}); - m_state->locations->locations.set(locations); - wait_msec(); - CompareLocationsTo(menu_model, locations_expected ? locations : empty); - - // now remove one of the locations... - locations.pop_back(); - m_state->locations->locations.set(locations); - wait_msec(); - CompareLocationsTo(menu_model, locations_expected ? locations : empty); - } - - void InspectSettings(GMenuModel* menu_model, Menu::Profile profile) - { - std::string expected_action; - - if (profile == Menu::Desktop) - expected_action = "indicator.activate-desktop-settings"; - else if (profile == Menu::Phone) - expected_action = "indicator.activate-phone-settings"; - - // get the Settings section - auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); - auto section = g_menu_model_get_item_link(submenu, Menu::Settings, G_MENU_LINK_SECTION); - - if (expected_action.empty()) - { - EXPECT_EQ(0, g_menu_model_get_n_items(section)); - } - else - { - EXPECT_EQ(1, g_menu_model_get_n_items(section)); - gchar* str = nullptr; - g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); - EXPECT_EQ(expected_action, str); - g_clear_pointer(&str, g_free); - } - - g_clear_object(§ion); - g_object_unref(submenu); - } -}; - - -TEST_F(MenuFixture, HelloWorld) -{ - EXPECT_EQ(Menu::NUM_PROFILES, m_menus.size()); - for (int i=0; imenu_model() != nullptr); - EXPECT_EQ(i, m_menus[i]->profile()); - } - EXPECT_EQ(m_menus[Menu::Desktop]->name(), "desktop"); -} - -TEST_F(MenuFixture, Header) -{ - for(auto& menu : m_menus) - InspectHeader(menu->menu_model(), menu->name()); -} - -TEST_F(MenuFixture, Sections) -{ - for(auto& menu : m_menus) - { - // check that the header has a submenu - auto menu_model = menu->menu_model(); - auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); - EXPECT_TRUE(submenu != nullptr); - EXPECT_EQ(Menu::NUM_SECTIONS, g_menu_model_get_n_items(submenu)); - g_object_unref(submenu); - } -} - -TEST_F(MenuFixture, Calendar) -{ - for(auto& menu : m_menus) - InspectCalendar(menu->menu_model(), menu->profile()); -} - -TEST_F(MenuFixture, Appointments) -{ - for(auto& menu : m_menus) - InspectAppointments(menu->menu_model(), menu->profile()); -} - -TEST_F(MenuFixture, Locations) -{ - for(auto& menu : m_menus) - InspectLocations(menu->menu_model(), menu->profile()); -} - -TEST_F(MenuFixture, Settings) -{ - for(auto& menu : m_menus) - InspectSettings(menu->menu_model(), menu->profile()); -} - - diff --git a/tests/test-menus.cpp b/tests/test-menus.cpp new file mode 100644 index 0000000..fe1e86e --- /dev/null +++ b/tests/test-menus.cpp @@ -0,0 +1,402 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + + +#include "actions-mock.h" +#include "state-fixture.h" + +#include +#include +#include +#include + +#include + +using namespace unity::indicator::datetime; + +class MenuFixture: public StateFixture +{ +private: + typedef StateFixture super; + +protected: + std::shared_ptr m_menu_factory; + std::vector> m_menus; + + virtual void SetUp() + { + super::SetUp(); + + // build the menus on top of the actions and state + m_menu_factory.reset(new MenuFactory(m_actions, m_state)); + for(int i=0; ibuildMenu(Menu::Profile(i))); + } + + virtual void TearDown() + { + m_menus.clear(); + m_menu_factory.reset(); + + super::TearDown(); + } + + void InspectHeader(GMenuModel* menu_model, const std::string& name) + { + // check that there's a header menuitem + EXPECT_EQ(1,g_menu_model_get_n_items(menu_model)); + gchar* str = nullptr; + g_menu_model_get_item_attribute(menu_model, 0, "x-canonical-type", "s", &str); + EXPECT_STREQ("com.canonical.indicator.root", str); + g_clear_pointer(&str, g_free); + g_menu_model_get_item_attribute(menu_model, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); + const auto action_name = name + "-header"; + EXPECT_EQ(std::string("indicator.")+action_name, str); + g_clear_pointer(&str, g_free); + + // check the header + auto dict = g_action_group_get_action_state(m_actions->action_group(), action_name.c_str()); + EXPECT_TRUE(dict != nullptr); + EXPECT_TRUE(g_variant_is_of_type(dict, G_VARIANT_TYPE_VARDICT)); + auto v = g_variant_lookup_value(dict, "accessible-desc", G_VARIANT_TYPE_STRING); + EXPECT_TRUE(v != nullptr); + g_variant_unref(v); + v = g_variant_lookup_value(dict, "label", G_VARIANT_TYPE_STRING); + EXPECT_TRUE(v != nullptr); + g_variant_unref(v); + v = g_variant_lookup_value(dict, "title", G_VARIANT_TYPE_STRING); + EXPECT_TRUE(v != nullptr); + g_variant_unref(v); + v = g_variant_lookup_value(dict, "visible", G_VARIANT_TYPE_BOOLEAN); + EXPECT_TRUE(v != nullptr); + g_variant_unref(v); + g_variant_unref(dict); + } + + void InspectCalendar(GMenuModel* menu_model, Menu::Profile profile) + { + gchar* str = nullptr; + const auto actions_expected = (profile == Menu::Desktop) || (profile == Menu::Phone); + const auto calendar_expected = (profile == Menu::Desktop) || (profile == Menu::DesktopGreeter); + + // get the calendar section + auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); + auto section = g_menu_model_get_item_link(submenu, Menu::Calendar, G_MENU_LINK_SECTION); + + // should be one or two items: a date label and maybe a calendar + ASSERT_TRUE(section != nullptr); + auto n_expected = calendar_expected ? 2 : 1; + EXPECT_EQ(n_expected, g_menu_model_get_n_items(section)); + + // look at the date menuitem + g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_LABEL, "s", &str); + const auto now = m_state->clock->localtime(); + EXPECT_EQ(now.format("%A, %e %B %Y"), str); + + g_clear_pointer(&str, g_free); + + g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); + if (actions_expected) + EXPECT_STREQ("indicator.activate-planner", str); + else + EXPECT_TRUE(str == nullptr); + g_clear_pointer(&str, g_free); + + // look at the calendar menuitem + if (calendar_expected) + { + g_menu_model_get_item_attribute(section, 1, "x-canonical-type", "s", &str); + EXPECT_STREQ("com.canonical.indicator.calendar", str); + g_clear_pointer(&str, g_free); + + g_menu_model_get_item_attribute(section, 1, G_MENU_ATTRIBUTE_ACTION, "s", &str); + EXPECT_STREQ("indicator.calendar", str); + g_clear_pointer(&str, g_free); + + g_menu_model_get_item_attribute(section, 1, "activation-action", "s", &str); + if (actions_expected) + EXPECT_STREQ("indicator.activate-planner", str); + else + EXPECT_TRUE(str == nullptr); + g_clear_pointer(&str, g_free); + } + + g_clear_object(§ion); + + // 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); + m_mock_state->mock_clock->set_localtime(tomorrow); + wait_msec(); + + section = g_menu_model_get_item_link(submenu, Menu::Calendar, G_MENU_LINK_SECTION); + g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_LABEL, "s", &str); + EXPECT_EQ(tomorrow.format("%A, %e %B %Y"), str); + g_clear_pointer(&str, g_free); + g_clear_object(§ion); + + // cleanup + g_object_unref(submenu); + } + + void InspectAppointments(GMenuModel* menu_model, Menu::Profile profile) + { + const bool appointments_expected = (profile == Menu::Desktop) + || (profile == Menu::Phone); + + // get the Appointments section + auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); + + // there shouldn't be any menuitems when "show events" is false + m_state->settings->show_events.set(false); + wait_msec(); + auto section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); + EXPECT_EQ(0, g_menu_model_get_n_items(section)); + g_clear_object(§ion); + + // when "show_events" is true, + // there should be an "add event" button even if there aren't any appointments + std::vector appointments; + m_state->settings->show_events.set(true); + m_state->planner->upcoming.set(appointments); + wait_msec(); + section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); + int expected_n = appointments_expected ? 1 : 0; + EXPECT_EQ(expected_n, g_menu_model_get_n_items(section)); + g_clear_object(§ion); + + // try adding a few appointments and see if the menu updates itself + + 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); + + Appointment a1; // an alarm clock appointment + a1.color = "red"; + a1.summary = "Alarm"; + a1.summary = "http://www.example.com/"; + a1.uid = "example"; + a1.has_alarms = true; + a1.begin = a1.end = tomorrow; + appointments.push_back(a1); + + Appointment a2; // a non-alarm appointment + a2.color = "green"; + a2.summary = "Other Text"; + a2.summary = "http://www.monkey.com/"; + a2.uid = "monkey"; + a2.has_alarms = false; + a2.begin = a2.end = tomorrow; + appointments.push_back(a2); + + m_state->planner->upcoming.set(appointments); + wait_msec(); // wait a moment for the menu to update + + section = g_menu_model_get_item_link(submenu, Menu::Appointments, G_MENU_LINK_SECTION); + expected_n = appointments_expected ? 3 : 0; + EXPECT_EQ(expected_n, g_menu_model_get_n_items(section)); + if (appointments_expected) + { + gchar * str = nullptr; + + // test the alarm + // - confirm it has an x-canonical-type of "alarm" + g_menu_model_get_item_attribute(section, 0, "x-canonical-type", "s", &str); + EXPECT_STREQ("com.canonical.indicator.alarm", str); + g_clear_pointer(&str, g_free); + // - confirm it has a nonempty x-canonical-time-format + g_menu_model_get_item_attribute(section, 0, "x-canonical-time-format", "s", &str); + EXPECT_TRUE(str && *str); + g_clear_pointer(&str, g_free); + // - confirm it has a serialized icon attribute + auto v = g_menu_model_get_item_attribute_value(section, 0, G_MENU_ATTRIBUTE_ICON, nullptr); + EXPECT_TRUE(v != nullptr); + auto icon = g_icon_deserialize(v); + EXPECT_TRUE(icon != nullptr); + g_clear_object(&icon); + g_clear_pointer(&v, g_variant_unref); + + // test the appointment + // - confirm it has an x-canonical-type of "appointment" + g_menu_model_get_item_attribute(section, 1, "x-canonical-type", "s", &str); + EXPECT_STREQ("com.canonical.indicator.appointment", str); + g_clear_pointer(&str, g_free); + // - confirm it has a nonempty x-canonical-time-format + g_menu_model_get_item_attribute(section, 0, "x-canonical-time-format", "s", &str); + EXPECT_TRUE(str && *str); + g_clear_pointer(&str, g_free); + // - confirm its color matches the one we fed the appointments vector + g_menu_model_get_item_attribute(section, 1, "x-canonical-color", "s", &str); + EXPECT_EQ(a2.color, str); + g_clear_pointer(&str, g_free); + } + g_clear_object(§ion); + + g_object_unref(submenu); + } + + void CompareLocationsTo(GMenuModel* menu_model, const std::vector& locations) + { + // get the Locations section + auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); + auto section = g_menu_model_get_item_link(submenu, Menu::Locations, G_MENU_LINK_SECTION); + + // confirm that section's menuitems mirror the "locations" vector + const auto n = locations.size(); + ASSERT_EQ(n, g_menu_model_get_n_items(section)); + for (guint i=0; i empty; + m_state->locations->locations.set(empty); + wait_msec(); + CompareLocationsTo(menu_model, empty); + + // add some locations and confirm the menu picked up our changes + Location l1 ("America/Chicago", "Dallas"); + Location l2 ("America/Arizona", "Phoenix"); + std::vector locations({l1, l2}); + m_state->locations->locations.set(locations); + wait_msec(); + CompareLocationsTo(menu_model, locations_expected ? locations : empty); + + // now remove one of the locations... + locations.pop_back(); + m_state->locations->locations.set(locations); + wait_msec(); + CompareLocationsTo(menu_model, locations_expected ? locations : empty); + } + + void InspectSettings(GMenuModel* menu_model, Menu::Profile profile) + { + std::string expected_action; + + if (profile == Menu::Desktop) + expected_action = "indicator.activate-desktop-settings"; + else if (profile == Menu::Phone) + expected_action = "indicator.activate-phone-settings"; + + // get the Settings section + auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); + auto section = g_menu_model_get_item_link(submenu, Menu::Settings, G_MENU_LINK_SECTION); + + if (expected_action.empty()) + { + EXPECT_EQ(0, g_menu_model_get_n_items(section)); + } + else + { + EXPECT_EQ(1, g_menu_model_get_n_items(section)); + gchar* str = nullptr; + g_menu_model_get_item_attribute(section, 0, G_MENU_ATTRIBUTE_ACTION, "s", &str); + EXPECT_EQ(expected_action, str); + g_clear_pointer(&str, g_free); + } + + g_clear_object(§ion); + g_object_unref(submenu); + } +}; + + +TEST_F(MenuFixture, HelloWorld) +{ + EXPECT_EQ(Menu::NUM_PROFILES, m_menus.size()); + for (int i=0; imenu_model() != nullptr); + EXPECT_EQ(i, m_menus[i]->profile()); + } + EXPECT_EQ(m_menus[Menu::Desktop]->name(), "desktop"); +} + +TEST_F(MenuFixture, Header) +{ + for(auto& menu : m_menus) + InspectHeader(menu->menu_model(), menu->name()); +} + +TEST_F(MenuFixture, Sections) +{ + for(auto& menu : m_menus) + { + // check that the header has a submenu + auto menu_model = menu->menu_model(); + auto submenu = g_menu_model_get_item_link(menu_model, 0, G_MENU_LINK_SUBMENU); + EXPECT_TRUE(submenu != nullptr); + EXPECT_EQ(Menu::NUM_SECTIONS, g_menu_model_get_n_items(submenu)); + g_object_unref(submenu); + } +} + +TEST_F(MenuFixture, Calendar) +{ + for(auto& menu : m_menus) + InspectCalendar(menu->menu_model(), menu->profile()); +} + +TEST_F(MenuFixture, Appointments) +{ + for(auto& menu : m_menus) + InspectAppointments(menu->menu_model(), menu->profile()); +} + +TEST_F(MenuFixture, Locations) +{ + for(auto& menu : m_menus) + InspectLocations(menu->menu_model(), menu->profile()); +} + +TEST_F(MenuFixture, Settings) +{ + for(auto& menu : m_menus) + InspectSettings(menu->menu_model(), menu->profile()); +} + + diff --git a/tests/test-planner.cc b/tests/test-planner.cc deleted file mode 100644 index 3072aea..0000000 --- a/tests/test-planner.cc +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "glib-fixture.h" - -#include -#include -#include -#include -#include - -#include -#include - -using unity::indicator::datetime::Appointment; -using unity::indicator::datetime::DateTime; -using unity::indicator::datetime::PlannerEds; - -/*** -**** -***/ - -typedef GlibFixture PlannerFixture; - -TEST_F(PlannerFixture, EDS) -{ - PlannerEds planner; - wait_msec(100); - - auto now = g_date_time_new_now_local(); - planner.time.set(DateTime(now)); - wait_msec(2500); - - std::vector thisMonth = planner.thisMonth.get(); - std::cerr << thisMonth.size() << " appointments this month" << std::endl; - for(const auto& a : thisMonth) - std::cerr << a.summary << std::endl; -} - - -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); - - Appointment a; - a.summary = "Test"; - a.begin = halloween; - a.end = g_date_time_add_hours(halloween, 1); - 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())); - - Appointment c; - c.begin = christmas; - c.end = g_date_time_add_hours(christmas, 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())); - a = d; - EXPECT_EQ(0, g_date_time_compare(d.begin(), a.begin())); - EXPECT_EQ(0, g_date_time_compare(d.end(), a.end())); -} - diff --git a/tests/test-planner.cpp b/tests/test-planner.cpp new file mode 100644 index 0000000..3072aea --- /dev/null +++ b/tests/test-planner.cpp @@ -0,0 +1,85 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "glib-fixture.h" + +#include +#include +#include +#include +#include + +#include +#include + +using unity::indicator::datetime::Appointment; +using unity::indicator::datetime::DateTime; +using unity::indicator::datetime::PlannerEds; + +/*** +**** +***/ + +typedef GlibFixture PlannerFixture; + +TEST_F(PlannerFixture, EDS) +{ + PlannerEds planner; + wait_msec(100); + + auto now = g_date_time_new_now_local(); + planner.time.set(DateTime(now)); + wait_msec(2500); + + std::vector thisMonth = planner.thisMonth.get(); + std::cerr << thisMonth.size() << " appointments this month" << std::endl; + for(const auto& a : thisMonth) + std::cerr << a.summary << std::endl; +} + + +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); + + Appointment a; + a.summary = "Test"; + a.begin = halloween; + a.end = g_date_time_add_hours(halloween, 1); + 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())); + + Appointment c; + c.begin = christmas; + c.end = g_date_time_add_hours(christmas, 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())); + a = d; + EXPECT_EQ(0, g_date_time_compare(d.begin(), a.begin())); + EXPECT_EQ(0, g_date_time_compare(d.end(), a.end())); +} + diff --git a/tests/test-settings.cc b/tests/test-settings.cc deleted file mode 100644 index 9e52197..0000000 --- a/tests/test-settings.cc +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "glib-fixture.h" - -#include -#include - -using namespace unity::indicator::datetime; - -/*** -**** -***/ - -class SettingsFixture: public GlibFixture -{ -private: - typedef GlibFixture super; - -protected: - - std::shared_ptr m_live; - std::shared_ptr m_settings; - GSettings * m_gsettings; - - virtual void SetUp() - { - super::SetUp(); - - m_gsettings = g_settings_new(SETTINGS_INTERFACE); - m_live.reset(new LiveSettings); - m_settings = std::dynamic_pointer_cast(m_live); - } - - virtual void TearDown() - { - g_clear_object(&m_gsettings); - m_settings.reset(); - m_live.reset(); - - super::TearDown(); - } - - void TestBoolProperty(core::Property& property, const gchar* key) - { - EXPECT_EQ(g_settings_get_boolean(m_gsettings, key), property.get()); - g_settings_set_boolean(m_gsettings, key, false); - EXPECT_EQ(false, property.get()); - g_settings_set_boolean(m_gsettings, key, true); - EXPECT_EQ(true, property.get()); - - property.set(false); - EXPECT_EQ(false, g_settings_get_boolean(m_gsettings, key)); - property.set(true); - EXPECT_EQ(true, g_settings_get_boolean(m_gsettings, key)); - } - - void TestStringProperty(core::Property& property, const gchar* key) - { - gchar* tmp; - std::string str; - - tmp = g_settings_get_string(m_gsettings, key); - EXPECT_EQ(tmp, property.get()); - g_clear_pointer(&tmp, g_free); - - str = "a"; - g_settings_set_string(m_gsettings, key, str.c_str()); - EXPECT_EQ(str, property.get()); - - str = "b"; - g_settings_set_string(m_gsettings, key, str.c_str()); - EXPECT_EQ(str, property.get()); - - str = "a"; - property.set(str); - tmp = g_settings_get_string(m_gsettings, key); - EXPECT_EQ(str, tmp); - g_clear_pointer(&tmp, g_free); - - str = "b"; - property.set(str); - tmp = g_settings_get_string(m_gsettings, key); - EXPECT_EQ(str, tmp); - g_clear_pointer(&tmp, g_free); - } -}; - -/*** -**** -***/ - -TEST_F(SettingsFixture, HelloWorld) -{ - EXPECT_TRUE(true); -} - -TEST_F(SettingsFixture, BoolProperties) -{ - TestBoolProperty(m_settings->show_seconds, SETTINGS_SHOW_SECONDS_S); - TestBoolProperty(m_settings->show_calendar, SETTINGS_SHOW_CALENDAR_S); - TestBoolProperty(m_settings->show_clock, SETTINGS_SHOW_CLOCK_S); - TestBoolProperty(m_settings->show_date, SETTINGS_SHOW_DATE_S); - TestBoolProperty(m_settings->show_day, SETTINGS_SHOW_DAY_S); - TestBoolProperty(m_settings->show_detected_location, SETTINGS_SHOW_DETECTED_S); - TestBoolProperty(m_settings->show_events, SETTINGS_SHOW_EVENTS_S); - TestBoolProperty(m_settings->show_locations, SETTINGS_SHOW_LOCATIONS_S); - TestBoolProperty(m_settings->show_week_numbers, SETTINGS_SHOW_WEEK_NUMBERS_S); - TestBoolProperty(m_settings->show_year, SETTINGS_SHOW_YEAR_S); -} - -TEST_F(SettingsFixture, StringProperties) -{ - TestStringProperty(m_settings->custom_time_format, SETTINGS_CUSTOM_TIME_FORMAT_S); - TestStringProperty(m_settings->timezone_name, SETTINGS_TIMEZONE_NAME_S); -} - -TEST_F(SettingsFixture, TimeFormatMode) -{ - const auto key = SETTINGS_TIME_FORMAT_S; - const TimeFormatMode modes[] = { TIME_FORMAT_MODE_LOCALE_DEFAULT, - TIME_FORMAT_MODE_12_HOUR, - TIME_FORMAT_MODE_24_HOUR, - TIME_FORMAT_MODE_CUSTOM }; - - for(const auto& mode : modes) - { - g_settings_set_enum(m_gsettings, key, mode); - EXPECT_EQ(mode, m_settings->time_format_mode.get()); - } - - for(const auto& mode : modes) - { - m_settings->time_format_mode.set(mode); - EXPECT_EQ(mode, g_settings_get_enum(m_gsettings, key)); - } -} - -namespace -{ - std::vector strv_to_vector(const gchar** strv) - { - std::vector v; - for(int i=0; strv && strv[i]; i++) - v.push_back(strv[i]); - return v; - } -}; - -TEST_F(SettingsFixture, Locations) -{ - const auto key = SETTINGS_LOCATIONS_S; - - const gchar* astrv[] = {"America/Los_Angeles Oakland", "America/Chicago Oklahoma City", "Europe/London London", NULL}; - const gchar* bstrv[] = {"America/Denver", "Europe/London London", "Europe/Berlin Berlin", NULL}; - const std::vector av = strv_to_vector(astrv); - const std::vector bv = strv_to_vector(bstrv); - - g_settings_set_strv(m_gsettings, key, astrv); - EXPECT_EQ(av, m_settings->locations.get()); - g_settings_set_strv(m_gsettings, key, bstrv); - EXPECT_EQ(bv, m_settings->locations.get()); - - m_settings->locations.set(av); - auto tmp = g_settings_get_strv(m_gsettings, key); - auto vtmp = strv_to_vector((const gchar**)tmp); - g_strfreev(tmp); - EXPECT_EQ(av, vtmp); - - m_settings->locations.set(bv); - tmp = g_settings_get_strv(m_gsettings, key); - vtmp = strv_to_vector((const gchar**)tmp); - g_strfreev(tmp); - EXPECT_EQ(bv, vtmp); -} - -#if 0 - core::Property> locations; - core::Property time_format_mode; - -#endif diff --git a/tests/test-settings.cpp b/tests/test-settings.cpp new file mode 100644 index 0000000..9e52197 --- /dev/null +++ b/tests/test-settings.cpp @@ -0,0 +1,197 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "glib-fixture.h" + +#include +#include + +using namespace unity::indicator::datetime; + +/*** +**** +***/ + +class SettingsFixture: public GlibFixture +{ +private: + typedef GlibFixture super; + +protected: + + std::shared_ptr m_live; + std::shared_ptr m_settings; + GSettings * m_gsettings; + + virtual void SetUp() + { + super::SetUp(); + + m_gsettings = g_settings_new(SETTINGS_INTERFACE); + m_live.reset(new LiveSettings); + m_settings = std::dynamic_pointer_cast(m_live); + } + + virtual void TearDown() + { + g_clear_object(&m_gsettings); + m_settings.reset(); + m_live.reset(); + + super::TearDown(); + } + + void TestBoolProperty(core::Property& property, const gchar* key) + { + EXPECT_EQ(g_settings_get_boolean(m_gsettings, key), property.get()); + g_settings_set_boolean(m_gsettings, key, false); + EXPECT_EQ(false, property.get()); + g_settings_set_boolean(m_gsettings, key, true); + EXPECT_EQ(true, property.get()); + + property.set(false); + EXPECT_EQ(false, g_settings_get_boolean(m_gsettings, key)); + property.set(true); + EXPECT_EQ(true, g_settings_get_boolean(m_gsettings, key)); + } + + void TestStringProperty(core::Property& property, const gchar* key) + { + gchar* tmp; + std::string str; + + tmp = g_settings_get_string(m_gsettings, key); + EXPECT_EQ(tmp, property.get()); + g_clear_pointer(&tmp, g_free); + + str = "a"; + g_settings_set_string(m_gsettings, key, str.c_str()); + EXPECT_EQ(str, property.get()); + + str = "b"; + g_settings_set_string(m_gsettings, key, str.c_str()); + EXPECT_EQ(str, property.get()); + + str = "a"; + property.set(str); + tmp = g_settings_get_string(m_gsettings, key); + EXPECT_EQ(str, tmp); + g_clear_pointer(&tmp, g_free); + + str = "b"; + property.set(str); + tmp = g_settings_get_string(m_gsettings, key); + EXPECT_EQ(str, tmp); + g_clear_pointer(&tmp, g_free); + } +}; + +/*** +**** +***/ + +TEST_F(SettingsFixture, HelloWorld) +{ + EXPECT_TRUE(true); +} + +TEST_F(SettingsFixture, BoolProperties) +{ + TestBoolProperty(m_settings->show_seconds, SETTINGS_SHOW_SECONDS_S); + TestBoolProperty(m_settings->show_calendar, SETTINGS_SHOW_CALENDAR_S); + TestBoolProperty(m_settings->show_clock, SETTINGS_SHOW_CLOCK_S); + TestBoolProperty(m_settings->show_date, SETTINGS_SHOW_DATE_S); + TestBoolProperty(m_settings->show_day, SETTINGS_SHOW_DAY_S); + TestBoolProperty(m_settings->show_detected_location, SETTINGS_SHOW_DETECTED_S); + TestBoolProperty(m_settings->show_events, SETTINGS_SHOW_EVENTS_S); + TestBoolProperty(m_settings->show_locations, SETTINGS_SHOW_LOCATIONS_S); + TestBoolProperty(m_settings->show_week_numbers, SETTINGS_SHOW_WEEK_NUMBERS_S); + TestBoolProperty(m_settings->show_year, SETTINGS_SHOW_YEAR_S); +} + +TEST_F(SettingsFixture, StringProperties) +{ + TestStringProperty(m_settings->custom_time_format, SETTINGS_CUSTOM_TIME_FORMAT_S); + TestStringProperty(m_settings->timezone_name, SETTINGS_TIMEZONE_NAME_S); +} + +TEST_F(SettingsFixture, TimeFormatMode) +{ + const auto key = SETTINGS_TIME_FORMAT_S; + const TimeFormatMode modes[] = { TIME_FORMAT_MODE_LOCALE_DEFAULT, + TIME_FORMAT_MODE_12_HOUR, + TIME_FORMAT_MODE_24_HOUR, + TIME_FORMAT_MODE_CUSTOM }; + + for(const auto& mode : modes) + { + g_settings_set_enum(m_gsettings, key, mode); + EXPECT_EQ(mode, m_settings->time_format_mode.get()); + } + + for(const auto& mode : modes) + { + m_settings->time_format_mode.set(mode); + EXPECT_EQ(mode, g_settings_get_enum(m_gsettings, key)); + } +} + +namespace +{ + std::vector strv_to_vector(const gchar** strv) + { + std::vector v; + for(int i=0; strv && strv[i]; i++) + v.push_back(strv[i]); + return v; + } +}; + +TEST_F(SettingsFixture, Locations) +{ + const auto key = SETTINGS_LOCATIONS_S; + + const gchar* astrv[] = {"America/Los_Angeles Oakland", "America/Chicago Oklahoma City", "Europe/London London", NULL}; + const gchar* bstrv[] = {"America/Denver", "Europe/London London", "Europe/Berlin Berlin", NULL}; + const std::vector av = strv_to_vector(astrv); + const std::vector bv = strv_to_vector(bstrv); + + g_settings_set_strv(m_gsettings, key, astrv); + EXPECT_EQ(av, m_settings->locations.get()); + g_settings_set_strv(m_gsettings, key, bstrv); + EXPECT_EQ(bv, m_settings->locations.get()); + + m_settings->locations.set(av); + auto tmp = g_settings_get_strv(m_gsettings, key); + auto vtmp = strv_to_vector((const gchar**)tmp); + g_strfreev(tmp); + EXPECT_EQ(av, vtmp); + + m_settings->locations.set(bv); + tmp = g_settings_get_strv(m_gsettings, key); + vtmp = strv_to_vector((const gchar**)tmp); + g_strfreev(tmp); + EXPECT_EQ(bv, vtmp); +} + +#if 0 + core::Property> locations; + core::Property time_format_mode; + +#endif diff --git a/tests/test-timezone-file.cc b/tests/test-timezone-file.cc deleted file mode 100644 index 453b353..0000000 --- a/tests/test-timezone-file.cc +++ /dev/null @@ -1,133 +0,0 @@ - -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "glib-fixture.h" - -#include - -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include - -#include // fopen() -//#include // chmod() -#include // sync() - -using unity::indicator::datetime::FileTimezone; - - -/*** -**** -***/ - -#define TIMEZONE_FILE (SANDBOX"/timezone") - -class TimezoneFixture: public GlibFixture -{ - private: - - typedef GlibFixture super; - - protected: - - virtual void SetUp() - { - super::SetUp(); - } - - virtual void TearDown() - { - super::TearDown(); - } - - public: - - /* convenience func to set the timezone file */ - void set_file(const std::string& text) - { - auto fp = fopen(TIMEZONE_FILE, "w+"); - fprintf(fp, "%s\n", text.c_str()); - fclose(fp); - sync(); - } -}; - - -/** - * Test that timezone-file warns, but doesn't crash, if the timezone file doesn't exist - */ -TEST_F(TimezoneFixture, NoFile) -{ - remove(TIMEZONE_FILE); - ASSERT_FALSE(g_file_test(TIMEZONE_FILE, G_FILE_TEST_EXISTS)); - - FileTimezone tz(TIMEZONE_FILE); - testLogCount(G_LOG_LEVEL_WARNING, 1); -} - - -/** - * Test that timezone-file picks up the initial value - */ -TEST_F(TimezoneFixture, InitialValue) -{ - const std::string expected_timezone = "America/Chicago"; - set_file(expected_timezone); - FileTimezone tz(TIMEZONE_FILE); - ASSERT_EQ(expected_timezone, tz.timezone.get()); -} - - -/** - * Test that clearing the timezone results in an empty string - */ -TEST_F(TimezoneFixture, ChangedValue) -{ - const std::string initial_timezone = "America/Chicago"; - const std::string changed_timezone = "America/New_York"; - set_file(initial_timezone); - - FileTimezone tz(TIMEZONE_FILE); - ASSERT_EQ(initial_timezone, tz.timezone.get()); - - bool changed = false; - auto connection = tz.timezone.changed().connect( - [&changed, this](const std::string& s){ - g_message("timezone changed to %s", s.c_str()); - changed = true; - g_main_loop_quit(loop); - }); - - g_idle_add([](gpointer gself){ - static_cast(gself)->set_file("America/New_York"); - // static_cast(gtz)->timezone.set("America/New_York"); - return G_SOURCE_REMOVE; - }, this);//&tz); - - g_main_loop_run(loop); - - ASSERT_TRUE(changed); - ASSERT_EQ(changed_timezone, tz.timezone.get()); -} diff --git a/tests/test-timezone-file.cpp b/tests/test-timezone-file.cpp new file mode 100644 index 0000000..453b353 --- /dev/null +++ b/tests/test-timezone-file.cpp @@ -0,0 +1,133 @@ + +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "glib-fixture.h" + +#include + +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include + +#include // fopen() +//#include // chmod() +#include // sync() + +using unity::indicator::datetime::FileTimezone; + + +/*** +**** +***/ + +#define TIMEZONE_FILE (SANDBOX"/timezone") + +class TimezoneFixture: public GlibFixture +{ + private: + + typedef GlibFixture super; + + protected: + + virtual void SetUp() + { + super::SetUp(); + } + + virtual void TearDown() + { + super::TearDown(); + } + + public: + + /* convenience func to set the timezone file */ + void set_file(const std::string& text) + { + auto fp = fopen(TIMEZONE_FILE, "w+"); + fprintf(fp, "%s\n", text.c_str()); + fclose(fp); + sync(); + } +}; + + +/** + * Test that timezone-file warns, but doesn't crash, if the timezone file doesn't exist + */ +TEST_F(TimezoneFixture, NoFile) +{ + remove(TIMEZONE_FILE); + ASSERT_FALSE(g_file_test(TIMEZONE_FILE, G_FILE_TEST_EXISTS)); + + FileTimezone tz(TIMEZONE_FILE); + testLogCount(G_LOG_LEVEL_WARNING, 1); +} + + +/** + * Test that timezone-file picks up the initial value + */ +TEST_F(TimezoneFixture, InitialValue) +{ + const std::string expected_timezone = "America/Chicago"; + set_file(expected_timezone); + FileTimezone tz(TIMEZONE_FILE); + ASSERT_EQ(expected_timezone, tz.timezone.get()); +} + + +/** + * Test that clearing the timezone results in an empty string + */ +TEST_F(TimezoneFixture, ChangedValue) +{ + const std::string initial_timezone = "America/Chicago"; + const std::string changed_timezone = "America/New_York"; + set_file(initial_timezone); + + FileTimezone tz(TIMEZONE_FILE); + ASSERT_EQ(initial_timezone, tz.timezone.get()); + + bool changed = false; + auto connection = tz.timezone.changed().connect( + [&changed, this](const std::string& s){ + g_message("timezone changed to %s", s.c_str()); + changed = true; + g_main_loop_quit(loop); + }); + + g_idle_add([](gpointer gself){ + static_cast(gself)->set_file("America/New_York"); + // static_cast(gtz)->timezone.set("America/New_York"); + return G_SOURCE_REMOVE; + }, this);//&tz); + + g_main_loop_run(loop); + + ASSERT_TRUE(changed); + ASSERT_EQ(changed_timezone, tz.timezone.get()); +} diff --git a/tests/test-timezone-geoclue.cc b/tests/test-timezone-geoclue.cc deleted file mode 100644 index 4bf08a7..0000000 --- a/tests/test-timezone-geoclue.cc +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * 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 . - */ - -#include "geoclue-fixture.h" - -#include - -//#include - -using unity::indicator::datetime::GeoclueTimezone; - -/*** -**** -***/ - -class TimezoneGeoclueFixture : public GeoclueFixture -{ -}; - -#if 0 -namespace -{ - struct EmitAddressChangedData - { - DbusTestDbusMock * mock = nullptr; - DbusTestDbusMockObject * obj_client = nullptr; - std::string timezone; - EmitAddressChangedData(DbusTestDbusMock * mock_, - DbusTestDbusMockObject * obj_client_, - const std::string& timezone_): mock(mock_), obj_client(obj_client_), timezone(timezone_) {} - }; - - gboolean emit_address_changed_idle(gpointer gdata) - { - auto data = static_cast(gdata); - - GError * error = nullptr; - dbus_test_dbus_mock_object_emit_signal(data->mock, data->obj_client, - "org.freedesktop.Geoclue.Address", - "AddressChanged", - G_VARIANT_TYPE("(ia{ss}(idd))"), - g_variant_new_parsed("(1385238033, {'timezone': 'America/Chicago'}, (3, 0.0, 0.0))"), - &error); - if (error) - { - g_warning("%s: %s", G_STRFUNC, error->message); - g_error_free(error); - } - - delete data; - return G_SOURCE_REMOVE; - } -} -#endif - -TEST_F(TimezoneGeoclueFixture, ChangeDetected) -{ -// const std::string timezone_1 = "America/Denver"; - const std::string timezone_2 = "America/Chicago"; - - GeoclueTimezone tz; - wait_msec(500); // wait for the bus to get set up - EXPECT_EQ(timezone_1, tz.timezone.get()); - - // start listening for a timezone change, then change the timezone - - bool changed = false; - auto connection = tz.timezone.changed().connect( - [&changed, this](const std::string& s){ - g_debug("timezone changed to %s", s.c_str()); - changed = true; - g_main_loop_quit(loop); - }); - - setGeoclueTimezoneOnIdle(timezone_2); - //g_timeout_add(50, emit_address_changed_idle, new EmitAddressChangedData(mock, obj_client, timezone_2.c_str())); - g_main_loop_run(loop); - EXPECT_EQ(timezone_2, tz.timezone.get()); -} - - diff --git a/tests/test-timezone-geoclue.cpp b/tests/test-timezone-geoclue.cpp new file mode 100644 index 0000000..4bf08a7 --- /dev/null +++ b/tests/test-timezone-geoclue.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * 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 . + */ + +#include "geoclue-fixture.h" + +#include + +//#include + +using unity::indicator::datetime::GeoclueTimezone; + +/*** +**** +***/ + +class TimezoneGeoclueFixture : public GeoclueFixture +{ +}; + +#if 0 +namespace +{ + struct EmitAddressChangedData + { + DbusTestDbusMock * mock = nullptr; + DbusTestDbusMockObject * obj_client = nullptr; + std::string timezone; + EmitAddressChangedData(DbusTestDbusMock * mock_, + DbusTestDbusMockObject * obj_client_, + const std::string& timezone_): mock(mock_), obj_client(obj_client_), timezone(timezone_) {} + }; + + gboolean emit_address_changed_idle(gpointer gdata) + { + auto data = static_cast(gdata); + + GError * error = nullptr; + dbus_test_dbus_mock_object_emit_signal(data->mock, data->obj_client, + "org.freedesktop.Geoclue.Address", + "AddressChanged", + G_VARIANT_TYPE("(ia{ss}(idd))"), + g_variant_new_parsed("(1385238033, {'timezone': 'America/Chicago'}, (3, 0.0, 0.0))"), + &error); + if (error) + { + g_warning("%s: %s", G_STRFUNC, error->message); + g_error_free(error); + } + + delete data; + return G_SOURCE_REMOVE; + } +} +#endif + +TEST_F(TimezoneGeoclueFixture, ChangeDetected) +{ +// const std::string timezone_1 = "America/Denver"; + const std::string timezone_2 = "America/Chicago"; + + GeoclueTimezone tz; + wait_msec(500); // wait for the bus to get set up + EXPECT_EQ(timezone_1, tz.timezone.get()); + + // start listening for a timezone change, then change the timezone + + bool changed = false; + auto connection = tz.timezone.changed().connect( + [&changed, this](const std::string& s){ + g_debug("timezone changed to %s", s.c_str()); + changed = true; + g_main_loop_quit(loop); + }); + + setGeoclueTimezoneOnIdle(timezone_2); + //g_timeout_add(50, emit_address_changed_idle, new EmitAddressChangedData(mock, obj_client, timezone_2.c_str())); + g_main_loop_run(loop); + EXPECT_EQ(timezone_2, tz.timezone.get()); +} + + diff --git a/tests/test-timezones.cc b/tests/test-timezones.cc deleted file mode 100644 index 3f02761..0000000 --- a/tests/test-timezones.cc +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - -#include "geoclue-fixture.h" - -#include -#include - -#include // std::shared_ptr - -#include // fopen() -#include // sync() - -using namespace unity::indicator::datetime; - -typedef GeoclueFixture TimezonesFixture; - -#define TIMEZONE_FILE (SANDBOX "/timezone") - -namespace -{ - /* convenience func to set the timezone file */ - void set_file(const std::string& text) - { - auto fp = fopen(TIMEZONE_FILE, "w+"); - fprintf(fp, "%s\n", text.c_str()); - fclose(fp); - sync(); - } -} - - -TEST_F(TimezonesFixture, ManagerTest) -{ - std::string timezone_file = "America/New_York"; - std::string timezone_geo = "America/Denver"; - - set_file(timezone_file); - std::shared_ptr settings(new Settings); - LiveTimezones z(settings, TIMEZONE_FILE); - wait_msec(500); // wait for the bus to get set up - EXPECT_EQ(timezone_file, z.timezone.get()); - auto zones = z.timezones.get(); - //std::set zones = z.timezones.get(); - EXPECT_EQ(1, zones.size()); - EXPECT_EQ(1, zones.count(timezone_file)); - - bool zone_changed = false; - auto zone_connection = z.timezone.changed().connect([&zone_changed, this](const std::string&) { - zone_changed = true; - g_main_loop_quit(loop); - }); - - // start listening for a timezone change, then change the timezone - bool zones_changed = false; - auto zones_connection = z.timezones.changed().connect([&zones_changed, &zones, this](const std::set& timezones) { - zones_changed = true; - zones = timezones; - g_main_loop_quit(loop); - }); - - g_idle_add([](gpointer s_in) { - auto s = static_cast(s_in); - g_message("geolocation was %d", (int)s->show_detected_location.get()); - g_message("turning geolocation on"); - s->show_detected_location.set(true); - return G_SOURCE_REMOVE; - }, settings.get()); - - // turn on geoclue during the idle... this should add timezone_1 to the 'timezones' property - g_main_loop_run(loop); - EXPECT_TRUE(zones_changed); - EXPECT_EQ(timezone_file, z.timezone.get()); - EXPECT_EQ(2, zones.size()); - EXPECT_EQ(1, zones.count(timezone_file)); - EXPECT_EQ(1, zones.count(timezone_geo)); - zones_changed = false; - - // now tweak the geoclue value... the geoclue-detected timezone should change, - // causing the 'timezones' property to change - zone_changed = false; - zones_changed = false; - timezone_geo = "America/Chicago"; - setGeoclueTimezoneOnIdle(timezone_geo); - g_main_loop_run(loop); - EXPECT_FALSE(zone_changed); - EXPECT_TRUE(zones_changed); - EXPECT_EQ(timezone_file, z.timezone.get()); - EXPECT_EQ(2, zones.size()); - EXPECT_EQ(1, zones.count(timezone_file)); - EXPECT_EQ(1, zones.count(timezone_geo)); - - // now set the file value... this should change both the primary property and set property - zone_changed = false; - zones_changed = false; - timezone_file = "America/Los_Angeles"; - EXPECT_EQ(0, zones.count(timezone_file)); - g_idle_add([](gpointer str) {set_file(static_cast(str)); return G_SOURCE_REMOVE;}, const_cast(timezone_file.c_str())); - g_main_loop_run(loop); - EXPECT_TRUE(zone_changed); - EXPECT_TRUE(zones_changed); - EXPECT_EQ(timezone_file, z.timezone.get()); - EXPECT_EQ(2, zones.size()); - EXPECT_EQ(1, zones.count(timezone_file)); - EXPECT_EQ(1, zones.count(timezone_geo)); -} - - diff --git a/tests/test-timezones.cpp b/tests/test-timezones.cpp new file mode 100644 index 0000000..3f02761 --- /dev/null +++ b/tests/test-timezones.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include "geoclue-fixture.h" + +#include +#include + +#include // std::shared_ptr + +#include // fopen() +#include // sync() + +using namespace unity::indicator::datetime; + +typedef GeoclueFixture TimezonesFixture; + +#define TIMEZONE_FILE (SANDBOX "/timezone") + +namespace +{ + /* convenience func to set the timezone file */ + void set_file(const std::string& text) + { + auto fp = fopen(TIMEZONE_FILE, "w+"); + fprintf(fp, "%s\n", text.c_str()); + fclose(fp); + sync(); + } +} + + +TEST_F(TimezonesFixture, ManagerTest) +{ + std::string timezone_file = "America/New_York"; + std::string timezone_geo = "America/Denver"; + + set_file(timezone_file); + std::shared_ptr settings(new Settings); + LiveTimezones z(settings, TIMEZONE_FILE); + wait_msec(500); // wait for the bus to get set up + EXPECT_EQ(timezone_file, z.timezone.get()); + auto zones = z.timezones.get(); + //std::set zones = z.timezones.get(); + EXPECT_EQ(1, zones.size()); + EXPECT_EQ(1, zones.count(timezone_file)); + + bool zone_changed = false; + auto zone_connection = z.timezone.changed().connect([&zone_changed, this](const std::string&) { + zone_changed = true; + g_main_loop_quit(loop); + }); + + // start listening for a timezone change, then change the timezone + bool zones_changed = false; + auto zones_connection = z.timezones.changed().connect([&zones_changed, &zones, this](const std::set& timezones) { + zones_changed = true; + zones = timezones; + g_main_loop_quit(loop); + }); + + g_idle_add([](gpointer s_in) { + auto s = static_cast(s_in); + g_message("geolocation was %d", (int)s->show_detected_location.get()); + g_message("turning geolocation on"); + s->show_detected_location.set(true); + return G_SOURCE_REMOVE; + }, settings.get()); + + // turn on geoclue during the idle... this should add timezone_1 to the 'timezones' property + g_main_loop_run(loop); + EXPECT_TRUE(zones_changed); + EXPECT_EQ(timezone_file, z.timezone.get()); + EXPECT_EQ(2, zones.size()); + EXPECT_EQ(1, zones.count(timezone_file)); + EXPECT_EQ(1, zones.count(timezone_geo)); + zones_changed = false; + + // now tweak the geoclue value... the geoclue-detected timezone should change, + // causing the 'timezones' property to change + zone_changed = false; + zones_changed = false; + timezone_geo = "America/Chicago"; + setGeoclueTimezoneOnIdle(timezone_geo); + g_main_loop_run(loop); + EXPECT_FALSE(zone_changed); + EXPECT_TRUE(zones_changed); + EXPECT_EQ(timezone_file, z.timezone.get()); + EXPECT_EQ(2, zones.size()); + EXPECT_EQ(1, zones.count(timezone_file)); + EXPECT_EQ(1, zones.count(timezone_geo)); + + // now set the file value... this should change both the primary property and set property + zone_changed = false; + zones_changed = false; + timezone_file = "America/Los_Angeles"; + EXPECT_EQ(0, zones.count(timezone_file)); + g_idle_add([](gpointer str) {set_file(static_cast(str)); return G_SOURCE_REMOVE;}, const_cast(timezone_file.c_str())); + g_main_loop_run(loop); + EXPECT_TRUE(zone_changed); + EXPECT_TRUE(zones_changed); + EXPECT_EQ(timezone_file, z.timezone.get()); + EXPECT_EQ(2, zones.size()); + EXPECT_EQ(1, zones.count(timezone_file)); + EXPECT_EQ(1, zones.count(timezone_geo)); +} + + diff --git a/tests/test-utils.cc b/tests/test-utils.cc deleted file mode 100644 index 2fe6a2e..0000000 --- a/tests/test-utils.cc +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013 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 . - * - * Authors: - * Charles Kerr - */ - -#include - -#include - -TEST(UtilsTest, SplitSettingsLocation) -{ - struct { - const char* location; - const char* expected_zone; - const char* expected_name; - } test_cases[] = { - { "America/Chicago Chicago", "America/Chicago", "Chicago" }, - { "America/Chicago Oklahoma City", "America/Chicago", "Oklahoma City" }, - { "America/Los_Angeles", "America/Los_Angeles", "Los Angeles" }, - { "America/Los_Angeles ", "America/Los_Angeles", "Los Angeles" }, - { " America/Los_Angeles", "America/Los_Angeles", "Los Angeles" }, - { " America/Los_Angeles ", "America/Los_Angeles", "Los Angeles" }, - { "UTC UTC", "UTC", "UTC" } - }; - - for(const auto& test_case : test_cases) - { - char * zone = nullptr; - char * name = nullptr; - - split_settings_location(test_case.location, &zone, &name); - ASSERT_STREQ(test_case.expected_zone, zone); - ASSERT_STREQ(test_case.expected_name, name); - - g_free(zone); - g_free(name); - } -} - -TEST(UtilsTest, BeautifulTimezoneName) -{ - struct { - const char* timezone; - const char* location; - const char* expected_name; - } test_cases[] = { - { "America/Chicago", NULL, "Chicago" }, - { "America/Chicago", "America/Chicago", "Chicago" }, - { "America/Chicago", "America/Chigago Chicago", "Chicago" }, - { "America/Chicago", "America/Chicago Oklahoma City", "Oklahoma City" }, - { "America/Chicago", "Europe/London London", "Chicago" } - }; - - for(const auto& test_case : test_cases) - { - auto name = get_beautified_timezone_name(test_case.timezone, test_case.location); - EXPECT_STREQ(test_case.expected_name, name); - g_free(name); - } -} diff --git a/tests/test-utils.cpp b/tests/test-utils.cpp new file mode 100644 index 0000000..2fe6a2e --- /dev/null +++ b/tests/test-utils.cpp @@ -0,0 +1,74 @@ +/* + * Copyright 2013 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 . + * + * Authors: + * Charles Kerr + */ + +#include + +#include + +TEST(UtilsTest, SplitSettingsLocation) +{ + struct { + const char* location; + const char* expected_zone; + const char* expected_name; + } test_cases[] = { + { "America/Chicago Chicago", "America/Chicago", "Chicago" }, + { "America/Chicago Oklahoma City", "America/Chicago", "Oklahoma City" }, + { "America/Los_Angeles", "America/Los_Angeles", "Los Angeles" }, + { "America/Los_Angeles ", "America/Los_Angeles", "Los Angeles" }, + { " America/Los_Angeles", "America/Los_Angeles", "Los Angeles" }, + { " America/Los_Angeles ", "America/Los_Angeles", "Los Angeles" }, + { "UTC UTC", "UTC", "UTC" } + }; + + for(const auto& test_case : test_cases) + { + char * zone = nullptr; + char * name = nullptr; + + split_settings_location(test_case.location, &zone, &name); + ASSERT_STREQ(test_case.expected_zone, zone); + ASSERT_STREQ(test_case.expected_name, name); + + g_free(zone); + g_free(name); + } +} + +TEST(UtilsTest, BeautifulTimezoneName) +{ + struct { + const char* timezone; + const char* location; + const char* expected_name; + } test_cases[] = { + { "America/Chicago", NULL, "Chicago" }, + { "America/Chicago", "America/Chicago", "Chicago" }, + { "America/Chicago", "America/Chigago Chicago", "Chicago" }, + { "America/Chicago", "America/Chicago Oklahoma City", "Oklahoma City" }, + { "America/Chicago", "Europe/London London", "Chicago" } + }; + + for(const auto& test_case : test_cases) + { + auto name = get_beautified_timezone_name(test_case.timezone, test_case.location); + EXPECT_STREQ(test_case.expected_name, name); + g_free(name); + } +} -- cgit v1.2.3