ocarina/tests/core/audio.c
Anna Schumaker c2178bc265 core: Cut back on hardcoded dbe_index uses
The dbe_index of a given database item might change in the future, so we
can't rely on it everywhere.  Let's just use it for saving and loading
files, with the expectation that changes will happen sometime after
startup.

Implements #69: Reduce use of dbe_index in Ocarina code
Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2016-09-11 10:50:45 -04:00

251 lines
7.3 KiB
C

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/audio.h>
#include <core/idle.h>
#include <core/playlist.h>
#include <core/tempq.h>
#include <core/core.h>
#include <tests/test.h>
static unsigned int load_count = 0;
static unsigned int state_count = 0;
static int pause_count = 0;
static bool test_audio_seek(gint64 pos)
{
bool ret = audio_seek(pos);
GstState state = audio_cur_state();
while (state != GST_STATE_PAUSED && state != GST_STATE_PLAYING)
state = audio_cur_state();
return ret;
}
static void test_send_error()
{
GstMessage *message;
GError *error;
error = g_error_new(1, G_FILE_ERROR_BADF, "Simulated Error");
message = gst_message_new_error(GST_OBJECT(test_audio_player()),
error, "Fake error for testing");
audio_error(message);
gst_message_unref(message);
g_error_free(error);
}
static void test_audio_load(struct track *track) { load_count++; }
static void test_change_state(GstState state) { state_count++; }
static void test_config_pause(int n) { pause_count = n; }
static struct audio_ops test_audio_ops = {
test_audio_load,
test_change_state,
test_config_pause,
};
static struct core_init_data test_init_data = {
.audio_ops = &test_audio_ops,
};
static void test_init()
{
test_equal((void *)test_audio_player(), NULL);
test_equal((void *)audio_cur_track(), NULL);
test_equal(audio_cur_state(), GST_STATE_NULL);
test_equal((void *)audio_next(), NULL);
core_init(NULL, NULL, &test_init_data);
test_equal(audio_load(NULL), (bool)false);
test_equal((void *)audio_next(), NULL);
test_equal((void *)audio_prev(), NULL);
test_send_error();
test_equal(audio_play(), (bool)false);
test_equal(audio_pause(), (bool)false);
test_equal(audio_seek(7), (bool)false);
test_equal(audio_position(), 0);
test_equal(audio_duration(), 0);
test_equal((void *)audio_cur_track(), NULL);
test_equal(audio_cur_state(), GST_STATE_NULL);
test_equal(load_count, 0);
test_equal(state_count, 0);
playlist_new(PL_LIBRARY, "tests/Music/Hyrule Symphony");
while (idle_run_task()) {};
test_equal((void *)audio_cur_track(), NULL);
test_not_equal((void *)test_audio_player(), NULL);
}
static void test_playback()
{
struct track *tracks[3] = { track_get(0), NULL, track_get(0) };
unsigned int i;
for (i = 0; i < 3; i++) {
test_loop_equal(audio_load(tracks[i]), (bool)(i == 0), i);
test_loop_equal(playlist_size(PL_SYSTEM, "History"), 1, i);
test_loop_equal(load_count, 1, i);
test_loop_equal(state_count, 1, i);
test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i);
test_loop_equal((void *)audio_cur_track(), (void *)tracks[0], i);
test_loop_equal(audio_duration(),
tracks[0]->tr_length * GST_SECOND, i);
} test_loop_passed();
test_equal(audio_pause(), (bool)true);
test_equal(audio_pause(), (bool)false);
test_equal(state_count, 2);
test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(test_audio_seek(5 * GST_SECOND), (bool)true);
test_equal(audio_position(), 5 * GST_SECOND);
test_equal(test_audio_seek(42 * GST_SECOND), (bool)true);
test_equal(audio_position(), 42 * GST_SECOND);
test_equal(audio_play(), (bool)true);
test_equal(audio_play(), (bool)false);
test_equal(state_count, 3);
test_equal(audio_pause(), (bool)true);
test_equal(state_count, 4);
test_equal(audio_cur_state(), GST_STATE_PAUSED);
/* Check duration again now that track is fully loaded. */
test_equal(audio_duration(), track_get(0)->tr_length * GST_SECOND);
}
static void test_next()
{
struct queue *history_q = playlist_get_queue(PL_SYSTEM, "History");
struct queue *temp_q = tempq_alloc(0);
int i;
state_count = 0;
/* First, let's test getting tracks from a temporary queue. */
queue_add(temp_q, track_get(2));
queue_add(temp_q, track_get(1));
queue_add(temp_q, track_get(0));
for (i = 2; i >= 0; i--) {
test_loop_equal(queue_size(temp_q), i + 1, i);
if (i > 0) {
test_loop_equal(audio_next()->tr_track, track_get(i)->tr_track, i);
} else /* Simulate an error. */
test_send_error();
test_loop_equal((void *)queue_at(history_q, 0),
(void *)track_get(i), i);
test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i);
test_loop_equal((void *)audio_cur_track(),
(void *)track_get(i), i);
} test_loop_passed();
test_equal(state_count, 3);
test_equal((void *)tempq_get(0), NULL);
/* Tracks should now be picked from the collection. */
for (i = 1; i <= 3; i++) {
if (i < 3) {
test_loop_equal(audio_next()->tr_track, i, i);
} else /* Simulate an error. */
test_send_error();
test_loop_equal(queue_at(history_q, 0)->tr_track, i, i);
test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i);
test_loop_equal(audio_cur_track()->tr_track, i, i);
} test_loop_passed();
test_equal(state_count, 6);
}
static void test_prev()
{
struct queue *history_q = playlist_get_queue(PL_SYSTEM, "History");
struct track *track = queue_at(history_q, 0);
state_count = 0;
test_equal(audio_prev()->tr_track, 2);
test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, 2);
test_equal(state_count, 1);
test_equal(audio_prev()->tr_track, 1);
test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, 1);
test_equal(state_count, 2);
test_equal(audio_pause(), (bool)true);
test_equal(audio_prev()->tr_track, track_get(0)->tr_track);
test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, track_get(0)->tr_track);
test_equal(state_count, 4);
test_equal(audio_prev()->tr_track, track_get(1)->tr_track);
test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, track_get(1)->tr_track);
test_equal(state_count, 5);
test_equal(audio_prev()->tr_track, track_get(2)->tr_track);
test_equal((void *)queue_at(history_q, 0), (void *)track);
test_equal(audio_cur_state(), GST_STATE_PLAYING);
test_equal(audio_cur_track()->tr_track, track_get(2)->tr_track);
test_equal(state_count, 6);
}
void test_autopause()
{
struct queue *history_q = playlist_get_queue(PL_SYSTEM, "History");
int i;
audio_pause_after(3);
test_equal(pause_count, 3);
pause_count = 0;
audio_pause_after(3);
test_equal(pause_count, 0);
audio_pause_after(5);
test_equal(pause_count, 5);
state_count = 0;
for (i = 4; i > -1; i--) {
audio_eos();
test_loop_equal(pause_count, i, i);
test_loop_equal(audio_cur_state(), GST_STATE_PLAYING, i);
test_loop_equal((void *)queue_at(history_q, 0),
(void *)audio_cur_track(), i);
} test_loop_passed();
test_equal(state_count, 5);
audio_eos();
test_equal(pause_count, -1);
test_equal(audio_cur_state(), GST_STATE_PAUSED);
test_equal(state_count, 6);
test_send_error();
test_equal(audio_cur_state(), GST_STATE_PAUSED);
}
static void test_deinit()
{
core_deinit();
test_equal((void *)audio_cur_track(), NULL);
test_equal((void *)test_audio_player(), NULL);
}
DECLARE_UNIT_TESTS(
UNIT_TEST("Audio Initialization", test_init),
UNIT_TEST("Audio Playback", test_playback),
UNIT_TEST("Audio Next", test_next),
UNIT_TEST("Audio Previous", test_prev),
UNIT_TEST("Audio Automatic Pausing", test_autopause),
UNIT_TEST("Audio Deinitialization", test_deinit),
);