diff options
-rw-r--r-- | .build.yml | 8 | ||||
-rw-r--r-- | tests/accounts-service-user.cc | 320 | ||||
-rw-r--r-- | tests/dbus-types/dbus-action-result.h | 7 | ||||
-rw-r--r-- | tests/indicator-fixture.h | 930 | ||||
-rw-r--r-- | tests/integration/indicator-sound-test-base.cpp | 11 | ||||
-rw-r--r-- | tests/integration/test-indicator.cpp | 8 | ||||
-rw-r--r-- | tests/integration/utils/dbus-pulse-volume.cpp | 12 | ||||
-rw-r--r-- | tests/media-player-user.cc | 500 | ||||
-rw-r--r-- | tests/name-watch-test.cc | 190 | ||||
-rw-r--r-- | tests/notifications-mock.h | 5 | ||||
-rw-r--r-- | tests/notifications-test.cc | 13 | ||||
-rw-r--r-- | tests/service-mocks/media-player-mpris-mock/MediaPlayerMprisMock.h | 9 | ||||
-rw-r--r-- | tests/volume-control-test.cc | 6 |
13 files changed, 1025 insertions, 994 deletions
@@ -212,7 +212,11 @@ before_scripts: - git clone --depth 1 https://github.com/AyatanaIndicators/libayatana-common.git libayatana-common-build - fi - cd libayatana-common-build - - cmake . -DCMAKE_INSTALL_PREFIX=/usr + - if [ ${DISTRO_NAME} == "debian" ]; then + - cmake . -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LOMIRI_FEATURES=ON + - else + - cmake . -DCMAKE_INSTALL_PREFIX=/usr + - fi - make - make install - cd - @@ -264,7 +268,7 @@ before_scripts: build_scripts: - if [ ${DISTRO_NAME} == "debian" ];then - export CFLAGS+=" -Wsign-compare -Wunused-parameter" - - cppcheck --enable=warning,style,performance,portability,information,missingInclude . + - cppcheck --enable=warning,style,performance,portability,information,missingInclude --inline-suppr --library=qt --suppress=missingInclude . - fi - - if [ -e ./CMakeLists.txt ]; then diff --git a/tests/accounts-service-user.cc b/tests/accounts-service-user.cc index 3c2ec3f..77c55ca 100644 --- a/tests/accounts-service-user.cc +++ b/tests/accounts-service-user.cc @@ -1,5 +1,6 @@ /* * Copyright 2014 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ * * Authors: * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> */ #include <gtest/gtest.h> @@ -32,169 +34,169 @@ extern "C" { class AccountsServiceUserTest : public ::testing::Test { - protected: - DbusTestService * service = NULL; - DbusTestDbusMock * mock = NULL; - - GDBusConnection * session = NULL; - GDBusConnection * system = NULL; - GDBusProxy * proxy = NULL; - - virtual void SetUp() { - service = dbus_test_service_new(NULL); - dbus_test_service_set_bus(service, DBUS_TEST_SERVICE_BUS_BOTH); - - AccountsServiceMock service_mock; - - dbus_test_service_add_task(service, (DbusTestTask*)service_mock); - dbus_test_service_start_tasks(service); - - session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); - ASSERT_NE(nullptr, session); - g_dbus_connection_set_exit_on_close(session, FALSE); - g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session); - - system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); - ASSERT_NE(nullptr, system); - g_dbus_connection_set_exit_on_close(system, FALSE); - g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); - - proxy = g_dbus_proxy_new_sync(session, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - "/user", - "org.freedesktop.DBus.Properties", - NULL, NULL); - ASSERT_NE(nullptr, proxy); - } - - virtual void TearDown() { - g_clear_object(&proxy); - g_clear_object(&mock); - g_clear_object(&service); - - g_object_unref(session); - g_object_unref(system); - - #if 0 - /* Accounts Service keeps a bunch of references around so we - have to split the tests and can't check this :-( */ - unsigned int cleartry = 0; - while ((session != NULL || system != NULL) && cleartry < 100) { - loop(100); - cleartry++; - } - - ASSERT_EQ(nullptr, session); - ASSERT_EQ(nullptr, system); - #endif - } - - static gboolean timeout_cb (gpointer user_data) { - GMainLoop * loop = static_cast<GMainLoop *>(user_data); - g_main_loop_quit(loop); - return G_SOURCE_REMOVE; - } - - void loop (unsigned int ms) { - GMainLoop * loop = g_main_loop_new(NULL, FALSE); - g_timeout_add(ms, timeout_cb, loop); - g_main_loop_run(loop); - g_main_loop_unref(loop); - } - - static int unref_idle (gpointer user_data) { - g_variant_unref(static_cast<GVariant *>(user_data)); - return G_SOURCE_REMOVE; - } - - const gchar * get_property_string (const gchar * name) { - GVariant * propval = g_dbus_proxy_call_sync(proxy, - "Get", - g_variant_new("(ss)", "org.ayatana.indicator.sound.AccountsService", name), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, NULL - ); - - if (propval == nullptr) { - return nullptr; - } - - /* NOTE: This is a bit of a hack, basically if main gets - called the returned string becomes invalid. But it - makes the test much easier to read :-/ */ - g_idle_add(unref_idle, propval); - - const gchar * ret = NULL; - GVariant * child = g_variant_get_child_value(propval, 0); - GVariant * vstr = g_variant_get_variant(child); - ret = g_variant_get_string(vstr, NULL); - g_variant_unref(vstr); - g_variant_unref(child); - - return ret; - } + protected: + DbusTestService * service = NULL; + DbusTestDbusMock * mock = NULL; + + GDBusConnection * session = NULL; + GDBusConnection * system = NULL; + GDBusProxy * proxy = NULL; + + virtual void SetUp() { + service = dbus_test_service_new(NULL); + dbus_test_service_set_bus(service, DBUS_TEST_SERVICE_BUS_BOTH); + + AccountsServiceMock service_mock; + + dbus_test_service_add_task(service, (DbusTestTask*)service_mock); + dbus_test_service_start_tasks(service); + + session = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL); + ASSERT_NE(nullptr, session); + g_dbus_connection_set_exit_on_close(session, FALSE); + g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session); + + system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); + ASSERT_NE(nullptr, system); + g_dbus_connection_set_exit_on_close(system, FALSE); + g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); + + proxy = g_dbus_proxy_new_sync(session, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + "/user", + "org.freedesktop.DBus.Properties", + NULL, NULL); + ASSERT_NE(nullptr, proxy); + } + + virtual void TearDown() { + g_clear_object(&proxy); + g_clear_object(&mock); + g_clear_object(&service); + + g_object_unref(session); + g_object_unref(system); + + #if 0 + /* Accounts Service keeps a bunch of references around so we + have to split the tests and can't check this :-( */ + unsigned int cleartry = 0; + while ((session != NULL || system != NULL) && cleartry < 100) { + loop(100); + cleartry++; + } + + ASSERT_EQ(nullptr, session); + ASSERT_EQ(nullptr, system); + #endif + } + + static gboolean timeout_cb (gpointer user_data) { + GMainLoop * pLoop = static_cast<GMainLoop *>(user_data); + g_main_loop_quit(pLoop); + return G_SOURCE_REMOVE; + } + + void loop (unsigned int ms) { + GMainLoop * loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(ms, timeout_cb, loop); + g_main_loop_run(loop); + g_main_loop_unref(loop); + } + + static int unref_idle (gpointer user_data) { + g_variant_unref(static_cast<GVariant *>(user_data)); + return G_SOURCE_REMOVE; + } + + const gchar * get_property_string (const gchar * name) { + GVariant * propval = g_dbus_proxy_call_sync(proxy, + "Get", + g_variant_new("(ss)", "org.ayatana.indicator.sound.AccountsService", name), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL + ); + + if (propval == nullptr) { + return nullptr; + } + + /* NOTE: This is a bit of a hack, basically if main gets + called the returned string becomes invalid. But it + makes the test much easier to read :-/ */ + g_idle_add(unref_idle, propval); + + const gchar * ret = NULL; + GVariant * child = g_variant_get_child_value(propval, 0); + GVariant * vstr = g_variant_get_variant(child); + ret = g_variant_get_string(vstr, NULL); + g_variant_unref(vstr); + g_variant_unref(child); + + return ret; + } }; TEST_F(AccountsServiceUserTest, BasicObject) { - AccountsServiceUser * srv = accounts_service_user_new(); - loop(50); - g_object_unref(srv); + AccountsServiceUser * srv = accounts_service_user_new(); + loop(50); + g_object_unref(srv); } TEST_F(AccountsServiceUserTest, SetMediaPlayer) { - MediaPlayerTrack * track = media_player_track_new("Artist", "Title", "Album", "http://art.url"); - - MediaPlayerMock * media = MEDIA_PLAYER_MOCK( - g_object_new(TYPE_MEDIA_PLAYER_MOCK, - "mock-id", "player-id", - "mock-name", "Test Player", - "mock-state", "Playing", - "mock-is-running", TRUE, - "mock-can-raise", FALSE, - "mock-current-track", track, - NULL) - ); - g_clear_object(&track); - - AccountsServiceUser * srv = accounts_service_user_new(); - - accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); - - loop(500); - - /* Verify the values are on the other side of the bus */ - EXPECT_STREQ("Test Player", get_property_string("PlayerName")); - EXPECT_STREQ("Playing", get_property_string("State")); - EXPECT_STREQ("Title", get_property_string("Title")); - EXPECT_STREQ("Artist", get_property_string("Artist")); - EXPECT_STREQ("Album", get_property_string("Album")); - EXPECT_STREQ("http://art.url", get_property_string("ArtUrl")); - - /* Check changing the track info */ - track = media_player_track_new("Artist-ish", "Title-like", "Psuedo Album", "http://fake.art.url"); - media_player_mock_set_mock_current_track(media, track); - g_clear_object(&track); - accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); - - loop(500); - - EXPECT_STREQ("Test Player", get_property_string("PlayerName")); - EXPECT_STREQ("Playing", get_property_string("State")); - EXPECT_STREQ("Title-like", get_property_string("Title")); - EXPECT_STREQ("Artist-ish", get_property_string("Artist")); - EXPECT_STREQ("Psuedo Album", get_property_string("Album")); - EXPECT_STREQ("http://fake.art.url", get_property_string("ArtUrl")); - - /* Check to ensure the state can be updated */ - media_player_set_state(MEDIA_PLAYER(media), "Paused"); - accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); - - loop(500); - - EXPECT_STREQ("Paused", get_property_string("State")); - - g_object_unref(media); - g_object_unref(srv); + MediaPlayerTrack * track = media_player_track_new("Artist", "Title", "Album", "http://art.url"); + + MediaPlayerMock * media = MEDIA_PLAYER_MOCK( + g_object_new(TYPE_MEDIA_PLAYER_MOCK, + "mock-id", "player-id", + "mock-name", "Test Player", + "mock-state", "Playing", + "mock-is-running", TRUE, + "mock-can-raise", FALSE, + "mock-current-track", track, + NULL) + ); + g_clear_object(&track); + + AccountsServiceUser * srv = accounts_service_user_new(); + + accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); + + loop(500); + + /* Verify the values are on the other side of the bus */ + EXPECT_STREQ("Test Player", get_property_string("PlayerName")); + EXPECT_STREQ("Playing", get_property_string("State")); + EXPECT_STREQ("Title", get_property_string("Title")); + EXPECT_STREQ("Artist", get_property_string("Artist")); + EXPECT_STREQ("Album", get_property_string("Album")); + EXPECT_STREQ("http://art.url", get_property_string("ArtUrl")); + + /* Check changing the track info */ + track = media_player_track_new("Artist-ish", "Title-like", "Psuedo Album", "http://fake.art.url"); + media_player_mock_set_mock_current_track(media, track); + g_clear_object(&track); + accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); + + loop(500); + + EXPECT_STREQ("Test Player", get_property_string("PlayerName")); + EXPECT_STREQ("Playing", get_property_string("State")); + EXPECT_STREQ("Title-like", get_property_string("Title")); + EXPECT_STREQ("Artist-ish", get_property_string("Artist")); + EXPECT_STREQ("Psuedo Album", get_property_string("Album")); + EXPECT_STREQ("http://fake.art.url", get_property_string("ArtUrl")); + + /* Check to ensure the state can be updated */ + media_player_set_state(MEDIA_PLAYER(media), "Paused"); + accounts_service_user_set_player(srv, MEDIA_PLAYER(media)); + + loop(500); + + EXPECT_STREQ("Paused", get_property_string("State")); + + g_object_unref(media); + g_object_unref(srv); } diff --git a/tests/dbus-types/dbus-action-result.h b/tests/dbus-types/dbus-action-result.h index 9371c69..e2795f6 100644 --- a/tests/dbus-types/dbus-action-result.h +++ b/tests/dbus-types/dbus-action-result.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2015 Canonical Ltd. + * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * 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 @@ -13,7 +14,9 @@ * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. * - * Author: Xavi Garcia <xavi.garcia.mena@canonical.com> + * Authors: + * Xavi Garcia <xavi.garcia.mena@canonical.com> + * Robert Tari <robert@tari.in> */ #pragma once diff --git a/tests/indicator-fixture.h b/tests/indicator-fixture.h index 3ba09c1..48e0ef7 100644 --- a/tests/indicator-fixture.h +++ b/tests/indicator-fixture.h @@ -1,5 +1,6 @@ /* * Copyright 2014 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ * * Authors: * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> */ #include <memory> @@ -29,496 +31,496 @@ class IndicatorFixture : public ::testing::Test { - private: - std::string _indicatorPath; - std::string _indicatorAddress; - std::vector<std::shared_ptr<DbusTestTask>> _mocks; - protected: - std::chrono::milliseconds _eventuallyTime; - - private: - class PerRunData { - public: - /* We're private in the fixture but other than that we don't care, - we don't leak out. This object's purpose isn't to hide data it is - to make the lifecycle of the items more clear. */ - std::shared_ptr<GMenuModel> _menu; - std::shared_ptr<GActionGroup> _actions; - DbusTestService * _session_service; - DbusTestService * _system_service; - DbusTestTask * _test_indicator; - DbusTestTask * _test_dummy; - GDBusConnection * _session; - GDBusConnection * _system; - - PerRunData (const std::string& indicatorPath, const std::string& indicatorAddress, std::vector<std::shared_ptr<DbusTestTask>>& mocks) - : _menu(nullptr) - , _session(nullptr) - { - _session_service = dbus_test_service_new(nullptr); - dbus_test_service_set_bus(_session_service, DBUS_TEST_SERVICE_BUS_SESSION); - - _system_service = dbus_test_service_new(nullptr); - dbus_test_service_set_bus(_system_service, DBUS_TEST_SERVICE_BUS_SYSTEM); - - _test_indicator = DBUS_TEST_TASK(dbus_test_process_new(indicatorPath.c_str())); - dbus_test_task_set_name(_test_indicator, "Indicator"); - dbus_test_service_add_task(_session_service, _test_indicator); - - _test_dummy = dbus_test_task_new(); - dbus_test_task_set_wait_for(_test_dummy, indicatorAddress.c_str()); - dbus_test_task_set_name(_test_dummy, "Dummy"); - dbus_test_service_add_task(_session_service, _test_dummy); - - std::for_each(mocks.begin(), mocks.end(), [this](std::shared_ptr<DbusTestTask> task) { - if (dbus_test_task_get_bus(task.get()) == DBUS_TEST_SERVICE_BUS_SYSTEM) { - dbus_test_service_add_task(_system_service, task.get()); - } else { - dbus_test_service_add_task(_session_service, task.get()); - } - }); - - g_debug("Starting System Bus"); - dbus_test_service_start_tasks(_system_service); - _system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); - g_dbus_connection_set_exit_on_close(_system, FALSE); - - g_debug("Starting Session Bus"); - dbus_test_service_start_tasks(_session_service); - _session = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); - g_dbus_connection_set_exit_on_close(_session, FALSE); - } - - virtual ~PerRunData (void) { - _menu.reset(); - _actions.reset(); - - /* D-Bus Test Stuff */ - g_clear_object(&_test_dummy); - g_clear_object(&_test_indicator); - g_clear_object(&_session_service); - g_clear_object(&_system_service); - - /* Wait for D-Bus session bus to go */ - if (!g_dbus_connection_is_closed(_session)) { - g_dbus_connection_close_sync(_session, nullptr, nullptr); - } - g_clear_object(&_session); - - if (!g_dbus_connection_is_closed(_system)) { - g_dbus_connection_close_sync(_system, nullptr, nullptr); - } - g_clear_object(&_system); - } - }; - - std::shared_ptr<PerRunData> run; - - public: - virtual ~IndicatorFixture() = default; - - IndicatorFixture (const std::string& path, - const std::string& addr) - : _indicatorPath(path) - , _indicatorAddress(addr) - , _eventuallyTime(std::chrono::seconds(5)) - { - }; - - - protected: - virtual void SetUp() override - { - run = std::make_shared<PerRunData>(_indicatorPath, _indicatorAddress, _mocks); - - _mocks.clear(); - } - - virtual void TearDown() override - { - run.reset(); - } - - void addMock (std::shared_ptr<DbusTestTask> mock) - { - _mocks.push_back(mock); - } - - std::shared_ptr<DbusTestTask> buildBustleMock (const std::string& filename, DbusTestServiceBus bus = DBUS_TEST_SERVICE_BUS_BOTH) - { - return std::shared_ptr<DbusTestTask>([filename, bus]() { - DbusTestTask * bustle = DBUS_TEST_TASK(dbus_test_bustle_new(filename.c_str())); - dbus_test_task_set_name(bustle, "Bustle"); - dbus_test_task_set_bus(bustle, bus); - return bustle; - }(), [](DbusTestTask * bustle) { - g_clear_object(&bustle); - }); - } - - private: - void waitForCore (GObject * obj, const gchar * signalname) { - auto loop = g_main_loop_new(nullptr, FALSE); - - /* Our two exit criteria */ - gulong signal = g_signal_connect_swapped(obj, signalname, G_CALLBACK(g_main_loop_quit), loop); - guint timer = g_timeout_add_seconds(5, [](gpointer user_data) -> gboolean { - g_warning("Menu Timeout"); - g_main_loop_quit((GMainLoop *)user_data); - return G_SOURCE_CONTINUE; - }, loop); - - /* Wait for sync */ - g_main_loop_run(loop); - - /* Clean up */ - g_source_remove(timer); - g_signal_handler_disconnect(obj, signal); - - g_main_loop_unref(loop); - } - - void menuWaitForItems (const std::shared_ptr<GMenuModel>& menu) { - auto count = g_menu_model_get_n_items(menu.get()); - - if (count != 0) - return; - - waitForCore(G_OBJECT(menu.get()), "items-changed"); - } - - void agWaitForActions (const std::shared_ptr<GActionGroup>& group) { - auto list = std::shared_ptr<gchar *>( - g_action_group_list_actions(group.get()), - [](gchar ** list) { - g_strfreev(list); - }); - - if (g_strv_length(list.get()) != 0) { - return; - } - - waitForCore(G_OBJECT(group.get()), "action-added"); - } - - testing::AssertionResult expectEventually (std::function<testing::AssertionResult(void)> &testfunc) { - auto loop = std::shared_ptr<GMainLoop>(g_main_loop_new(nullptr, FALSE), [](GMainLoop * loop) { if (loop != nullptr) g_main_loop_unref(loop); }); - - std::promise<testing::AssertionResult> retpromise; - auto retfuture = retpromise.get_future(); - auto start = std::chrono::steady_clock::now(); - - /* The core of the idle function as an object so we can use the C++-isms - of attaching the variables and make this code reasonably readable */ - std::function<void(void)> idlefunc = [&loop, &retpromise, &testfunc, &start, this]() -> void { - auto result = testfunc(); - - if (result == false && _eventuallyTime > (std::chrono::steady_clock::now() - start)) { - return; - } - - retpromise.set_value(result); - g_main_loop_quit(loop.get()); - }; - - auto idlesrc = g_idle_add([](gpointer data) -> gboolean { - auto func = reinterpret_cast<std::function<void(void)> *>(data); - (*func)(); - return G_SOURCE_CONTINUE; - }, &idlefunc); - - g_main_loop_run(loop.get()); - g_source_remove(idlesrc); - - return retfuture.get(); - } - - protected: - void setMenu (const std::string& path) { - run->_menu.reset(); - - g_debug("Getting Menu: %s:%s", _indicatorAddress.c_str(), path.c_str()); - run->_menu = std::shared_ptr<GMenuModel>(G_MENU_MODEL(g_dbus_menu_model_get(run->_session, _indicatorAddress.c_str(), path.c_str())), [](GMenuModel * modelptr) { - g_clear_object(&modelptr); - }); - - menuWaitForItems(run->_menu); - } - - void setActions (const std::string& path) { - run->_actions.reset(); - - run->_actions = std::shared_ptr<GActionGroup>(G_ACTION_GROUP(g_dbus_action_group_get(run->_session, _indicatorAddress.c_str(), path.c_str())), [](GActionGroup * groupptr) { - g_clear_object(&groupptr); - }); - - agWaitForActions(run->_actions); - } - - testing::AssertionResult expectActionExists (const gchar * nameStr, const std::string& name) { - bool hasit = g_action_group_has_action(run->_actions.get(), name.c_str()); - - if (!hasit) { - auto result = testing::AssertionFailure(); - result << - " Action: " << nameStr << std::endl << - " Expected: " << "Exists" << std::endl << - " Actual: " << "No action found" << std::endl; - - return result; - } - - auto result = testing::AssertionSuccess(); - return result; - } - - template <typename... Args> testing::AssertionResult expectEventuallyActionStateExists (Args&& ... args) { - std::function<testing::AssertionResult(void)> func = [&]() { - return expectActionStateExists(std::forward<Args>(args)...); - }; - return expectEventually(func); - } - - testing::AssertionResult expectActionStateType (const char * nameStr, const char * typeStr, const std::string& name, const GVariantType * type) { - auto atype = g_action_group_get_action_state_type(run->_actions.get(), name.c_str()); - bool same = false; - - if (atype != nullptr) { - same = g_variant_type_equal(atype, type); - } - - if (!same) { - auto result = testing::AssertionFailure(); - result << - " Action: " << nameStr << std::endl << - " Expected: " << typeStr << std::endl << - " Actual: " << g_variant_type_peek_string(atype) << std::endl; - - return result; - } - - auto result = testing::AssertionSuccess(); - return result; - } - - template <typename... Args> testing::AssertionResult expectEventuallyActionStateType (Args&& ... args) { - std::function<testing::AssertionResult(void)> func = [&]() { - return expectActionStateType(std::forward<Args>(args)...); - }; - return expectEventually(func); - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, GVariant * value) { - auto varref = std::shared_ptr<GVariant>(g_variant_ref_sink(value), [](GVariant * varptr) { - if (varptr != nullptr) - g_variant_unref(varptr); - }); - auto aval = std::shared_ptr<GVariant>(g_action_group_get_action_state(run->_actions.get(), name.c_str()), [] (GVariant * varptr) { - if (varptr != nullptr) - g_variant_unref(varptr); - }); - bool match = false; - - if (aval != nullptr) { - match = g_variant_equal(aval.get(), varref.get()); - } - - if (!match) { - gchar * attstr = nullptr; - - if (aval != nullptr) { - attstr = g_variant_print(aval.get(), TRUE); - } else { - attstr = g_strdup("nullptr"); - } - - auto result = testing::AssertionFailure(); - result << - " Action: " << nameStr << std::endl << - " Expected: " << valueStr << std::endl << - " Actual: " << attstr << std::endl; - - g_free(attstr); - - return result; - } else { - auto result = testing::AssertionSuccess(); - return result; - } - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, bool value) { - GVariant * var = g_variant_new_boolean(value); - return expectActionStateIs(nameStr, valueStr, name, var); - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, std::string value) { - GVariant * var = g_variant_new_string(value.c_str()); - return expectActionStateIs(nameStr, valueStr, name, var); - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, const char * value) { - GVariant * var = g_variant_new_string(value); - return expectActionStateIs(nameStr, valueStr, name, var); - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, double value) { - GVariant * var = g_variant_new_double(value); - return expectActionStateIs(nameStr, valueStr, name, var); - } - - testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, float value) { - GVariant * var = g_variant_new_double(value); - return expectActionStateIs(nameStr, valueStr, name, var); - } - - template <typename... Args> testing::AssertionResult expectEventuallyActionStateIs (Args&& ... args) { - std::function<testing::AssertionResult(void)> func = [&]() { - return expectActionStateIs(std::forward<Args>(args)...); - }; - return expectEventually(func); - } - - - private: - std::shared_ptr<GVariant> getMenuAttributeVal (int location, std::shared_ptr<GMenuModel>& menu, const std::string& attribute, std::shared_ptr<GVariant>& value) { - if (!(location < g_menu_model_get_n_items(menu.get()))) { - return nullptr; - } - - if (location >= g_menu_model_get_n_items(menu.get())) - return nullptr; - - auto menuval = std::shared_ptr<GVariant>(g_menu_model_get_item_attribute_value(menu.get(), location, attribute.c_str(), g_variant_get_type(value.get())), [](GVariant * varptr) { - if (varptr != nullptr) - g_variant_unref(varptr); - }); - - return menuval; - } - - std::shared_ptr<GVariant> getMenuAttributeRecurse (std::vector<int>::const_iterator menuLocation, std::vector<int>::const_iterator menuEnd, const std::string& attribute, std::shared_ptr<GVariant>& value, std::shared_ptr<GMenuModel>& menu) { - if (menuLocation == menuEnd) - return nullptr; - - if (menuLocation + 1 == menuEnd) - return getMenuAttributeVal(*menuLocation, menu, attribute, value); - - auto clearfunc = [](GMenuModel * modelptr) { - g_clear_object(&modelptr); - }; - - auto submenu = std::shared_ptr<GMenuModel>(g_menu_model_get_item_link(menu.get(), *menuLocation, G_MENU_LINK_SUBMENU), clearfunc); - - if (submenu == nullptr) - submenu = std::shared_ptr<GMenuModel>(g_menu_model_get_item_link(menu.get(), *menuLocation, G_MENU_LINK_SECTION), clearfunc); - - if (submenu == nullptr) - return nullptr; - - menuWaitForItems(submenu); - - return getMenuAttributeRecurse(menuLocation + 1, menuEnd, attribute, value, submenu); - } - - protected: - testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int> menuLocation, const std::string& attribute, GVariant * value) { - auto varref = std::shared_ptr<GVariant>(g_variant_ref_sink(value), [](GVariant * varptr) { - if (varptr != nullptr) - g_variant_unref(varptr); - }); - - auto attrib = getMenuAttributeRecurse(menuLocation.cbegin(), menuLocation.cend(), attribute, varref, run->_menu); - bool same = false; - - if (attrib != nullptr && varref != nullptr) { - same = g_variant_equal(attrib.get(), varref.get()); - } - - if (!same) { - gchar * attstr = nullptr; - - if (attrib != nullptr) { - attstr = g_variant_print(attrib.get(), TRUE); - } else { - attstr = g_strdup("nullptr"); - } - - auto result = testing::AssertionFailure(); - result << - " Menu: " << menuLocationStr << std::endl << - " Attribute: " << attributeStr << std::endl << - " Expected: " << valueStr << std::endl << - " Actual: " << attstr << std::endl; - - g_free(attstr); - - return result; - } else { - auto result = testing::AssertionSuccess(); - return result; - } - } - - testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int> menuLocation, const std::string& attribute, bool value) { - GVariant * var = g_variant_new_boolean(value); - return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); - } - - testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int> menuLocation, const std::string& attribute, std::string value) { - GVariant * var = g_variant_new_string(value.c_str()); - return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); - } - - testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int> menuLocation, const std::string& attribute, const char * value) { - GVariant * var = g_variant_new_string(value); - return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); - } - - template <typename... Args> testing::AssertionResult expectEventuallyMenuAttribute (Args&& ... args) { - std::function<testing::AssertionResult(void)> func = [&]() { - return expectMenuAttribute(std::forward<Args>(args)...); - }; - return expectEventually(func); - } + private: + std::string _indicatorPath; + std::string _indicatorAddress; + std::vector<std::shared_ptr<DbusTestTask>> _mocks; + protected: + std::chrono::milliseconds _eventuallyTime; + + private: + class PerRunData { + public: + /* We're private in the fixture but other than that we don't care, + we don't leak out. This object's purpose isn't to hide data it is + to make the lifecycle of the items more clear. */ + std::shared_ptr<GMenuModel> _menu; + std::shared_ptr<GActionGroup> _actions; + DbusTestService * _session_service; + DbusTestService * _system_service; + DbusTestTask * _test_indicator; + DbusTestTask * _test_dummy; + GDBusConnection * _session; + GDBusConnection * _system; + + PerRunData (const std::string& indicatorPath, const std::string& indicatorAddress, std::vector<std::shared_ptr<DbusTestTask>>& mocks) + : _menu(nullptr) + , _session(nullptr) + { + _session_service = dbus_test_service_new(nullptr); + dbus_test_service_set_bus(_session_service, DBUS_TEST_SERVICE_BUS_SESSION); + + _system_service = dbus_test_service_new(nullptr); + dbus_test_service_set_bus(_system_service, DBUS_TEST_SERVICE_BUS_SYSTEM); + + _test_indicator = DBUS_TEST_TASK(dbus_test_process_new(indicatorPath.c_str())); + dbus_test_task_set_name(_test_indicator, "Indicator"); + dbus_test_service_add_task(_session_service, _test_indicator); + + _test_dummy = dbus_test_task_new(); + dbus_test_task_set_wait_for(_test_dummy, indicatorAddress.c_str()); + dbus_test_task_set_name(_test_dummy, "Dummy"); + dbus_test_service_add_task(_session_service, _test_dummy); + + std::for_each(mocks.begin(), mocks.end(), [this](std::shared_ptr<DbusTestTask> task) { + if (dbus_test_task_get_bus(task.get()) == DBUS_TEST_SERVICE_BUS_SYSTEM) { + dbus_test_service_add_task(_system_service, task.get()); + } else { + dbus_test_service_add_task(_session_service, task.get()); + } + }); + + g_debug("Starting System Bus"); + dbus_test_service_start_tasks(_system_service); + _system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, nullptr); + g_dbus_connection_set_exit_on_close(_system, FALSE); + + g_debug("Starting Session Bus"); + dbus_test_service_start_tasks(_session_service); + _session = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, nullptr); + g_dbus_connection_set_exit_on_close(_session, FALSE); + } + + virtual ~PerRunData (void) { + _menu.reset(); + _actions.reset(); + + /* D-Bus Test Stuff */ + g_clear_object(&_test_dummy); + g_clear_object(&_test_indicator); + g_clear_object(&_session_service); + g_clear_object(&_system_service); + + /* Wait for D-Bus session bus to go */ + if (!g_dbus_connection_is_closed(_session)) { + g_dbus_connection_close_sync(_session, nullptr, nullptr); + } + g_clear_object(&_session); + + if (!g_dbus_connection_is_closed(_system)) { + g_dbus_connection_close_sync(_system, nullptr, nullptr); + } + g_clear_object(&_system); + } + }; + + std::shared_ptr<PerRunData> run; + + public: + virtual ~IndicatorFixture() = default; + + IndicatorFixture (const std::string& path, + const std::string& addr) + : _indicatorPath(path) + , _indicatorAddress(addr) + , _eventuallyTime(std::chrono::seconds(5)) + { + }; + + + protected: + virtual void SetUp() override + { + run = std::make_shared<PerRunData>(_indicatorPath, _indicatorAddress, _mocks); + + _mocks.clear(); + } + + virtual void TearDown() override + { + run.reset(); + } + + void addMock (std::shared_ptr<DbusTestTask> mock) + { + _mocks.push_back(mock); + } + + std::shared_ptr<DbusTestTask> buildBustleMock (const std::string& filename, DbusTestServiceBus bus = DBUS_TEST_SERVICE_BUS_BOTH) + { + return std::shared_ptr<DbusTestTask>([filename, bus]() { + DbusTestTask * bustle = DBUS_TEST_TASK(dbus_test_bustle_new(filename.c_str())); + dbus_test_task_set_name(bustle, "Bustle"); + dbus_test_task_set_bus(bustle, bus); + return bustle; + }(), [](DbusTestTask * bustle) { + g_clear_object(&bustle); + }); + } + + private: + void waitForCore (GObject * obj, const gchar * signalname) { + auto loop = g_main_loop_new(nullptr, FALSE); + + /* Our two exit criteria */ + gulong signal = g_signal_connect_swapped(obj, signalname, G_CALLBACK(g_main_loop_quit), loop); + guint timer = g_timeout_add_seconds(5, [](gpointer user_data) -> gboolean { + g_warning("Menu Timeout"); + g_main_loop_quit((GMainLoop *)user_data); + return G_SOURCE_CONTINUE; + }, loop); + + /* Wait for sync */ + g_main_loop_run(loop); + + /* Clean up */ + g_source_remove(timer); + g_signal_handler_disconnect(obj, signal); + + g_main_loop_unref(loop); + } + + void menuWaitForItems (const std::shared_ptr<GMenuModel>& menu) { + auto count = g_menu_model_get_n_items(menu.get()); + + if (count != 0) + return; + + waitForCore(G_OBJECT(menu.get()), "items-changed"); + } + + void agWaitForActions (const std::shared_ptr<GActionGroup>& group) { + auto list = std::shared_ptr<gchar *>( + g_action_group_list_actions(group.get()), + [](gchar ** list) { + g_strfreev(list); + }); + + if (g_strv_length(list.get()) != 0) { + return; + } + + waitForCore(G_OBJECT(group.get()), "action-added"); + } + + testing::AssertionResult expectEventually (std::function<testing::AssertionResult(void)> &testfunc) { + auto loop = std::shared_ptr<GMainLoop>(g_main_loop_new(nullptr, FALSE), [](GMainLoop * loop) { if (loop != nullptr) g_main_loop_unref(loop); }); + + std::promise<testing::AssertionResult> retpromise; + auto retfuture = retpromise.get_future(); + auto start = std::chrono::steady_clock::now(); + + /* The core of the idle function as an object so we can use the C++-isms + of attaching the variables and make this code reasonably readable */ + std::function<void(void)> idlefunc = [&loop, &retpromise, &testfunc, &start, this]() -> void { + auto result = testfunc(); + + if (result == false && _eventuallyTime > (std::chrono::steady_clock::now() - start)) { + return; + } + + retpromise.set_value(result); + g_main_loop_quit(loop.get()); + }; + + auto idlesrc = g_idle_add([](gpointer data) -> gboolean { + auto func = reinterpret_cast<std::function<void(void)> *>(data); + (*func)(); + return G_SOURCE_CONTINUE; + }, &idlefunc); + + g_main_loop_run(loop.get()); + g_source_remove(idlesrc); + + return retfuture.get(); + } + + protected: + void setMenu (const std::string& path) { + run->_menu.reset(); + + g_debug("Getting Menu: %s:%s", _indicatorAddress.c_str(), path.c_str()); + run->_menu = std::shared_ptr<GMenuModel>(G_MENU_MODEL(g_dbus_menu_model_get(run->_session, _indicatorAddress.c_str(), path.c_str())), [](GMenuModel * modelptr) { + g_clear_object(&modelptr); + }); + + menuWaitForItems(run->_menu); + } + + void setActions (const std::string& path) { + run->_actions.reset(); + + run->_actions = std::shared_ptr<GActionGroup>(G_ACTION_GROUP(g_dbus_action_group_get(run->_session, _indicatorAddress.c_str(), path.c_str())), [](GActionGroup * groupptr) { + g_clear_object(&groupptr); + }); + + agWaitForActions(run->_actions); + } + + testing::AssertionResult expectActionExists (const gchar * nameStr, const std::string& name) { + bool hasit = g_action_group_has_action(run->_actions.get(), name.c_str()); + + if (!hasit) { + auto result = testing::AssertionFailure(); + result << + " Action: " << nameStr << std::endl << + " Expected: " << "Exists" << std::endl << + " Actual: " << "No action found" << std::endl; + + return result; + } + + auto result = testing::AssertionSuccess(); + return result; + } + + template <typename... Args> testing::AssertionResult expectEventuallyActionStateExists (Args&& ... args) { + std::function<testing::AssertionResult(void)> func = [&]() { + return expectActionStateExists(std::forward<Args>(args)...); + }; + return expectEventually(func); + } + + testing::AssertionResult expectActionStateType (const char * nameStr, const char * typeStr, const std::string& name, const GVariantType * type) { + auto atype = g_action_group_get_action_state_type(run->_actions.get(), name.c_str()); + bool same = false; + + if (atype != nullptr) { + same = g_variant_type_equal(atype, type); + } + + if (!same) { + auto result = testing::AssertionFailure(); + result << + " Action: " << nameStr << std::endl << + " Expected: " << typeStr << std::endl << + " Actual: " << g_variant_type_peek_string(atype) << std::endl; + + return result; + } + + auto result = testing::AssertionSuccess(); + return result; + } + + template <typename... Args> testing::AssertionResult expectEventuallyActionStateType (Args&& ... args) { + std::function<testing::AssertionResult(void)> func = [&]() { + return expectActionStateType(std::forward<Args>(args)...); + }; + return expectEventually(func); + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, GVariant * value) { + auto varref = std::shared_ptr<GVariant>(g_variant_ref_sink(value), [](GVariant * varptr) { + if (varptr != nullptr) + g_variant_unref(varptr); + }); + auto aval = std::shared_ptr<GVariant>(g_action_group_get_action_state(run->_actions.get(), name.c_str()), [] (GVariant * varptr) { + if (varptr != nullptr) + g_variant_unref(varptr); + }); + bool match = false; + + if (aval != nullptr) { + match = g_variant_equal(aval.get(), varref.get()); + } + + if (!match) { + gchar * attstr = nullptr; + + if (aval != nullptr) { + attstr = g_variant_print(aval.get(), TRUE); + } else { + attstr = g_strdup("nullptr"); + } + + auto result = testing::AssertionFailure(); + result << + " Action: " << nameStr << std::endl << + " Expected: " << valueStr << std::endl << + " Actual: " << attstr << std::endl; + + g_free(attstr); + + return result; + } else { + auto result = testing::AssertionSuccess(); + return result; + } + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, bool value) { + GVariant * var = g_variant_new_boolean(value); + return expectActionStateIs(nameStr, valueStr, name, var); + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, std::string value) { + GVariant * var = g_variant_new_string(value.c_str()); + return expectActionStateIs(nameStr, valueStr, name, var); + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, const char * value) { + GVariant * var = g_variant_new_string(value); + return expectActionStateIs(nameStr, valueStr, name, var); + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, double value) { + GVariant * var = g_variant_new_double(value); + return expectActionStateIs(nameStr, valueStr, name, var); + } + + testing::AssertionResult expectActionStateIs (const char * nameStr, const char * valueStr, const std::string& name, float value) { + GVariant * var = g_variant_new_double(value); + return expectActionStateIs(nameStr, valueStr, name, var); + } + + template <typename... Args> testing::AssertionResult expectEventuallyActionStateIs (Args&& ... args) { + std::function<testing::AssertionResult(void)> func = [&]() { + return expectActionStateIs(std::forward<Args>(args)...); + }; + return expectEventually(func); + } + + + private: + std::shared_ptr<GVariant> getMenuAttributeVal (int location, std::shared_ptr<GMenuModel>& menu, const std::string& attribute, std::shared_ptr<GVariant>& value) { + if (!(location < g_menu_model_get_n_items(menu.get()))) { + return nullptr; + } + + if (location >= g_menu_model_get_n_items(menu.get())) + return nullptr; + + auto menuval = std::shared_ptr<GVariant>(g_menu_model_get_item_attribute_value(menu.get(), location, attribute.c_str(), g_variant_get_type(value.get())), [](GVariant * varptr) { + if (varptr != nullptr) + g_variant_unref(varptr); + }); + + return menuval; + } + + std::shared_ptr<GVariant> getMenuAttributeRecurse (std::vector<int>::const_iterator menuLocation, std::vector<int>::const_iterator menuEnd, const std::string& attribute, std::shared_ptr<GVariant>& value, std::shared_ptr<GMenuModel>& menu) { + if (menuLocation == menuEnd) + return nullptr; + + if (menuLocation + 1 == menuEnd) + return getMenuAttributeVal(*menuLocation, menu, attribute, value); + + auto clearfunc = [](GMenuModel * modelptr) { + g_clear_object(&modelptr); + }; + + auto submenu = std::shared_ptr<GMenuModel>(g_menu_model_get_item_link(menu.get(), *menuLocation, G_MENU_LINK_SUBMENU), clearfunc); + + if (submenu == nullptr) + submenu = std::shared_ptr<GMenuModel>(g_menu_model_get_item_link(menu.get(), *menuLocation, G_MENU_LINK_SECTION), clearfunc); + + if (submenu == nullptr) + return nullptr; + + menuWaitForItems(submenu); + + return getMenuAttributeRecurse(menuLocation + 1, menuEnd, attribute, value, submenu); + } + + protected: + testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int>& menuLocation, const std::string& attribute, GVariant * value) { + auto varref = std::shared_ptr<GVariant>(g_variant_ref_sink(value), [](GVariant * varptr) { + if (varptr != nullptr) + g_variant_unref(varptr); + }); + + auto attrib = getMenuAttributeRecurse(menuLocation.cbegin(), menuLocation.cend(), attribute, varref, run->_menu); + bool same = false; + + if (attrib != nullptr && varref != nullptr) { + same = g_variant_equal(attrib.get(), varref.get()); + } + + if (!same) { + gchar * attstr = nullptr; + + if (attrib != nullptr) { + attstr = g_variant_print(attrib.get(), TRUE); + } else { + attstr = g_strdup("nullptr"); + } + + auto result = testing::AssertionFailure(); + result << + " Menu: " << menuLocationStr << std::endl << + " Attribute: " << attributeStr << std::endl << + " Expected: " << valueStr << std::endl << + " Actual: " << attstr << std::endl; + + g_free(attstr); + + return result; + } else { + auto result = testing::AssertionSuccess(); + return result; + } + } + + testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int>& menuLocation, const std::string& attribute, bool value) { + GVariant * var = g_variant_new_boolean(value); + return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); + } + + testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int>& menuLocation, const std::string& attribute, std::string value) { + GVariant * var = g_variant_new_string(value.c_str()); + return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); + } + + testing::AssertionResult expectMenuAttribute (const char * menuLocationStr, const char * attributeStr, const char * valueStr, const std::vector<int>& menuLocation, const std::string& attribute, const char * value) { + GVariant * var = g_variant_new_string(value); + return expectMenuAttribute(menuLocationStr, attributeStr, valueStr, menuLocation, attribute, var); + } + + template <typename... Args> testing::AssertionResult expectEventuallyMenuAttribute (Args&& ... args) { + std::function<testing::AssertionResult(void)> func = [&]() { + return expectMenuAttribute(std::forward<Args>(args)...); + }; + return expectEventually(func); + } }; /* Menu Attrib */ #define ASSERT_MENU_ATTRIB(menu, attrib, value) \ - ASSERT_PRED_FORMAT3(IndicatorFixture::expectMenuAttribute, menu, attrib, value) + ASSERT_PRED_FORMAT3(IndicatorFixture::expectMenuAttribute, menu, attrib, value) #define EXPECT_MENU_ATTRIB(menu, attrib, value) \ - EXPECT_PRED_FORMAT3(IndicatorFixture::expectMenuAttribute, menu, attrib, value) + EXPECT_PRED_FORMAT3(IndicatorFixture::expectMenuAttribute, menu, attrib, value) #define EXPECT_EVENTUALLY_MENU_ATTRIB(menu, attrib, value) \ - EXPECT_PRED_FORMAT3(IndicatorFixture::expectEventuallyMenuAttribute, menu, attrib, value) + EXPECT_PRED_FORMAT3(IndicatorFixture::expectEventuallyMenuAttribute, menu, attrib, value) /* Action Exists */ #define ASSERT_ACTION_EXISTS(action) \ - ASSERT_PRED_FORMAT1(IndicatorFixture::expectActionExists, action) + ASSERT_PRED_FORMAT1(IndicatorFixture::expectActionExists, action) #define EXPECT_ACTION_EXISTS(action) \ - EXPECT_PRED_FORMAT1(IndicatorFixture::expectActionExists, action) + EXPECT_PRED_FORMAT1(IndicatorFixture::expectActionExists, action) #define EXPECT_EVENTUALLY_ACTION_EXISTS(action) \ - EXPECT_PRED_FORMAT1(IndicatorFixture::expectEventuallyActionExists, action) + EXPECT_PRED_FORMAT1(IndicatorFixture::expectEventuallyActionExists, action) /* Action State */ #define ASSERT_ACTION_STATE(action, value) \ - ASSERT_PRED_FORMAT2(IndicatorFixture::expectActionStateIs, action, value) + ASSERT_PRED_FORMAT2(IndicatorFixture::expectActionStateIs, action, value) #define EXPECT_ACTION_STATE(action, value) \ - EXPECT_PRED_FORMAT2(IndicatorFixture::expectActionStateIs, action, value) + EXPECT_PRED_FORMAT2(IndicatorFixture::expectActionStateIs, action, value) #define EXPECT_EVENTUALLY_ACTION_STATE(action, value) \ - EXPECT_PRED_FORMAT2(IndicatorFixture::expectEventuallyActionStateIs, action, value) + EXPECT_PRED_FORMAT2(IndicatorFixture::expectEventuallyActionStateIs, action, value) /* Action State Type */ #define ASSERT_ACTION_STATE_TYPE(action, type) \ - ASSERT_PRED_FORMAT2(IndicatorFixture::expectActionStateType, action, type) + ASSERT_PRED_FORMAT2(IndicatorFixture::expectActionStateType, action, type) #define EXPECT_ACTION_STATE_TYPE(action, type) \ - EXPECT_PRED_FORMAT2(IndicatorFixture::expectActionStateType, action, type) + EXPECT_PRED_FORMAT2(IndicatorFixture::expectActionStateType, action, type) #define EXPECT_EVENTUALLY_ACTION_STATE_TYPE(action, type) \ - EXPECT_PRED_FORMAT2(IndicatorFixture::expectEventuallyActionStateType, action, type) + EXPECT_PRED_FORMAT2(IndicatorFixture::expectEventuallyActionStateType, action, type) diff --git a/tests/integration/indicator-sound-test-base.cpp b/tests/integration/indicator-sound-test-base.cpp index 1a74621..6c64815 100644 --- a/tests/integration/indicator-sound-test-base.cpp +++ b/tests/integration/indicator-sound-test-base.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2015 Canonical Ltd. - * Copyright (C) 2021 Robert Tari + * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * 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 @@ -534,9 +534,10 @@ void IndicatorSoundTestBase::initializeAccountsInterface() auto userPath = userResp.value().path(); if (userPath != "") { - std::unique_ptr<AccountsSoundInterface> soundInterface(new AccountsSoundInterface("org.freedesktop.Accounts", + // This silences cppcheck, but let's leave it here in case we actually need it + /*std::unique_ptr<AccountsSoundInterface> soundInterface(new AccountsSoundInterface("org.freedesktop.Accounts", userPath, - dbusTestRunner.systemConnection(), 0)); + dbusTestRunner.systemConnection(), 0));*/ accounts_interface_.reset(new DBusPropertiesInterface("org.freedesktop.Accounts", userPath, @@ -1008,8 +1009,6 @@ QVariantList IndicatorSoundTestBase::getActionValue(QString const &action) QStringList IndicatorSoundTestBase::getRootIconValue(bool *isValid) { - QString result = 0; - QVariantList varList = getActionValue("root"); if (isValid != nullptr) { diff --git a/tests/integration/test-indicator.cpp b/tests/integration/test-indicator.cpp index 5d31508..cbf1c6d 100644 --- a/tests/integration/test-indicator.cpp +++ b/tests/integration/test-indicator.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2015 Canonical Ltd. + * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * 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 @@ -13,7 +14,9 @@ * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. * - * Author: Xavi Garcia <xavi.garcia.mena@canonical.com> + * Authors: + * Xavi Garcia <xavi.garcia.mena@canonical.com> + * Robert Tari <robert@tari.in> */ #include <indicator-sound-test-base.h> @@ -32,6 +35,7 @@ class TestIndicator: public IndicatorSoundTestBase { }; +// cppcheck-suppress syntaxError TEST_F(TestIndicator, DISABLED_PhoneCheckRootIcon) { double INITIAL_VOLUME = 0.0; diff --git a/tests/integration/utils/dbus-pulse-volume.cpp b/tests/integration/utils/dbus-pulse-volume.cpp index 7d51b23..2bbc5d4 100644 --- a/tests/integration/utils/dbus-pulse-volume.cpp +++ b/tests/integration/utils/dbus-pulse-volume.cpp @@ -1,6 +1,6 @@ /* - * Copyright (C) 2015 Canonical Ltd. - * Copyright (C) 2021 Robert Tari + * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * 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 @@ -141,14 +141,14 @@ bool DBusPulseVolume::setVolume(QString const & role, double volume) if (accounts_interface_) { - QDBusVariant dbusVar(QVariant::fromValue(volume)); - QDBusReply<void> set_vol = accounts_interface_->call(QLatin1String("Set"), + QDBusVariant pDbusVar(QVariant::fromValue(volume)); + QDBusReply<void> pSetVol = accounts_interface_->call(QLatin1String("Set"), QVariant::fromValue(QString("com.lomiri.AccountsService.Sound")), QVariant::fromValue(QString("Volume")), - QVariant::fromValue(dbusVar)); + QVariant::fromValue(pDbusVar)); if (!set_vol.isValid()) { - qWarning() << "SetVolume::setVolume(): D-Bus error: " << set_vol.error().message(); + qWarning() << "SetVolume::setVolume(): D-Bus error: " << pSetVol.error().message(); return false; } } diff --git a/tests/media-player-user.cc b/tests/media-player-user.cc index eab996b..2bd4995 100644 --- a/tests/media-player-user.cc +++ b/tests/media-player-user.cc @@ -1,5 +1,6 @@ /* * Copyright 2014 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ * * Authors: * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> */ #include <chrono> @@ -33,288 +35,288 @@ extern "C" { class MediaPlayerUserTest : public ::testing::Test { - protected: - DbusTestService * testsystem = NULL; - AccountsServiceMock service_mock; - - DbusTestService * testsession = NULL; - - DbusTestProcess * systemmonitor = nullptr; - DbusTestProcess * sessionmonitor = nullptr; - - GDBusConnection * system = NULL; - GDBusConnection * session = NULL; - GDBusProxy * proxy = NULL; - - std::chrono::milliseconds _eventuallyTime = std::chrono::seconds{5}; - - virtual void SetUp() { - /* System Bus */ - testsystem = dbus_test_service_new(NULL); - dbus_test_service_set_bus(testsystem, DBUS_TEST_SERVICE_BUS_SYSTEM); - - systemmonitor = dbus_test_process_new("dbus-monitor"); - dbus_test_process_append_param(systemmonitor, "--system"); - dbus_test_task_set_name(DBUS_TEST_TASK(systemmonitor), "System"); - dbus_test_service_add_task(testsystem, DBUS_TEST_TASK(systemmonitor)); - - dbus_test_service_add_task(testsystem, (DbusTestTask*)service_mock); - dbus_test_service_start_tasks(testsystem); - - system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); - ASSERT_NE(nullptr, system); - g_dbus_connection_set_exit_on_close(system, FALSE); - g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); - - /* Session Bus */ - testsession = dbus_test_service_new(NULL); - dbus_test_service_set_bus(testsession, DBUS_TEST_SERVICE_BUS_SESSION); - - sessionmonitor = dbus_test_process_new("dbus-monitor"); - dbus_test_process_append_param(sessionmonitor, "--session"); - dbus_test_task_set_name(DBUS_TEST_TASK(sessionmonitor), "Session"); - dbus_test_service_add_task(testsession, DBUS_TEST_TASK(sessionmonitor)); - - dbus_test_service_start_tasks(testsession); - - session = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); - ASSERT_NE(nullptr, session); - g_dbus_connection_set_exit_on_close(session, FALSE); - g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session); - - /* Setup proxy */ - proxy = g_dbus_proxy_new_sync(system, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - "/user", - "org.freedesktop.DBus.Properties", - NULL, NULL); - ASSERT_NE(nullptr, proxy); - } - - virtual void TearDown() { - g_clear_object(&sessionmonitor); - g_clear_object(&systemmonitor); - - g_clear_object(&proxy); - g_clear_object(&testsystem); - g_clear_object(&testsession); - - g_object_unref(system); - g_object_unref(session); - - #if 0 - /* Accounts Service keeps a bunch of references around so we - have to split the tests and can't check this :-( */ - unsigned int cleartry = 0; - while ((session != NULL || system != NULL) && cleartry < 100) { - loop(100); - cleartry++; - } - - ASSERT_EQ(nullptr, session); - ASSERT_EQ(nullptr, system); - #endif - } - - static gboolean timeout_cb (gpointer user_data) { - GMainLoop * loop = static_cast<GMainLoop *>(user_data); - g_main_loop_quit(loop); - return G_SOURCE_REMOVE; - } - - void loop (unsigned int ms) { - GMainLoop * loop = g_main_loop_new(NULL, FALSE); - g_timeout_add(ms, timeout_cb, loop); - g_main_loop_run(loop); - g_main_loop_unref(loop); - } - - void set_property (const gchar * name, GVariant * value) { - dbus_test_dbus_mock_object_update_property((DbusTestDbusMock *)service_mock, service_mock.get_sound(), name, value, NULL); - } - - testing::AssertionResult expectEventually (std::function<testing::AssertionResult(void)> &testfunc) { - auto loop = std::shared_ptr<GMainLoop>(g_main_loop_new(nullptr, FALSE), [](GMainLoop * loop) { if (loop != nullptr) g_main_loop_unref(loop); }); - - std::promise<testing::AssertionResult> retpromise; - auto retfuture = retpromise.get_future(); - auto start = std::chrono::steady_clock::now(); - - /* The core of the idle function as an object so we can use the C++-isms - of attaching the variables and make this code reasonably readable */ - std::function<void(void)> idlefunc = [&loop, &retpromise, &testfunc, &start, this]() -> void { - auto result = testfunc(); - - if (result == false && _eventuallyTime > (std::chrono::steady_clock::now() - start)) { - return; - } - - retpromise.set_value(result); - g_main_loop_quit(loop.get()); - }; - - auto idlesrc = g_idle_add([](gpointer data) -> gboolean { - auto func = reinterpret_cast<std::function<void(void)> *>(data); - (*func)(); - return G_SOURCE_CONTINUE; - }, &idlefunc); - - g_main_loop_run(loop.get()); - g_source_remove(idlesrc); - - return retfuture.get(); - } - - /* Eventually Helpers */ - #define _EVENTUALLY_HELPER(oper) \ - template <typename... Args> testing::AssertionResult expectEventually##oper (Args&& ... args) { \ - std::function<testing::AssertionResult(void)> func = [&]() { \ - return testing::internal::CmpHelper##oper(std::forward<Args>(args)...); \ - }; \ - return expectEventually(func); \ - } - - _EVENTUALLY_HELPER(EQ); - _EVENTUALLY_HELPER(NE); - _EVENTUALLY_HELPER(LT); - _EVENTUALLY_HELPER(GT); - _EVENTUALLY_HELPER(STREQ); - _EVENTUALLY_HELPER(STRNE); - - #undef _EVENTUALLY_HELPER + protected: + DbusTestService * testsystem = NULL; + AccountsServiceMock service_mock; + + DbusTestService * testsession = NULL; + + DbusTestProcess * systemmonitor = nullptr; + DbusTestProcess * sessionmonitor = nullptr; + + GDBusConnection * system = NULL; + GDBusConnection * session = NULL; + GDBusProxy * proxy = NULL; + + std::chrono::milliseconds _eventuallyTime = std::chrono::seconds{5}; + + virtual void SetUp() { + /* System Bus */ + testsystem = dbus_test_service_new(NULL); + dbus_test_service_set_bus(testsystem, DBUS_TEST_SERVICE_BUS_SYSTEM); + + systemmonitor = dbus_test_process_new("dbus-monitor"); + dbus_test_process_append_param(systemmonitor, "--system"); + dbus_test_task_set_name(DBUS_TEST_TASK(systemmonitor), "System"); + dbus_test_service_add_task(testsystem, DBUS_TEST_TASK(systemmonitor)); + + dbus_test_service_add_task(testsystem, (DbusTestTask*)service_mock); + dbus_test_service_start_tasks(testsystem); + + system = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); + ASSERT_NE(nullptr, system); + g_dbus_connection_set_exit_on_close(system, FALSE); + g_object_add_weak_pointer(G_OBJECT(system), (gpointer *)&system); + + /* Session Bus */ + testsession = dbus_test_service_new(NULL); + dbus_test_service_set_bus(testsession, DBUS_TEST_SERVICE_BUS_SESSION); + + sessionmonitor = dbus_test_process_new("dbus-monitor"); + dbus_test_process_append_param(sessionmonitor, "--session"); + dbus_test_task_set_name(DBUS_TEST_TASK(sessionmonitor), "Session"); + dbus_test_service_add_task(testsession, DBUS_TEST_TASK(sessionmonitor)); + + dbus_test_service_start_tasks(testsession); + + session = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL); + ASSERT_NE(nullptr, session); + g_dbus_connection_set_exit_on_close(session, FALSE); + g_object_add_weak_pointer(G_OBJECT(session), (gpointer *)&session); + + /* Setup proxy */ + proxy = g_dbus_proxy_new_sync(system, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.Accounts", + "/user", + "org.freedesktop.DBus.Properties", + NULL, NULL); + ASSERT_NE(nullptr, proxy); + } + + virtual void TearDown() { + g_clear_object(&sessionmonitor); + g_clear_object(&systemmonitor); + + g_clear_object(&proxy); + g_clear_object(&testsystem); + g_clear_object(&testsession); + + g_object_unref(system); + g_object_unref(session); + + #if 0 + /* Accounts Service keeps a bunch of references around so we + have to split the tests and can't check this :-( */ + unsigned int cleartry = 0; + while ((session != NULL || system != NULL) && cleartry < 100) { + loop(100); + cleartry++; + } + + ASSERT_EQ(nullptr, session); + ASSERT_EQ(nullptr, system); + #endif + } + + static gboolean timeout_cb (gpointer user_data) { + GMainLoop * pLoop = static_cast<GMainLoop *>(user_data); + g_main_loop_quit(pLoop); + return G_SOURCE_REMOVE; + } + + void loop (unsigned int ms) { + GMainLoop * pLoop = g_main_loop_new(NULL, FALSE); + g_timeout_add(ms, timeout_cb, pLoop); + g_main_loop_run(pLoop); + g_main_loop_unref(pLoop); + } + + void set_property (const gchar * name, GVariant * value) { + dbus_test_dbus_mock_object_update_property((DbusTestDbusMock *)service_mock, service_mock.get_sound(), name, value, NULL); + } + + testing::AssertionResult expectEventually (std::function<testing::AssertionResult(void)> &testfunc) { + auto pLoop = std::shared_ptr<GMainLoop>(g_main_loop_new(nullptr, FALSE), [](GMainLoop * pLoop) { if (pLoop != nullptr) g_main_loop_unref(pLoop); }); + + std::promise<testing::AssertionResult> retpromise; + auto retfuture = retpromise.get_future(); + auto start = std::chrono::steady_clock::now(); + + /* The core of the idle function as an object so we can use the C++-isms + of attaching the variables and make this code reasonably readable */ + std::function<void(void)> idlefunc = [&pLoop, &retpromise, &testfunc, &start, this]() -> void { + auto result = testfunc(); + + if (result == false && _eventuallyTime > (std::chrono::steady_clock::now() - start)) { + return; + } + + retpromise.set_value(result); + g_main_loop_quit(pLoop.get()); + }; + + auto idlesrc = g_idle_add([](gpointer data) -> gboolean { + auto func = reinterpret_cast<std::function<void(void)> *>(data); + (*func)(); + return G_SOURCE_CONTINUE; + }, &idlefunc); + + g_main_loop_run(pLoop.get()); + g_source_remove(idlesrc); + + return retfuture.get(); + } + + /* Eventually Helpers */ + #define _EVENTUALLY_HELPER(oper) \ + template <typename... Args> testing::AssertionResult expectEventually##oper (Args&& ... args) { \ + std::function<testing::AssertionResult(void)> func = [&]() { \ + return testing::internal::CmpHelper##oper(std::forward<Args>(args)...); \ + }; \ + return expectEventually(func); \ + } + + _EVENTUALLY_HELPER(EQ); + _EVENTUALLY_HELPER(NE); + _EVENTUALLY_HELPER(LT); + _EVENTUALLY_HELPER(GT); + _EVENTUALLY_HELPER(STREQ); + _EVENTUALLY_HELPER(STRNE); + + #undef _EVENTUALLY_HELPER }; /* Helpers */ #define EXPECT_EVENTUALLY_EQ(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyEQ, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyEQ, expected, actual) #define EXPECT_EVENTUALLY_NE(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyNE, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyNE, expected, actual) #define EXPECT_EVENTUALLY_LT(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyLT, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyLT, expected, actual) #define EXPECT_EVENTUALLY_GT(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyGT, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallyGT, expected, actual) #define EXPECT_EVENTUALLY_STREQ(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTREQ, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTREQ, expected, actual) #define EXPECT_EVENTUALLY_STRNE(expected, actual) \ - EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTRNE, expected, actual) + EXPECT_PRED_FORMAT2(MediaPlayerUserTest::expectEventuallySTRNE, expected, actual) TEST_F(MediaPlayerUserTest, BasicObject) { - MediaPlayerUser * player = media_player_user_new("user"); - ASSERT_NE(nullptr, player); - - /* Protected, but no useful data */ - EXPECT_FALSE(media_player_get_is_running(MEDIA_PLAYER(player))); - EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); - EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); - EXPECT_STREQ("", media_player_get_name(MEDIA_PLAYER(player))); - EXPECT_STREQ("", media_player_get_state(MEDIA_PLAYER(player))); - EXPECT_EQ(nullptr, media_player_get_icon(MEDIA_PLAYER(player))); - EXPECT_EQ(nullptr, media_player_get_current_track(MEDIA_PLAYER(player))); - - /* Get the proxy -- but no good data */ - loop(100); - - /* Ensure even with the proxy we don't have anything */ - EXPECT_FALSE(media_player_get_is_running(MEDIA_PLAYER(player))); - EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); - EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); - EXPECT_STREQ("", media_player_get_name(MEDIA_PLAYER(player))); - EXPECT_STREQ("", media_player_get_state(MEDIA_PLAYER(player))); - EXPECT_EQ(nullptr, media_player_get_icon(MEDIA_PLAYER(player))); - EXPECT_EQ(nullptr, media_player_get_current_track(MEDIA_PLAYER(player))); - - g_clear_object(&player); + MediaPlayerUser * player = media_player_user_new("user"); + ASSERT_NE(nullptr, player); + + /* Protected, but no useful data */ + EXPECT_FALSE(media_player_get_is_running(MEDIA_PLAYER(player))); + EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); + EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); + EXPECT_STREQ("", media_player_get_name(MEDIA_PLAYER(player))); + EXPECT_STREQ("", media_player_get_state(MEDIA_PLAYER(player))); + EXPECT_EQ(nullptr, media_player_get_icon(MEDIA_PLAYER(player))); + EXPECT_EQ(nullptr, media_player_get_current_track(MEDIA_PLAYER(player))); + + /* Get the proxy -- but no good data */ + loop(100); + + /* Ensure even with the proxy we don't have anything */ + EXPECT_FALSE(media_player_get_is_running(MEDIA_PLAYER(player))); + EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); + EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); + EXPECT_STREQ("", media_player_get_name(MEDIA_PLAYER(player))); + EXPECT_STREQ("", media_player_get_state(MEDIA_PLAYER(player))); + EXPECT_EQ(nullptr, media_player_get_icon(MEDIA_PLAYER(player))); + EXPECT_EQ(nullptr, media_player_get_current_track(MEDIA_PLAYER(player))); + + g_clear_object(&player); } void running_update (GObject * obj, GParamSpec * pspec, bool * running) { - *running = media_player_get_is_running(MEDIA_PLAYER(obj)) == TRUE; + *running = media_player_get_is_running(MEDIA_PLAYER(obj)) == TRUE; }; TEST_F(MediaPlayerUserTest, DISABLED_DataSet) { - /* Put data into Acts */ - set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); - set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); - GIcon * in_icon = g_themed_icon_new_with_default_fallbacks("foo-bar-fallback"); - set_property("PlayerIcon", g_variant_new_variant(g_icon_serialize(in_icon))); - set_property("State", g_variant_new_string("Chillin'")); - set_property("Title", g_variant_new_string("Dictator")); - set_property("Artist", g_variant_new_string("Bansky")); - set_property("Album", g_variant_new_string("Vinyl is dead")); - set_property("ArtUrl", g_variant_new_string("http://art.url")); - - /* Build our media player */ - MediaPlayerUser * player = media_player_user_new("user"); - ASSERT_NE(nullptr, player); - - /* Ensure even with the proxy we don't have anything */ - bool running = false; - g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); - running_update(G_OBJECT(player), nullptr, &running); - EXPECT_EVENTUALLY_EQ(true, running); - EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); - EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); - EXPECT_STREQ("The Player Formerly Known as Prince", media_player_get_name(MEDIA_PLAYER(player))); - EXPECT_STREQ("Chillin'", media_player_get_state(MEDIA_PLAYER(player))); - - GIcon * out_icon = media_player_get_icon(MEDIA_PLAYER(player)); - EXPECT_NE(nullptr, out_icon); - EXPECT_TRUE(g_icon_equal(in_icon, out_icon)); - // NOTE: No reference in 'out_icon' returned - - MediaPlayerTrack * track = media_player_get_current_track(MEDIA_PLAYER(player)); - EXPECT_NE(nullptr, track); - EXPECT_STREQ("Dictator", media_player_track_get_title(track)); - EXPECT_STREQ("Bansky", media_player_track_get_artist(track)); - EXPECT_STREQ("Vinyl is dead", media_player_track_get_album(track)); - EXPECT_STREQ("http://art.url", media_player_track_get_art_url(track)); - // NOTE: No reference in 'track' returned - - g_clear_object(&in_icon); - g_clear_object(&player); + /* Put data into Acts */ + set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); + set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); + GIcon * in_icon = g_themed_icon_new_with_default_fallbacks("foo-bar-fallback"); + set_property("PlayerIcon", g_variant_new_variant(g_icon_serialize(in_icon))); + set_property("State", g_variant_new_string("Chillin'")); + set_property("Title", g_variant_new_string("Dictator")); + set_property("Artist", g_variant_new_string("Bansky")); + set_property("Album", g_variant_new_string("Vinyl is dead")); + set_property("ArtUrl", g_variant_new_string("http://art.url")); + + /* Build our media player */ + MediaPlayerUser * player = media_player_user_new("user"); + ASSERT_NE(nullptr, player); + + /* Ensure even with the proxy we don't have anything */ + bool running = false; + g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); + running_update(G_OBJECT(player), nullptr, &running); + EXPECT_EVENTUALLY_EQ(true, running); + EXPECT_TRUE(media_player_get_can_raise(MEDIA_PLAYER(player))); + EXPECT_STREQ("user", media_player_get_id(MEDIA_PLAYER(player))); + EXPECT_STREQ("The Player Formerly Known as Prince", media_player_get_name(MEDIA_PLAYER(player))); + EXPECT_STREQ("Chillin'", media_player_get_state(MEDIA_PLAYER(player))); + + GIcon * out_icon = media_player_get_icon(MEDIA_PLAYER(player)); + EXPECT_NE(nullptr, out_icon); + EXPECT_TRUE(g_icon_equal(in_icon, out_icon)); + // NOTE: No reference in 'out_icon' returned + + MediaPlayerTrack * track = media_player_get_current_track(MEDIA_PLAYER(player)); + EXPECT_NE(nullptr, track); + EXPECT_STREQ("Dictator", media_player_track_get_title(track)); + EXPECT_STREQ("Bansky", media_player_track_get_artist(track)); + EXPECT_STREQ("Vinyl is dead", media_player_track_get_album(track)); + EXPECT_STREQ("http://art.url", media_player_track_get_art_url(track)); + // NOTE: No reference in 'track' returned + + g_clear_object(&in_icon); + g_clear_object(&player); } TEST_F(MediaPlayerUserTest, DISABLED_TimeoutTest) { - /* Put data into Acts -- but 15 minutes ago */ - set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time() - 15 * 60 * 1000 * 1000)); - set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); - GIcon * in_icon = g_themed_icon_new_with_default_fallbacks("foo-bar-fallback"); - set_property("PlayerIcon", g_variant_new_variant(g_icon_serialize(in_icon))); - set_property("State", g_variant_new_string("Chillin'")); - set_property("Title", g_variant_new_string("Dictator")); - set_property("Artist", g_variant_new_string("Bansky")); - set_property("Album", g_variant_new_string("Vinyl is dead")); - set_property("ArtUrl", g_variant_new_string("http://art.url")); + /* Put data into Acts -- but 15 minutes ago */ + set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time() - 15 * 60 * 1000 * 1000)); + set_property("PlayerName", g_variant_new_string("The Player Formerly Known as Prince")); + GIcon * in_icon = g_themed_icon_new_with_default_fallbacks("foo-bar-fallback"); + set_property("PlayerIcon", g_variant_new_variant(g_icon_serialize(in_icon))); + set_property("State", g_variant_new_string("Chillin'")); + set_property("Title", g_variant_new_string("Dictator")); + set_property("Artist", g_variant_new_string("Bansky")); + set_property("Album", g_variant_new_string("Vinyl is dead")); + set_property("ArtUrl", g_variant_new_string("http://art.url")); - /* Build our media player */ - MediaPlayerUser * player = media_player_user_new("user"); - ASSERT_NE(nullptr, player); + /* Build our media player */ + MediaPlayerUser * player = media_player_user_new("user"); + ASSERT_NE(nullptr, player); - bool running = false; - g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); - running_update(G_OBJECT(player), nullptr, &running); + bool running = false; + g_signal_connect(G_OBJECT(player), "notify::is-running", G_CALLBACK(running_update), &running); + running_update(G_OBJECT(player), nullptr, &running); - /* Ensure that we show up as not running */ - EXPECT_EVENTUALLY_EQ(false, running); + /* Ensure that we show up as not running */ + EXPECT_EVENTUALLY_EQ(false, running); - /* Update to make running */ - set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); + /* Update to make running */ + set_property("Timestamp", g_variant_new_uint64(g_get_monotonic_time())); - EXPECT_EVENTUALLY_EQ(true, running); + EXPECT_EVENTUALLY_EQ(true, running); - /* Clear to not run */ - set_property("Timestamp", g_variant_new_uint64(1)); + /* Clear to not run */ + set_property("Timestamp", g_variant_new_uint64(1)); - EXPECT_EVENTUALLY_EQ(false, running); + EXPECT_EVENTUALLY_EQ(false, running); - g_clear_object(&in_icon); - g_clear_object(&player); + g_clear_object(&in_icon); + g_clear_object(&player); } diff --git a/tests/name-watch-test.cc b/tests/name-watch-test.cc index d7e85b4..263b3f2 100644 --- a/tests/name-watch-test.cc +++ b/tests/name-watch-test.cc @@ -1,5 +1,6 @@ /* * Copyright 2013 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ * * Authors: * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> */ #include <gio/gio.h> @@ -26,150 +28,150 @@ extern "C" { class NameWatchTest : public ::testing::Test { - private: - GTestDBus * testbus = NULL; - - protected: - virtual void SetUp() { - testbus = g_test_dbus_new(G_TEST_DBUS_NONE); - g_test_dbus_up(testbus); - } - - virtual void TearDown() { - g_test_dbus_down(testbus); - g_clear_object(&testbus); - } - - static gboolean timeout_cb (gpointer user_data) { - GMainLoop * loop = static_cast<GMainLoop *>(user_data); - g_main_loop_quit(loop); - return G_SOURCE_REMOVE; - } - - void loop (unsigned int ms) { - GMainLoop * loop = g_main_loop_new(NULL, FALSE); - g_timeout_add(ms, timeout_cb, loop); - g_main_loop_run(loop); - g_main_loop_unref(loop); - } + private: + GTestDBus * testbus = NULL; + + protected: + virtual void SetUp() { + testbus = g_test_dbus_new(G_TEST_DBUS_NONE); + g_test_dbus_up(testbus); + } + + virtual void TearDown() { + g_test_dbus_down(testbus); + g_clear_object(&testbus); + } + + static gboolean timeout_cb (gpointer user_data) { + GMainLoop * pLoop = static_cast<GMainLoop *>(user_data); + g_main_loop_quit(pLoop); + return G_SOURCE_REMOVE; + } + + void loop (unsigned int ms) { + GMainLoop * loop = g_main_loop_new(NULL, FALSE); + g_timeout_add(ms, timeout_cb, loop); + g_main_loop_run(loop); + g_main_loop_unref(loop); + } }; typedef struct { - guint appeared; - guint vanished; + guint appeared; + guint vanished; } callback_count_t; static void appeared_simple_cb (GDBusConnection * bus, const gchar * name, const gchar * owner, gpointer user_data) { - callback_count_t * callback_count = static_cast<callback_count_t *>(user_data); - callback_count->appeared++; + callback_count_t * callback_count = static_cast<callback_count_t *>(user_data); + callback_count->appeared++; } static void vanished_simple_cb (GDBusConnection * bus, const gchar * name, gpointer user_data) { - callback_count_t * callback_count = static_cast<callback_count_t *>(user_data); - callback_count->vanished++; + callback_count_t * callback_count = static_cast<callback_count_t *>(user_data); + callback_count->vanished++; } TEST_F(NameWatchTest, BaseWatch) { - callback_count_t callback_count = {0}; + callback_count_t callback_count = {0}; - guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, - "com.foo", - appeared_simple_cb, - vanished_simple_cb, - &callback_count, - NULL); + guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, + "com.foo", + appeared_simple_cb, + vanished_simple_cb, + &callback_count, + NULL); - guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, - "com.foo.bar", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL, NULL); - guint name2 = g_bus_own_name(G_BUS_TYPE_SESSION, - "com.foo.bar_too", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL, NULL); + guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, + "com.foo.bar", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL, NULL); + guint name2 = g_bus_own_name(G_BUS_TYPE_SESSION, + "com.foo.bar_too", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL, NULL); - loop(100); + loop(100); - ASSERT_EQ(callback_count.appeared, 2); + ASSERT_EQ(callback_count.appeared, 2); - g_bus_unown_name(name1); - g_bus_unown_name(name2); + g_bus_unown_name(name1); + g_bus_unown_name(name2); - loop(100); + loop(100); - ASSERT_EQ(callback_count.vanished, 2); + ASSERT_EQ(callback_count.vanished, 2); - bus_unwatch_namespace(ns_watch); + bus_unwatch_namespace(ns_watch); } TEST_F(NameWatchTest, NonMatches) { - callback_count_t callback_count = {0}; + callback_count_t callback_count = {0}; - guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, - "com.foo", - appeared_simple_cb, - vanished_simple_cb, - &callback_count, - NULL); + guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, + "com.foo", + appeared_simple_cb, + vanished_simple_cb, + &callback_count, + NULL); - guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, - "com.foobar.bar", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL, NULL); - guint name2 = g_bus_own_name(G_BUS_TYPE_SESSION, - "com.bar.com.foo", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL, NULL); + guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, + "com.foobar.bar", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL, NULL); + guint name2 = g_bus_own_name(G_BUS_TYPE_SESSION, + "com.bar.com.foo", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL, NULL); - loop(100); + loop(100); - ASSERT_EQ(callback_count.appeared, 0); + ASSERT_EQ(callback_count.appeared, 0); - g_bus_unown_name(name1); - g_bus_unown_name(name2); + g_bus_unown_name(name1); + g_bus_unown_name(name2); - loop(100); + loop(100); - ASSERT_EQ(callback_count.vanished, 0); + ASSERT_EQ(callback_count.vanished, 0); - bus_unwatch_namespace(ns_watch); + bus_unwatch_namespace(ns_watch); } TEST_F(NameWatchTest, StartupNames) { - guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, - "com.foo.bar", - G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL, NULL); + guint name1 = g_bus_own_name(G_BUS_TYPE_SESSION, + "com.foo.bar", + G_BUS_NAME_OWNER_FLAGS_NONE, + NULL, NULL, NULL, NULL, NULL); - loop(100); + loop(100); - callback_count_t callback_count = {0}; + callback_count_t callback_count = {0}; - guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, - "com.foo", - appeared_simple_cb, - vanished_simple_cb, - &callback_count, - NULL); + guint ns_watch = bus_watch_namespace(G_BUS_TYPE_SESSION, + "com.foo", + appeared_simple_cb, + vanished_simple_cb, + &callback_count, + NULL); - loop(100); + loop(100); - ASSERT_EQ(callback_count.appeared, 1); + ASSERT_EQ(callback_count.appeared, 1); - g_bus_unown_name(name1); + g_bus_unown_name(name1); - loop(100); + loop(100); - ASSERT_EQ(callback_count.vanished, 1); + ASSERT_EQ(callback_count.vanished, 1); - bus_unwatch_namespace(ns_watch); + bus_unwatch_namespace(ns_watch); } diff --git a/tests/notifications-mock.h b/tests/notifications-mock.h index 190aa0d..49b2e66 100644 --- a/tests/notifications-mock.h +++ b/tests/notifications-mock.h @@ -1,5 +1,6 @@ /* * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +31,7 @@ class NotificationsMock DbusTestDbusMockObject * baseobj = nullptr; public: - NotificationsMock (std::vector<std::string> capabilities = {"actions", "body", "body-markup", "icon-static", "image/svg+xml", "x-canonical-private-synchronous", "x-canonical-append", "x-canonical-private-icon-only", "x-canonical-truncation", "private-synchronous", "append", "private-icon-only", "truncation"}) { + NotificationsMock (const std::vector<std::string>& capabilities = {"actions", "body", "body-markup", "icon-static", "image/svg+xml", "x-canonical-private-synchronous", "x-canonical-append", "x-canonical-private-icon-only", "x-canonical-truncation", "private-synchronous", "append", "private-icon-only", "truncation"}) { mock = dbus_test_dbus_mock_new("org.freedesktop.Notifications"); dbus_test_task_set_bus(DBUS_TEST_TASK(mock), DBUS_TEST_SERVICE_BUS_SESSION); dbus_test_task_set_name(DBUS_TEST_TASK(mock), "Notify"); @@ -64,7 +65,7 @@ class NotificationsMock std::string vector2py (std::vector<std::string> vect) { std::string retval("[ "); - std::for_each(vect.begin(), vect.end() - 1, [&retval](std::string entry) { + std::for_each(vect.begin(), vect.end() - 1, [&retval](const std::string& entry) { retval += "'"; retval += entry; retval += "', "; diff --git a/tests/notifications-test.cc b/tests/notifications-test.cc index b1531df..a9fa55d 100644 --- a/tests/notifications-test.cc +++ b/tests/notifications-test.cc @@ -98,8 +98,8 @@ class NotificationsTest : public ::testing::Test } static gboolean timeout_cb (gpointer user_data) { - GMainLoop * loop = static_cast<GMainLoop *>(user_data); - g_main_loop_quit(loop); + GMainLoop * pLoop = static_cast<GMainLoop *>(user_data); + g_main_loop_quit(pLoop); return G_SOURCE_REMOVE; } @@ -234,7 +234,7 @@ TEST_F(NotificationsTest, BasicObject) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); - auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); + standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Give some time settle */ loop(50); @@ -247,6 +247,7 @@ TEST_F(NotificationsTest, VolumeChanges) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ @@ -289,6 +290,7 @@ TEST_F(NotificationsTest, DISABLED_StreamChanges) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ @@ -330,6 +332,7 @@ TEST_F(NotificationsTest, DISABLED_IconTesting) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set an initial volume */ @@ -367,6 +370,7 @@ TEST_F(NotificationsTest, DISABLED_ServerRestart) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ @@ -417,6 +421,7 @@ TEST_F(NotificationsTest, DISABLED_HighVolume) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ @@ -462,6 +467,7 @@ TEST_F(NotificationsTest, DISABLED_MenuHide) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ @@ -495,6 +501,7 @@ TEST_F(NotificationsTest, DISABLED_ExtendendVolumeNotification) { auto volumeControl = volumeControlMock(options); auto volumeWarning = volumeWarningMock(options); auto accountsService = std::make_shared<AccountsServiceAccess>(); + // cppcheck-suppress unreadVariable auto soundService = standardService(volumeControl, playerListMock(), options, volumeWarning, accountsService); /* Set a volume */ diff --git a/tests/service-mocks/media-player-mpris-mock/MediaPlayerMprisMock.h b/tests/service-mocks/media-player-mpris-mock/MediaPlayerMprisMock.h index 6d08a29..c6fdc70 100644 --- a/tests/service-mocks/media-player-mpris-mock/MediaPlayerMprisMock.h +++ b/tests/service-mocks/media-player-mpris-mock/MediaPlayerMprisMock.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2015 Canonical Ltd. + * Copyright 2015 Canonical Ltd. + * Copyright 2021 Robert Tari * * 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 @@ -13,7 +14,9 @@ * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. * - * Author: Xavi Garcia <xavi.garcia.mena@canonical.com> + * Authors: + * Xavi Garcia <xavi.garcia.mena@canonical.com> + * Robert Tari <robert@tari.in> */ #pragma once @@ -58,7 +61,7 @@ public Q_SLOTS: void setDesktopEntry(QString const &destopEntry); public: - MediaPlayerMprisMock(QString const &playerName, QObject* parent = 0); + MediaPlayerMprisMock(QString const &playerName, QObject* parent); virtual ~MediaPlayerMprisMock(); private: diff --git a/tests/volume-control-test.cc b/tests/volume-control-test.cc index f25048b..36fa05e 100644 --- a/tests/volume-control-test.cc +++ b/tests/volume-control-test.cc @@ -1,5 +1,6 @@ /* * Copyright 2014 Canonical Ltd. + * Copyright 2021 Robert Tari * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,6 +16,7 @@ * * Authors: * Ted Gould <ted@canonical.com> + * Robert Tari <robert@tari.in> */ #include <gtest/gtest.h> @@ -62,8 +64,8 @@ class VolumeControlTest : public ::testing::Test } static gboolean timeout_cb (gpointer user_data) { - GMainLoop * loop = static_cast<GMainLoop *>(user_data); - g_main_loop_quit(loop); + GMainLoop * pLoop = static_cast<GMainLoop *>(user_data); + g_main_loop_quit(pLoop); return G_SOURCE_REMOVE; } |