ocarina/tests/core/playlist.c

457 lines
14 KiB
C

/*
* Copyright 2016 (c) Anna Schumaker.
*/
#include <core/idle.h>
#include <core/playlist.h>
#include <core/settings.h>
#include <core/tags/tags.h>
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;
}