From c799846b912a8008fef6118cd4817d4fd843dd5a Mon Sep 17 00:00:00 2001 From: charles kerr Date: Fri, 1 Jan 2016 11:10:02 -0600 Subject: in notifications-test, make the loop test more flexible --- tests/notifications-test.cc | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'tests/notifications-test.cc') diff --git a/tests/notifications-test.cc b/tests/notifications-test.cc index b4d2216..6f523f1 100644 --- a/tests/notifications-test.cc +++ b/tests/notifications-test.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2015 Canonical Ltd. + * Copyright © 2015-2016 Canonical Ltd. * * 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,8 +15,10 @@ * * Authors: * Ted Gould + * Charles Kerr */ +#include #include #include @@ -105,28 +107,37 @@ class NotificationsTest : public ::testing::Test g_main_loop_unref(loop); } - void loop_until_notifications(unsigned int max_seconds=1) { - struct Data { - std::shared_ptr notifications; - GMainLoop * loop = g_main_loop_new(nullptr, false); - gint64 deadline; - } data; - data.notifications = notifications; - data.deadline = g_get_monotonic_time() + (gint64(max_seconds) * G_USEC_PER_SEC); - + void loop_until(const std::function& test, unsigned int max_ms=50, unsigned int test_interval_ms=10) { + + // g_timeout's callback only allows a single pointer, + // so use a temporary stack struct to wedge everything into one pointer + struct CallbackData { + const std::function& test; + const gint64 deadline; + GMainLoop* loop = g_main_loop_new(nullptr, false); + CallbackData (const std::function& f, unsigned int max_ms): + test{f}, + deadline{g_get_monotonic_time() + (max_ms*1000)} {} + ~CallbackData() {g_main_loop_unref(loop);} + } data(test, max_ms); + + // tell the timer to stop looping on success or deadline auto timerfunc = [](gpointer gdata) -> gboolean { - auto data = static_cast(gdata); - if (data->notifications->getNotifications().empty() && (g_get_monotonic_time() < data->deadline)) + auto& data = *static_cast(gdata); + if (!data.test() && (g_get_monotonic_time() < data.deadline)) return G_SOURCE_CONTINUE; - g_main_loop_quit(data->loop); + g_main_loop_quit(data.loop); return G_SOURCE_REMOVE; }; - static constexpr guint interval_milliseconds = 10; - g_timeout_add (interval_milliseconds, timerfunc, &data); + // start looping + g_timeout_add (std::min(max_ms, test_interval_ms), timerfunc, &data); g_main_loop_run(data.loop); + } - g_main_loop_unref(data.loop); + void loop_until_notifications(unsigned int max_seconds=1) { + auto test = [this]{ return !notifications->getNotifications().empty(); }; + loop_until(test, max_seconds); } static int unref_idle (gpointer user_data) { -- cgit v1.2.3