RSS

(root)/calliope : /tests/main-test.c (revision 447)

Line Revision Contents
1 185 /*  Calliope Music Player
2  *  Copyright 2005-09 Sam Thursfield <ssssam gmail.com>
3  *
4  *  This program is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15 315  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 185  */
17 315
18 185 /* main-test: tests for mostly top level UI objects. */
19
20 #include <glib.h>
21 #include <gtk/gtk.h>
22 #include <gst/gst.h>
23 337 #include "calliope-core.h"
24 185 #include "conftool.h"
25 193 #include "gstreamer.h"
26 185 #include "musicsourceimporting.h"
27 #include "library.h"
28 #include "uimanager.h"
29 #include "calliope.h"
30 #include "browser.h"
31 #include "player.h"
32 #include "addmusicdialog.h"
33 #include "main.h"
34 #include "test-utils.h"
35
36
37 193 static const char *ui_descr_1 = "<menubar name='TestMenu'>"
38 189                                     "<menu action='TestMenu1'>"
39 193                                     "  <menuitem action='Test'/>"
40 315                                     "</menu></menubar>",
41
42 193                   *ui_descr_2 = "<menubar name='TestMenu'>"
43 189                                     "<menu action='TestMenu2'>"
44                                     "  <menuitem action='Test'/>"
45 193                                     "</menu></menubar>";
46 315
47 193 static GtkActionEntry actions[] = {
48 189     { "TestMenu1", NULL, "Test _1"              },
49     { "TestMenu2", NULL, "Test _2"              },
50     { "Test", GTK_STOCK_NEW, "_Test", "", NULL, NULL    },
51 185 };
52
53 static void ui_manager(void) {
54         ui = ui_manager_new();
55 315         ui_manager_add_actions (ui, actions, G_N_ELEMENTS(actions), NULL, "test:actions");
56         ui_manager_add_ui_from_string (ui, ui_descr_1, "test:ui");
57 189
58         ui_manager_remove_ui (ui, "test:ui");
59         ui_manager_remove_actions (ui, "test:actions", NULL);
60 315
61 189         gtk_ui_manager_ensure_update (GTK_UI_MANAGER(ui));
62
63 315         ui_manager_add_actions (ui, actions, G_N_ELEMENTS(actions), NULL, "test:actions");
64         ui_manager_add_ui_from_string (ui, ui_descr_1, "test:ui-1");
65         ui_manager_add_ui_from_string (ui, ui_descr_2, "test:ui-2");
66 189
67         ui_manager_remove_ui (ui, "test:ui-2");
68
69         ui_manager_remove_ui (ui, "test:ui-1");
70         ui_manager_remove_actions (ui, "test:actions", NULL);
71 315
72 185         g_object_unref (ui);
73         ui = NULL;
74 };
75
76
77 198 GtkWidget *test_calliope_new() {
78 188         Calliope *calliope = calliope_new();
79 315
80 188         // Stop us quitting the non-existant main loop on destroy.
81 315         gulong quit_id = g_signal_handler_find(calliope, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, gtk_main_quit,
82 188                                                NULL);
83         g_signal_handler_disconnect (calliope, quit_id);
84 315
85         return GTK_WIDGET(calliope);
86 188 };
87
88 315 typedef struct {
89 185         // sets up gconf and ui globals.
90 189         gboolean scrobbler_state;
91 185 } AppFixture;
92
93 188 static void app_fixture_setup (AppFixture *fixture, const void *data) {
94 185         gconf = gconf_client_get_default();
95         ui = ui_manager_new();
96 189
97         // FIXME: disable scrobbler during tests. This is a system of using system gconf instead our own
98         fixture->scrobbler_state = gconf_client_get_bool(gconf, KEY_SCROBBLER_ENABLED, NULL);
99 198         //gconf_client_set_bool (gconf, KEY_SCROBBLER_ENABLED, FALSE, NULL);
100 185 };
101
102 188 static void app_fixture_teardown (AppFixture *fixture, const void *data) {
103 189         gconf_client_set_bool (gconf, KEY_SCROBBLER_ENABLED, fixture->scrobbler_state, NULL);
104
105 185         g_object_unref (ui);    ui = NULL;
106         g_object_unref (gconf); gconf = NULL;
107 315         _entry_cleanup ();
108 185 };
109
110 188 static void dialog_add_music(AppFixture *fixture, const void *data) {
111 356         #ifndef LIBRARY_DISABLE
112 185         GtkListStore *library_list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_POINTER);
113 315
114 185         MusicSource *library = library_new (TEST_DB_PATH);
115         GtkTreeIter iter;
116         gtk_list_store_append (library_list, &iter);
117 315         gtk_list_store_set (library_list, &iter, 0, "Test Library", 1, library, -1);
118
119 185         AddMusicDialog *dialog = add_music_dialog_new(library_list);
120
121         add_music_dialog_show (dialog);
122
123         // Should select 'library' as default destination.
124         //
125         GtkWidget *destination_combo = WID("add-music-destination");
126         g_assert (GTK_IS_COMBO_BOX(destination_combo));
127 315
128 185         int active_destination_index = gtk_combo_box_get_active(GTK_COMBO_BOX(destination_combo));
129 315         g_assert_cmpint (active_destination_index, ==, 0);
130
131         //void add_music_dialog_search_path(AddMusicDialog *self, const char *path);
132
133 185         add_music_dialog_free (dialog);
134         g_object_unref (library_list);
135 356         #endif
136 185 };
137
138 193
139 static void browser (AppFixture *fixture, const void *data) {
140         // Test it lives and dies okay.
141         //
142         GtkWidget *browser=browser_new();
143         g_object_ref_sink(browser);
144         g_object_unref(browser);
145 315
146 193         browser=browser_new();
147         g_object_ref_sink(browser);
148 315
149 193         // Test for leaked references adding a source.
150 315         //
151 193         MusicSource *fake_source=g_object_new(MUSIC_SOURCE_IMPORTING_TYPE, NULL);
152 403         browser_add_source (BROWSER(browser), fake_source, NULL);
153 193         browser_close_current_source(BROWSER(browser));
154 315
155         g_assert_cmpint(G_OBJECT(fake_source)->ref_count, ==, 1);
156 193         g_object_unref(fake_source);
157 };
158
159 static void player (AppFixture *fixture, const void *data) {
160         // Test working with a browser.
161 315         GtkWidget *player = player_new(NULL);
162 193         g_object_ref_sink (player);
163         g_object_unref (player);
164 315
165 193         //////
166         GtkWidget *calliope = test_calliope_new();
167 315         /*player = player_new(NULL);
168 193         g_object_ref_sink (player);
169         g_object_unref (player);*/
170         gtk_widget_destroy (calliope);
171
172         calliope = test_calliope_new();
173 315         /*player = player_new(NULL);
174 193         g_object_ref_sink (player);
175         g_object_unref (player);*/
176         gtk_widget_destroy (calliope);
177 315         _entry_cleanup ();
178 193 };
179
180
181 187 // Move the app around and see if it remembers.
182 189 // FIXME: test doesn't work.
183 187 //
184 329 /*static void app_geometry (AppFixture *fixture, const void *data) {
185 187         // Save original geometry because we currently use the main gconf client. FIXME: tests should
186         // with their own gconf setup, using default values in schemas, and so it shouldn't matter if
187         // we clobber values.
188 188         GError *error = NULL;
189 315         GSList *original_geometry = gconf_client_get_list(gconf, KEY_GEOMETRY, GCONF_VALUE_INT,
190 188                                                           &error);
191         g_assert_no_error (error);
192 187
193 189         int x, y, w, h;
194
195 321         GtkWidget *calliope_1 = test_calliope_new();
196 189
197 187         gtk_window_move (GTK_WINDOW(calliope_1), 1, 1);
198 315         gtk_window_set_default_size (GTK_WINDOW(calliope_1), 1000, 1000);
199 189         gtk_widget_show (GTK_WIDGET(calliope_1));
200 315
201 188         gtk_widget_destroy (GTK_WIDGET(calliope_1));
202 315
203 321         GtkWidget *calliope_2 = test_calliope_new();
204 187         gtk_window_get_position (GTK_WINDOW(calliope_2), &x, &y);
205         gtk_window_get_size (GTK_WINDOW(calliope_2), &w, &h);
206         g_assert_cmpint (x, ==, 1);
207         g_assert_cmpint (y, ==, 1);
208         g_assert_cmpint (w, ==, 1000);
209         g_assert_cmpint (h, ==, 1000);
210 315
211 187         gtk_window_maximize (GTK_WINDOW(calliope_2));
212 321         gtk_widget_destroy (calliope_2);
213 189
214 321         GtkWidget *calliope_3 = test_calliope_new();
215 187         GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET(calliope_3));
216         g_assert (gdk_window!=NULL);
217 315
218 187         GdkWindowState state = gdk_window_get_state(gdk_window);
219 315         g_assert (state & GDK_WINDOW_STATE_MAXIMIZED);
220 321         gtk_widget_destroy (calliope_3);
221 187
222         gconf_client_set_list (gconf, KEY_GEOMETRY, GCONF_VALUE_INT, original_geometry, NULL);
223         g_slist_free (original_geometry);
224 329 };*/
225
226
227 static void final_test_with_view (GtkWidget *calliope, MusicView *view) {
228 328         gboolean view_was_destroyed = FALSE;
229         void view_destroyed () { view_was_destroyed = TRUE; };
230
231 185         // FIXME: test the shuffled and sorted playorders, and try all the preset view types .
232 405         for (int i=0; i<5; i++) {
233                 g_usleep (G_USEC_PER_SEC); g_main_context_iteration (NULL, FALSE);
234         };
235 356
236 394         // Test view was destroyed okay.
237 328         g_object_weak_ref (G_OBJECT(view), (GWeakNotify)view_destroyed, NULL);
238 332         //printf ("Closing new source .. (view refs %i)\n", G_OBJECT(view)->ref_count); fflush (stdout);
239 329         calliope_close_source (CALLIOPE(calliope), view);
240 328         g_assert (view_was_destroyed);
241 332         //printf ("Done.\n"); fflush (stdout);
242 185 };
243
244 426 static void final (AppFixture *fixture, const gchar *view_config, gboolean read_tags) {
245 185         // Finally, make a Calliope and do some 'real-world' testing.
246         //
247         //g_log_set_always_fatal(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
248 328         gboolean view_was_destroyed = FALSE;
249 426         
250 328         void view_destroyed () { view_was_destroyed = TRUE; };
251
252 445.1.1         GTestTimeout *test_timer = g_test_timeout_new (120.0);
253 405         GMainLoop *main_loop = g_main_loop_new (NULL, TRUE);
254 204
255 329         GtkWidget *calliope = test_calliope_new();
256 315
257 203         // Test timer to make sure the processes don't get stuck.
258 315         char *current_dir = g_get_current_dir();
259
260 356         #ifndef LIBRARY_DISABLE
261 185         MusicView *library_view = NULL;
262         char *test_database_path = g_build_filename (current_dir, "test-data", "test.db", NULL);
263         if (g_file_test(test_database_path, G_FILE_TEST_EXISTS)) {
264 329                 library_view = calliope_open_library (CALLIOPE(calliope), test_database_path);
265 185         } else
266                 g_message ("Could not find %s - will not test with database.\n", test_database_path);
267         g_free (test_database_path);
268 315
269 356         if (library_view!=NULL) {
270                 final_test_with_view (calliope, library_view);
271         };
272         #endif
273
274 426         GConfChangeSet *import_settings = gconf_change_set_new ();
275         gconf_change_set_set_bool (import_settings, KEY_IMPORT_TAGS, read_tags);
276
277 185         MusicView *directory_view = NULL;
278         char *test_directory_path = g_build_filename (current_dir, "test-data", "files", NULL);
279         if (g_file_test(test_directory_path, G_FILE_TEST_EXISTS)) {
280 397                 // First, test that we can cancel a load without it breaking tragically.
281                 //
282 421                 directory_view = calliope_open_directory (CALLIOPE(calliope), test_directory_path, 
283 426                                                           view_config, import_settings);
284 315
285 405                 for (int i=0; i<10; i++) {
286                         g_usleep (50000); g_main_context_iteration (NULL, FALSE);
287                 };
288 356
289 328                 g_object_weak_ref (G_OBJECT(directory_view), (GWeakNotify)view_destroyed, NULL);
290 329                 calliope_close_source (CALLIOPE(calliope), directory_view);
291 328                 g_assert (view_was_destroyed);
292 315
293 397                 // This time test it properly.
294                 //
295 421                 directory_view = calliope_open_directory (CALLIOPE(calliope), test_directory_path, 
296 426                                                           view_config, import_settings);
297 330                 //printf ("..Opened new source..\n"); fflush (stdout);
298 185         } else
299                 g_message ("Could not find %s - will not test with files.\n", test_directory_path);
300         g_free (test_directory_path);
301         g_free (current_dir);
302 315
303 426         gconf_change_set_unref (import_settings);
304
305 323         g_test_timeout_destroy (test_timer);
306 315
307         if (directory_view!=NULL) {
308 328                 final_test_with_view (calliope, directory_view);
309 315         };
310
311 405         g_main_loop_unref (main_loop);
312
313 329         gtk_widget_destroy (calliope);
314 185 };
315
316 426 static void final_no_tags (AppFixture *fixture, const void *data) {
317         const char *view_config = data;
318         final (fixture, view_config, FALSE);
319 }
320
321 static void final_tags (AppFixture *fixture, const void *data) {
322         const char *view_config = data;
323         final (fixture, view_config, TRUE);
324 }
325
326 185 int main(int argc, char *argv[]) {
327 397         gdk_threads_enter ();
328 185         gtk_test_init (&argc, &argv, NULL);
329         gst_init (&argc, &argv);
330 337         calliope_core_init ();
331 193         gst_file_types_init ();
332 315
333 445.1.1         /*g_test_add_func ("/main/UI Manager", ui_manager);
334 193         g_test_add ("/main/app/Browser", AppFixture, NULL, app_fixture_setup, browser,
335                     app_fixture_teardown);
336 315         g_test_add ("/main/app/Player", AppFixture, NULL, app_fixture_setup, player,
337 193                     app_fixture_teardown);
338 188         g_test_add ("/main/dialogs/Add Music", AppFixture, NULL, app_fixture_setup, dialog_add_music,
339 445.1.1                     app_fixture_teardown);*/
340 315         //g_test_add ("/main/app/Geometry", AppFixture, NULL, app_fixture_setup, app_geometry,
341 189         //            app_fixture_teardown);
342 431
343 423         char path[256];
344 421         for (int i=0; i<VIEW_CONFIG_PRESETS; i++) {
345 445.1.1                 /*g_test_add (PATH_PRINTF("/main/app/Final [no tags, Preset %i]", i), AppFixture, 
346 426                             view_config_preset[i][1], app_fixture_setup, final_no_tags,
347 445.1.1                             app_fixture_teardown);*/
348 431                 g_test_add (PATH_PRINTF("/main/app/Final [tags, Preset %i]", i), AppFixture, 
349 426                             view_config_preset[i][1], app_fixture_setup, final_tags,
350                             app_fixture_teardown);
351 421         };
352 315
353 421         gboolean result = g_test_run();
354 405
355 397         gdk_threads_leave ();
356 315
357 185         return result;
358 }

Loggerhead is a web-based interface for Bazaar branches