Back to index

unity  6.0.0
test_icon_loader.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License version 3, as published
00006  * by the  Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * version 3 along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>
00016  *
00017  * Authored by: Michal Hruby <michal.hruby@canonical.com>
00018  */
00019 
00020 #include <gmock/gmock.h>
00021 
00022 #include "IconLoader.h"
00023 
00024 using namespace testing;
00025 using namespace unity;
00026 
00027 namespace
00028 {
00029 bool IsValidPixbuf(GdkPixbuf *pixbuf)
00030 {
00031   return GDK_IS_PIXBUF (pixbuf);
00032 }
00033 
00034 gboolean TimeoutReached (gpointer data)
00035 {
00036   bool *b = static_cast<bool*>(data);
00037 
00038   *b = true;
00039 
00040   return FALSE;
00041 }
00042 
00043 struct LoadResult
00044 {
00045   GdkPixbuf *pixbuf;
00046   bool got_callback;
00047 
00048   LoadResult() : pixbuf(NULL), got_callback(false) {}
00049   void IconLoaded(std::string const& icon_name, unsigned size,
00050                   glib::Object<GdkPixbuf> const& buf)
00051   {
00052     pixbuf = buf;
00053 
00054     got_callback = true;
00055   }
00056 };
00057 
00058 TEST(TestIconLoader, TestGetDefault)
00059 {
00060   // we need to initialize gtk
00061   int args_cnt = 0;
00062   gtk_init (&args_cnt, NULL);
00063 
00064   IconLoader::GetDefault();
00065 }
00066 
00067 TEST(TestIconLoader, TestGetOneIcon)
00068 {
00069   LoadResult load_result;
00070   IconLoader& icon_loader = IconLoader::GetDefault();
00071   volatile bool timeout_reached = false;
00072 
00073   icon_loader.LoadFromIconName("gedit-icon", 48, sigc::mem_fun(load_result,
00074         &LoadResult::IconLoaded));
00075 
00076   guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
00077   while (!timeout_reached && !load_result.got_callback)
00078   {
00079     g_main_context_iteration (NULL, TRUE);
00080   }
00081 
00082   EXPECT_TRUE(load_result.got_callback);
00083   EXPECT_TRUE(IsValidPixbuf(load_result.pixbuf));
00084 
00085   g_source_remove (tid);
00086 }
00087 
00088 TEST(TestIconLoader, TestGetOneIconManyTimes)
00089 {
00090   std::vector<LoadResult> results;
00091   std::vector<int> handles;
00092   IconLoader& icon_loader = IconLoader::GetDefault();
00093   volatile bool timeout_reached = false;
00094   int i, load_count;
00095 
00096   // 100 times should be good
00097   load_count = 100;
00098   results.resize (load_count);
00099   handles.resize (load_count);
00100 
00101   // careful, don't use the same icon as in previous tests, otherwise it'll
00102   // be cached already!
00103   for (int i = 0; i < load_count; i++)
00104   {
00105     handles[i] = icon_loader.LoadFromIconName("web-browser", 48,
00106         sigc::mem_fun(results[i], &LoadResult::IconLoaded));
00107   }
00108 
00109   // disconnect every other handler (and especially the first one)
00110   for (i = 0; i < load_count; i += 2)
00111   {
00112     icon_loader.DisconnectHandle(handles[i]);
00113   }
00114 
00115   guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
00116   int iterations = 0;
00117   while (!timeout_reached)
00118   {
00119     g_main_context_iteration (NULL, TRUE);
00120     bool all_loaded = true;
00121     bool any_loaded = false;
00122     for (i = 1; i < load_count; i += 2)
00123     {
00124       all_loaded &= results[i].got_callback;
00125       any_loaded |= results[i].got_callback;
00126       if (!all_loaded) break;
00127     }
00128     // count the number of iterations where we got some results
00129     if (any_loaded) iterations++;
00130     if (all_loaded) break;
00131   }
00132 
00133   EXPECT_FALSE(timeout_reached);
00134   // it's all loading the same icon, the results had to come in the same
00135   // main loop iteration (that's the desired behaviour)
00136   EXPECT_EQ(iterations, 1);
00137 
00138   for (i = 0; i < load_count; i++)
00139   {
00140     if (i % 2)
00141     {
00142       EXPECT_TRUE(results[i].got_callback);
00143       EXPECT_TRUE(IsValidPixbuf(results[i].pixbuf));
00144     }
00145     else
00146     {
00147       EXPECT_FALSE(results[i].got_callback);
00148     }
00149   }
00150 
00151   g_source_remove (tid);
00152 }
00153 
00154 TEST(TestIconLoader, TestGetManyIcons)
00155 {
00156   std::vector<LoadResult> results;
00157   IconLoader& icon_loader = IconLoader::GetDefault();
00158   volatile bool timeout_reached = false;
00159   int i = 0;
00160   int icon_count;
00161 
00162   GList *icons = gtk_icon_theme_list_icons (gtk_icon_theme_get_default (),
00163                                             "Applications");
00164   // loading 100 icons should suffice
00165   icon_count = MIN (100, g_list_length (icons));
00166   results.resize (icon_count);
00167   for (GList *it = icons; it != NULL; it = it->next)
00168   {
00169     const char *icon_name = static_cast<char*>(it->data);
00170     icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(results[i++],
00171         &LoadResult::IconLoaded));
00172     if (i >= icon_count) break;
00173   }
00174 
00175   guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
00176   while (!timeout_reached)
00177   {
00178     g_main_context_iteration (NULL, TRUE);
00179     bool all_loaded = true;
00180     for (auto loader: results)
00181     {
00182       all_loaded &= loader.got_callback;
00183       if (!all_loaded) break;
00184     }
00185     if (all_loaded) break;
00186   }
00187 
00188   for (auto load_result: results)
00189   {
00190     EXPECT_TRUE(load_result.got_callback);
00191     EXPECT_TRUE(IsValidPixbuf(load_result.pixbuf));
00192   }
00193 
00194   g_source_remove (tid);
00195 }
00196 
00197 TEST(TestIconLoader, TestCancelSome)
00198 {
00199   std::vector<LoadResult> results;
00200   std::vector<int> handles;
00201   IconLoader& icon_loader = IconLoader::GetDefault();
00202   volatile bool timeout_reached = false;
00203   int i = 0;
00204   int icon_count;
00205 
00206   GList *icons = gtk_icon_theme_list_icons (gtk_icon_theme_get_default (),
00207                                             "Emblems");
00208   // loading 100 icons should suffice
00209   icon_count = MIN (100, g_list_length (icons));
00210   results.resize (icon_count);
00211   handles.resize (icon_count);
00212   for (GList *it = icons; it != NULL; it = it->next)
00213   {
00214     const char *icon_name = static_cast<char*>(it->data);
00215     int handle = icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(
00216           results[i], &LoadResult::IconLoaded));
00217     handles[i++] = handle;
00218     if (i >= icon_count) break;
00219   }
00220 
00221   // disconnect every other handler
00222   for (i = 0; i < icon_count; i += 2)
00223   {
00224     icon_loader.DisconnectHandle(handles[i]);
00225   }
00226 
00227   guint tid = g_timeout_add (30000, TimeoutReached, (gpointer)(&timeout_reached));
00228   while (!timeout_reached)
00229   {
00230     g_main_context_iteration (NULL, TRUE);
00231     bool all_loaded = true;
00232     for (int i = 1; i < icon_count; i += 2)
00233     {
00234       all_loaded &= results[i].got_callback;
00235       if (!all_loaded) break;
00236     }
00237     if (all_loaded) break;
00238   }
00239 
00240   for (i = 0; i < icon_count; i++)
00241   {
00242     if (i % 2)
00243     {
00244       EXPECT_TRUE(results[i].got_callback);
00245       EXPECT_TRUE(IsValidPixbuf(results[i].pixbuf));
00246     }
00247     else
00248     {
00249       EXPECT_FALSE(results[i].got_callback);
00250     }
00251   }
00252 
00253   g_source_remove (tid);
00254 }
00255 
00256 
00257 }