/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include #include #include #include #include #include unsigned int count_insert = 0; unsigned int count_delete = 0; unsigned int count_update = 0; void on_row_inserted(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { count_insert++; } void on_row_deleted(GtkTreeModel *model, GtkTreePath *path, gpointer data) { count_delete++; } void on_row_changed(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { count_update++; } void test_cb_alloc(struct playlist *playlist) {} struct playlist_callbacks test_cb = { .pl_cb_alloc = test_cb_alloc, .pl_cb_added = gui_model_add, .pl_cb_removed = gui_model_remove, .pl_cb_updated = gui_model_update, }; struct core_init_data init_data = { .playlist_cb = &test_cb, }; static void test_init() { GuiModel *model = gui_model_get(); GtkTreeModel *treemodel = GTK_TREE_MODEL(model); GType type; g_assert_null(gui_model_get_playlist()); gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Collection")); g_assert_nonnull(model); g_assert_true(GTK_IS_TREE_MODEL(model)); g_assert(gui_model_get_playlist() == playlist_lookup(PL_SYSTEM, "Collection")); g_assert_cmpuint(gtk_tree_model_get_flags(treemodel), ==, GTK_TREE_MODEL_LIST_ONLY); g_assert_cmpuint(gtk_tree_model_get_n_columns(treemodel), ==, 11); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_TRACK_NR); g_assert_cmpuint(type, ==, G_TYPE_UINT); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_TITLE); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_LENGTH); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_ARTIST); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_ALBUM); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_YEAR); g_assert_cmpuint(type, ==, G_TYPE_UINT); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_GENRE); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_COUNT); g_assert_cmpuint(type, ==, G_TYPE_UINT); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_LAST_PLAY); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_FILE_PATH); g_assert_cmpuint(type, ==, G_TYPE_STRING); type = gtk_tree_model_get_column_type(treemodel, GUI_MODEL_FONT); g_assert_cmpuint(type, ==, G_TYPE_STRING); } static void __test_empty_subprocess() { GtkTreeModel *model = GTK_TREE_MODEL(gui_model_get()); GtkTreeIter iter; GValue value; GType type; gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Collection")); memset(&value, 0, sizeof(GValue)); g_assert_false(gtk_tree_model_get_iter_first(model, &iter)); g_assert_null(gtk_tree_model_get_path(model, &iter)); g_assert_null(gui_model_iter_get_track(&iter)); /* These will all trigger assertion failures ... sorry */ gtk_tree_model_get_value(model, &iter, GUI_MODEL_TRACK_NR, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_TITLE, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_LENGTH, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_ARTIST, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_ALBUM, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_YEAR, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_GENRE, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_COUNT, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_LAST_PLAY, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_FILE_PATH, &value); g_assert_false(G_IS_VALUE(&value)); gtk_tree_model_get_value(model, &iter, GUI_MODEL_FONT, &value); g_assert_false(G_IS_VALUE(&value)); type = gtk_tree_model_get_column_type(model, GUI_MODEL_N_COLUMNS); g_assert_cmpuint(type, ==, G_TYPE_INVALID); g_assert_false(gtk_tree_model_iter_next(model, &iter)); g_assert_false(gtk_tree_model_iter_children(model, &iter, NULL)); g_assert_false(gtk_tree_model_iter_has_child(model, &iter)); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, &iter), ==, 0); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, NULL), ==, 0); g_assert_false(gtk_tree_model_iter_nth_child(model, &iter, NULL, 3)); g_assert_false(gtk_tree_model_iter_parent(model, &iter, &iter)); } static void test_empty() { if (g_test_subprocess()) { __test_empty_subprocess(); return; } g_test_trap_subprocess(NULL, 0, 0); g_test_trap_assert_failed(); } static void test_model() { GtkTreeModel *model = GTK_TREE_MODEL(gui_model_get()); struct playlist *collection, *favorites; struct track *track; GtkTreePath *path; GtkTreeIter iter; GValue value; gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Collection")); g_assert_cmpstr(gtk_label_get_text(gui_model_runtime()), ==, ""); memset(&value, 0, sizeof(GValue)); g_signal_connect(model, "row-inserted", (GCallback)on_row_inserted, NULL); g_signal_connect(model, "row-deleted", (GCallback)on_row_deleted, NULL); g_signal_connect(model, "row-changed", (GCallback)on_row_changed, NULL); /* Okay, now scan a directory ... */ collection = playlist_lookup(PL_SYSTEM, "Collection"); favorites = playlist_lookup(PL_SYSTEM, "Favorites"); playlist_new(PL_LIBRARY, "tests/Music/Hyrule Symphony"); while (idle_run_task() == true) {} g_assert_cmpuint(playlist_size(collection), ==, 13); g_assert_cmpuint(count_insert, ==, 13); playlist_generic_resort(playlist_lookup(PL_SYSTEM, "Collection")); g_assert_cmpuint(count_update, ==, 13); playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(0)); playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(1)); playlist_add(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(2)); g_assert_cmpuint(playlist_size(favorites), ==, 3); g_assert_cmpstr(gtk_label_get_text(gui_model_runtime()), ==, "42 minutes, 45 seconds"); /* ... and test again */ g_assert_true(gtk_tree_model_get_iter_first(model, &iter)); track = gui_model_iter_get_track(&iter); g_assert_cmpuint(track->tr_track, ==, 1); audio_load(track); path = gtk_tree_model_get_path(model, &iter); g_assert_nonnull(path); g_assert_cmpuint(gtk_tree_path_get_indices(path)[0], ==, 0); g_assert(gui_model_path_get_track(path) == track); gtk_tree_path_free(path); gtk_tree_model_get_value(model, &iter, GUI_MODEL_TRACK_NR, &value); g_assert_cmpuint(g_value_get_uint(&value), ==, track->tr_track); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_TITLE, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "Title Theme"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_LENGTH, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "4:03"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_ARTIST, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "Koji Kondo"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_ALBUM, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "Hyrule Symphony"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_YEAR, &value); g_assert_cmpuint(g_value_get_uint(&value), ==, 1998); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_GENRE, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "Game"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_COUNT, &value); g_assert_cmpuint(g_value_get_uint(&value), ==, 0); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_LAST_PLAY, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "Never"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_FILE_PATH, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "tests/Music/Hyrule Symphony/01 - Title Theme.ogg"); g_value_unset(&value); gtk_tree_model_get_value(model, &iter, GUI_MODEL_FONT, &value); g_assert_cmpstr(g_value_get_string(&value), ==, "bold"); g_value_unset(&value); g_assert_true(gtk_tree_model_iter_next(model, &iter)); track = gui_model_iter_get_track(&iter); g_assert_cmpuint(track->tr_track, ==, 2); gtk_tree_model_get_value(model, &iter, GUI_MODEL_FONT, &value); g_assert_cmpstr(g_value_get_string(&value), ==, ""); g_value_unset(&value); g_assert_true(gtk_tree_model_iter_children(model, &iter, NULL)); track = gui_model_iter_get_track(&iter); g_assert_cmpuint(track->tr_track, ==, 1); g_assert_false(gtk_tree_model_iter_has_child(model, &iter)); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, &iter), ==, 0); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, NULL), ==, 13); gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Favorites")); g_assert_cmpuint(count_delete, ==, 13); g_assert_cmpuint(count_insert, ==, 14); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, NULL), ==, 3); g_assert_cmpstr(gtk_label_get_text(gui_model_runtime()), ==, "10 minutes, 46 seconds"); gui_model_set_playlist(NULL); g_assert_cmpuint(count_delete, ==, 16); g_assert_cmpuint(count_insert, ==, 14); g_assert_cmpuint(gtk_tree_model_iter_n_children(model, NULL), ==, 0); g_assert_cmpstr(gtk_label_get_text(gui_model_runtime()), ==, ""); gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Collection")); g_assert_cmpuint(count_delete, ==, 16); g_assert_cmpuint(count_insert, ==, 15); g_assert_cmpstr(gtk_label_get_text(gui_model_runtime()), ==, "42 minutes, 45 seconds"); g_assert_true(gtk_tree_model_iter_nth_child(model, &iter, NULL, 3)); track = gui_model_iter_get_track(&iter); g_assert_cmpuint(track->tr_track, ==, 4); g_assert_false(gtk_tree_model_iter_parent(model, &iter, &iter)); gui_model_set_playlist(playlist_lookup(PL_SYSTEM, "Favorites")); g_assert_cmpuint(count_delete, ==, 29); g_assert_cmpuint(count_insert, ==, 16); playlist_remove(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(0)); playlist_remove(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(1)); playlist_remove(playlist_lookup(PL_SYSTEM, "Favorites"), track_get(2)); g_assert_cmpuint(count_delete, ==, 32); } int main(int argc, char **argv) { int ret; gtk_init(&argc, NULL); core_init(&argc, NULL, &init_data); gui_builder_init("share/ocarina/ocarina.ui"); gui_model_init(); while (idle_run_task()) {}; g_test_init(&argc, &argv, NULL); g_test_add_func("/Gui/Model/Init", test_init); g_test_add_func("/Gui/Model/Empty", test_empty); g_test_add_func("/Gui/Model/Tracks", test_model); ret = g_test_run(); gui_model_deinit(); gui_builder_deinit(); core_deinit(); g_assert_false(G_IS_OBJECT(gui_model_get())); g_assert_null(gui_model_get_playlist()); g_assert_cmpuint(gui_model_get_type(), ==, 0); return ret; }