/* * Copyright 2016 (c) Anna Schumaker. */ #include #include #include #include static struct playlist *cb_playlist = NULL; static struct track *cb_track = NULL; static void test_pl_alloc(struct playlist *playlist) { cb_playlist = NULL; } static void test_pl_removed(struct playlist *playlist, struct track *track, unsigned int n) { cb_playlist = playlist; cb_track = track; } static void test_pl_callback(struct playlist *playlist, struct track *track) { cb_playlist = playlist; cb_track = track; } static struct playlist_ops test_noop; static struct playlist_ops test_ops = { .pl_add = playlist_generic_add, .pl_can_select = playlist_generic_can_select, .pl_remove = playlist_generic_remove, .pl_set_random = playlist_generic_set_random, .pl_sort = playlist_generic_sort, .pl_rearrange = playlist_generic_rearrange, }; static struct playlist_callbacks test_cb = { .pl_cb_alloc = test_pl_alloc, .pl_cb_added = test_pl_callback, .pl_cb_removed = test_pl_removed, .pl_cb_updated = test_pl_callback, }; static void test_null() { g_assert_null(playlist_new(PL_MAX_TYPE, "NULL")); g_assert_null(playlist_new(PL_MAX_TYPE, NULL)); g_assert_false(playlist_delete(NULL)); playlist_generic_free(NULL); playlist_generic_init(NULL, 0); playlist_generic_deinit(NULL); g_assert_null(playlist_lookup(PL_MAX_TYPE, "NULL")); g_assert_null(playlist_lookup(PL_MAX_TYPE, NULL)); g_assert_null(playlist_get(PL_MAX_TYPE, 0)); g_assert(playlist_current() == playlist_lookup(PL_SYSTEM, "Collection")); g_assert_false(playlist_select(NULL)); g_assert(playlist_current() == playlist_lookup(PL_SYSTEM, "Collection")); g_assert_null(playlist_next()); playlist_selected(NULL); playlist_played(NULL); g_assert_false(playlist_add(NULL, NULL)); g_assert_false(playlist_add(NULL, track_get(0))); g_assert_false(playlist_has(NULL, NULL)); g_assert_false(playlist_has(NULL, track_get(0))); g_assert_cmpuint(playlist_size(NULL), ==, 0); g_assert_false(playlist_remove(NULL, NULL)); g_assert_false(playlist_remove(NULL, track_get(0))); playlist_set_random(NULL, true); g_assert_false(playlist_sort(NULL, COMPARE_TRACK)); g_assert_false(playlist_sort(NULL, COMPARE_TRACK)); playlist_generic_resort(NULL); playlist_clear_sort(NULL); g_assert_false(playlist_rearrange(NULL, 0, 0)); playlist_set_search(NULL, NULL); g_assert_false(playlist_generic_add(NULL, NULL)); g_assert_false(playlist_generic_add_front(NULL, NULL)); g_assert_false(playlist_generic_remove(NULL, NULL)); g_assert_null(playlist_at(NULL, 0)); playlist_generic_update(NULL, NULL); playlist_generic_clear(NULL); playlist_generic_save(NULL, NULL, PL_SAVE_ALL); playlist_generic_load(NULL, NULL, PL_SAVE_ALL); g_assert_null(playlist_iter_get(NULL, 0)); g_assert_false(playlist_iter_next(NULL)); g_assert_null(playlist_iter_track(NULL)); g_assert_cmpint(playlist_iter_index(NULL, NULL), ==, -1); g_assert_false(playlist_current_set(NULL, 0)); g_assert_false(playlist_current_next(NULL)); g_assert_false(playlist_current_previous(NULL)); g_assert_null(playlist_current_track(NULL)); g_assert_cmpint(playlist_current_index(NULL), ==, -1); } static void test_playlist() { struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); unsigned int ex_length = 0; playlist_iter it; int i; g_assert_cmpuint(playlist_size(&p), ==, 0); playlist_generic_init(&p, 0); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 0); for (i = 0; i < 13; i++) { ex_length += track_get(i)->tr_length; playlist_generic_add_front(&p, track_get(i)); g_assert_true(playlist_has(&p, track_get(i))); g_assert_cmpuint(p.pl_length, ==, ex_length); g_assert_cmpuint(playlist_size(&p), ==, i + 1); g_assert(cb_playlist == &p); g_assert(cb_track == track_get(i)); } g_assert_false(playlist_generic_add_front(&p, NULL)); /* Trigger an update for each track. */ i = 13; playlist_for_each(&p, it) { g_assert_cmpuint(playlist_iter_track(it)->tr_track, ==, i--); playlist_generic_update(&p, playlist_iter_track(it)); g_assert(cb_playlist == &p); g_assert(cb_track == playlist_iter_track(it)); } playlist_generic_update(&p, NULL); g_assert(cb_playlist == &p); g_assert_null(cb_track); /* Remove all tracks. */ playlist_current_set(&p, 12); for (i = 0; i < 13; i++) { ex_length -= track_get(i)->tr_length; g_assert_true(playlist_remove(&p, track_get(i))); g_assert_false(playlist_has(&p, track_get(i))); g_assert(cb_playlist == &p); g_assert(cb_track == track_get(i)); g_assert_cmpuint(p.pl_length, ==, ex_length); g_assert_cmpint(playlist_current_index(&p), ==, (11 - i)); g_assert_cmpuint(playlist_size(&p), ==, (12 - i)); if (i < 12) g_assert_nonnull(p.pl_current); } g_assert_false(playlist_generic_remove(&p, NULL)); g_assert_false(playlist_has(&p, track_get(i))); g_assert(cb_playlist == &p); g_assert(cb_track == track_get(12)); g_assert_cmpuint(p.pl_length, ==, ex_length); g_assert_null(p.pl_current); /* Re-add the tracks! */ for (i = 0; i < 13; i++) { ex_length += track_get(i)->tr_length; g_assert_true( playlist_add(&p, track_get(i))); g_assert_false(playlist_add(&p, track_get(i))); g_assert_true(playlist_has(&p, track_get(i))); g_assert(playlist_at(&p, i) == track_get(i)); g_assert_cmpuint(p.pl_length, ==, ex_length); g_assert_cmpuint(playlist_size(&p), ==, i + 1); g_assert(cb_playlist == &p); g_assert(cb_track == track_get(i)); } g_assert_false(playlist_generic_add(&p, NULL)); g_assert_cmpuint(p.pl_length, ==, ex_length); /* Now clear the playlist. */ playlist_current_set(&p, 12); playlist_generic_clear(&p); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_null(p.pl_current); /* Set search text. */ playlist_set_search(&p, "test"); g_assert_cmpstr(p.pl_search[0], ==, "test"); playlist_set_search(&p, "Test Text"); g_assert_cmpstr(p.pl_search[0], ==, "test"); g_assert_cmpstr(p.pl_search[1], ==, "text"); /* Deinitialize the playlist. */ playlist_generic_deinit(&p); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_null(p.pl_current); g_assert_null(p.pl_search); g_assert_null(p.pl_sort); } static void test_sorting() { struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct track *track; unsigned int i; playlist_generic_init(&p, 4, COMPARE_ARTIST, COMPARE_YEAR, COMPARE_ALBUM, COMPARE_TRACK); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 4); playlist_clear_sort(&p); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 0); for (i = 0; i < 13; i++) { track = track_get(i); track->tr_count = (track->tr_track % 2) ? 4 : 2; playlist_generic_add_front(&p, track); } cb_playlist = NULL; cb_track = NULL; p.pl_ops = &test_noop; g_assert_false(playlist_sort(&p, COMPARE_TRACK)); g_assert_null(cb_playlist); g_assert_null(cb_track); p.pl_ops = &test_ops; g_assert_true(playlist_sort(&p, COMPARE_TRACK)); g_assert(cb_playlist == &p); g_assert_null(cb_track); for (i = 0; i < 13; i++) { track = playlist_at(&p, i); g_assert_cmpuint(track->tr_track, ==, i + 1); } playlist_clear_sort(&p); playlist_generic_resort(&p); g_assert_true(playlist_sort(&p, COMPARE_COUNT)); for (i = 0; i < 13; i++) { track = playlist_at(&p, i); g_assert_cmpuint(track->tr_count, ==, (i < 6) ? 2 : 4); } g_assert_true(playlist_sort(&p, COMPARE_TRACK)); for (i = 0; i < 13; i++) { track = playlist_at(&p, i); g_assert_cmpuint(track->tr_count, ==, (i < 6) ? 2 : 4); if (i < 6) g_assert_cmpuint(track->tr_track, ==, (i + 1) * 2); else g_assert_cmpuint(track->tr_track, ==, (2 * i) - 11); } g_assert_true(playlist_sort(&p, COMPARE_COUNT)); for (i = 0; i < 13; i++) { track = playlist_at(&p, i); g_assert_cmpuint(track->tr_count, ==, (i < 7) ? 4 : 2); if (i < 7) g_assert_cmpuint(track->tr_track, ==, (2 * i) + 1); else g_assert_cmpuint(track->tr_track, ==, (2 * i) - 12); } /* Test inserting at a sorted position. */ playlist_generic_clear(&p); playlist_clear_sort(&p); playlist_sort(&p, COMPARE_TRACK); playlist_sort(&p, COMPARE_TRACK); for (i = 0; i < 13; i++) { g_assert_false(playlist_has(&p, track_get(i))); g_assert_true( playlist_add(&p, track_get(i))); g_assert_false(playlist_add(&p, track_get(i))); } for (i = 0; i < 13; i++) g_assert_cmpuint(playlist_at(&p, i)->tr_track, ==, 13 - i); /* Deinitialize the playlist. */ playlist_generic_deinit(&p); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_null(p.pl_current); g_assert_null(p.pl_sort); } static void test_rearranging() { struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct track *track; unsigned int i; playlist_generic_init(&p, 4, COMPARE_ARTIST, COMPARE_YEAR, COMPARE_ALBUM, COMPARE_TRACK); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 4); for (i = 0; i < 13; i++) playlist_add(&p, track_get(i)); g_assert_false(playlist_rearrange(&p, 42, 4)); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 4); g_assert_false(playlist_rearrange(&p, 4, 42)); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 4); g_assert_false(playlist_rearrange(&p, 4, 4)); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 4); g_assert_true(playlist_rearrange(&p, 12, 0)); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 0); g_assert_true(playlist_rearrange(&p, 1, 12)); g_assert_cmpuint(g_slist_length(p.pl_sort), ==, 0); for (i = 0; i < 13; i++) { track = playlist_at(&p, i); if (i == 0) g_assert_cmpuint(track->tr_track, ==, 13); else if (i == 12) g_assert_cmpuint(track->tr_track, ==, 1); else g_assert_cmpuint(track->tr_track, ==, i + 1); } playlist_generic_deinit(&p); } static void test_next() { struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct track *track; unsigned int i; g_random_set_seed(0); playlist_generic_init(&p, 0); for (i = 0; i < 13; i++) playlist_generic_add(&p, track_get(i)); g_assert_true(playlist_select(&p)); g_assert(playlist_current() == &p); /* Test playlist_next() with wraparound, but no random. */ for (i = 0; i < (13 * 2); i++) { track = playlist_next(); g_assert_nonnull(track); g_assert_cmpuint(track->tr_track, ==, (i % 13) + 1); g_assert_cmpuint(playlist_size(&p), ==, 13); } playlist_set_random(&p, true); g_assert_true(p.pl_random); /* rand() = { 10, 4, 6, 1, 8, 4, 1 } */ g_assert_cmpuint(playlist_next()->tr_track, ==, 9); g_assert_cmpuint(playlist_next()->tr_track, ==, 13); g_assert_cmpuint(playlist_next()->tr_track, ==, 6); g_assert_cmpuint(playlist_next()->tr_track, ==, 7); g_assert_cmpuint(playlist_next()->tr_track, ==, 2); g_assert_cmpuint(playlist_next()->tr_track, ==, 6); g_assert_cmpuint(playlist_next()->tr_track, ==, 1); g_assert_cmpuint(playlist_size(&p), ==, 13); /* Deinitialize the playlist. */ playlist_generic_deinit(&p); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_null(p.pl_current); g_assert_null(p.pl_sort); } static void test_save_load() { struct playlist p = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct playlist q = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); struct playlist r = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test", 0, &test_ops); struct playlist s = DEFINE_PLAYLIST(PL_MAX_TYPE, "Test 2", 0, NULL); struct file f = FILE_INIT_DATA("", "test.playlist", 0); unsigned int i; for (i = 0; i < 13; i++) { playlist_generic_add(&p, track_get(i)); playlist_generic_add(&q, track_get(i)); playlist_generic_add(&r, track_get(i)); } playlist_set_random(&p, true); playlist_clear_sort(&p); playlist_sort(&p, COMPARE_TRACK); playlist_current_set(&p, 3); playlist_current_set(&q, 4); g_assert_false(file_exists(&f)); g_assert_true( file_open(&f, OPEN_WRITE)); playlist_generic_save(&p, &f, PL_SAVE_METADATA); playlist_generic_save(&q, &f, PL_SAVE_ALL); file_close(&f); g_assert_true(file_open(&f, OPEN_READ)); playlist_generic_load(&r, &f, PL_SAVE_METADATA); playlist_generic_load(&s, &f, PL_SAVE_ALL); file_close(&f); g_assert_true(r.pl_random); g_assert_cmpuint(playlist_current_index(&r), ==, 3); g_assert_cmpuint(g_slist_length(r.pl_sort), ==, 1); g_assert_cmpuint(GPOINTER_TO_UINT(r.pl_sort->data), ==, COMPARE_TRACK); g_assert_false(s.pl_random); g_assert_cmpuint(playlist_current_index(&s), ==, 4); g_assert(playlist_current_track(&s) == playlist_at(&q, 4)); g_assert_cmpuint(g_slist_length(s.pl_sort), ==, 0); g_assert_cmpuint(playlist_size(&s), ==, 13); /* Deinitialize the playlist. */ playlist_generic_deinit(&p); g_assert_cmpuint(playlist_size(&p), ==, 0); g_assert_cmpuint(p.pl_length, ==, 0); g_assert_null(p.pl_current); } int main(int argc, char **argv) { struct library *library; int ret; idle_init(IDLE_SYNC); settings_init(); tags_init(); playlist_init(&test_cb); while (idle_run_task()) {}; library = library_find("tests/Music"); track_add(library, "tests/Music/Hyrule Symphony/01 - Title Theme.ogg"); track_add(library, "tests/Music/Hyrule Symphony/02 - Kokiri Forest.ogg"); track_add(library, "tests/Music/Hyrule Symphony/03 - Hyrule Field.ogg"); track_add(library, "tests/Music/Hyrule Symphony/04 - Hyrule Castle.ogg"); track_add(library, "tests/Music/Hyrule Symphony/05 - Lon Lon Ranch.ogg"); track_add(library, "tests/Music/Hyrule Symphony/06 - Kakariko Village.ogg"); track_add(library, "tests/Music/Hyrule Symphony/07 - Death Mountain.ogg"); track_add(library, "tests/Music/Hyrule Symphony/08 - Zora's Domain.ogg"); track_add(library, "tests/Music/Hyrule Symphony/09 - Gerudo Valley.ogg"); track_add(library, "tests/Music/Hyrule Symphony/10 - Ganondorf.ogg"); track_add(library, "tests/Music/Hyrule Symphony/11 - Princess Zelda.ogg"); track_add(library, "tests/Music/Hyrule Symphony/12 - Ocarina Medley.ogg"); track_add(library, "tests/Music/Hyrule Symphony/13 - The Legend of Zelda Medley.ogg"); g_test_init(&argc, &argv, NULL); g_test_add_func("/Core/Playlist/NULL", test_null); g_test_add_func("/Core/Playlists/General", test_playlist); g_test_add_func("/Core/Playlists/Sorting", test_sorting); g_test_add_func("/Core/Playlists/Rearranging", test_rearranging); g_test_add_func("/Core/Playlists/Next Track", test_next); g_test_add_func("/Core/Playlist/Save and Load", test_save_load); ret = g_test_run(); playlist_deinit(); tags_deinit(); settings_deinit(); idle_deinit(); return ret; }