ocarina/tests/core/queue.cpp

321 lines
7.7 KiB
C++
Raw Normal View History

/*
* Copyright 2014 (c) Anna Schumaker.
*/
#include <core/queue.h>
extern "C" {
#include <core/filter.h>
#include <core/random.h>
#include <core/tags/tags.h>
}
#include "test.h"
unsigned int count_add = 0;
unsigned int count_del = 0;
unsigned int count_updated = 0;
unsigned int last_update = 0;
unsigned int expected = 0;
struct track *TRACK_NULL = NULL;
static class TestNotifier : public QNotifier {
public:
TestNotifier() : QNotifier() {}
void on_track_added(unsigned int i) { count_add++; }
void on_track_removed(unsigned int i) { count_del++; }
void on_track_updated(unsigned int i) { count_updated++; last_update = i; }
} test_notifier;
class TestQueue : public Queue {
public:
TestQueue() : Queue() { set_notifier(&test_notifier); }
TestQueue(unsigned int f) : Queue(f) { set_notifier(&test_notifier); }
~TestQueue() {}
unsigned int get_cur() { return _cur; }
unsigned int get_flags() { return _flags; }
QNotifier *get_notify() { return _notify; }
std::vector <sort_info> get_sorder() { return _sort_order; };
};
void test_default()
{
TestQueue q;
test_equal(q.get_cur(), (unsigned)-1);
test_equal(q.get_flags(), (unsigned)0);
test_equal(q.length(), (unsigned)0);
test_equal(q.get_sorder().size(), (size_t)0);
test_equal(q.next(), (struct track *)NULL);
test_equal(q.get_notify(), &test_notifier);
}
void test_constructor()
{
unsigned int flags = Q_ENABLED | Q_RANDOM;
TestQueue q(flags);
test_equal(q.get_cur(), (unsigned)-1);
test_equal(q.get_flags(), flags);
test_equal(q.length(), (unsigned)0);
test_equal(q.get_sorder().size(), (size_t)0);
test_equal(q.next(), (struct track *)NULL);
test_equal(q.get_notify(), &test_notifier);
}
void test_flags()
{
TestQueue q(0);
test_equal(q.get_flags(), (unsigned)0);
q.set_flag(Q_ENABLED);
test_equal(q.get_flags(), (unsigned)Q_ENABLED);
q.unset_flag(Q_ENABLED);
test_equal(q.get_flags(), (unsigned)0);
q.set_flag(Q_REPEAT);
q.set_flag(Q_RANDOM);
test_equal(q.has_flag(Q_ENABLED), false);
test_equal(q.has_flag(Q_RANDOM), true);
test_equal(q.has_flag(Q_REPEAT), true);
test_equal(q.has_flag(Q_NO_SORT), false);
}
void test_add_remove()
{
TestQueue q(0);
struct track *track;
test_cp_data_dir();
filter_init();
tags_init();
test_equal(q.length(), expected);
test_equal(q.size(), (unsigned)0);
/* Add tracks */
for (unsigned int i = 0; i < 24; i++) {
track = track_get(i);
expected += track->tr_length;
test_loop_equal(q.add(track), i, i);
test_loop_equal(count_add, i + 1, i);
} test_loop_passed();
test_equal(q.length(), expected);
test_equal(q.size(), (unsigned)24);
/* Add everything again */
for (unsigned int i = 24; i < 48; i++) {
track = track_get(i - 24);
expected += track->tr_length;
test_loop_equal(q.add(track), i, i);
test_loop_equal(count_add, i + 1, i);
} test_loop_passed();
test_equal(q.length(), expected);
test_equal(q.size(), (unsigned)48);
/* Test removing multiple tracks at once */
count_del = 0;
for (unsigned int i = 0; i < 12; i++) {
track = track_get(i);
q.del(track);
expected -= track->tr_length * 2;
test_loop_equal(count_del, (i + 1) * 2, i);
}
test_equal(q.length(), expected);
test_equal(q.size(), (unsigned)24);
/* Test removing tracks one at a time */
count_del = 0;
for (unsigned int i = 0; i < 12; i++) {
expected -= q[23 - i]->tr_length;
q.del((unsigned int)(23 - i));
test_loop_equal(count_del, (i + 1), i);
} test_loop_passed();
test_equal(q.length(), expected);
test_equal(q.size(), (unsigned)12);
/* Remove remaining tracks */
count_del = 0;
for (unsigned int i = 0; i < 12; i++) {
expected -= q[0]->tr_length;
q.del((unsigned int)0);
test_loop_equal(count_del, i + 1, i);
} test_loop_passed();
test_equal(q.length(), (unsigned)0);
test_equal(q.size(), (unsigned)0);
}
static void test_fill_q(TestQueue *q)
{
for (unsigned int i = 0; i < 24; i++)
q->add(track_get(i));
}
void test_updated()
{
struct track *track;
TestQueue q(0);
test_fill_q(&q);
for (unsigned int i = 0; i < 24; i++) {
q.updated(track_get(i));
test_loop_equal(last_update, i, i);
test_loop_equal(count_updated, i + 1, i);
} test_loop_passed();
track = track_get(0);
q.add(track);
q.add(track);
q.updated(track);
test_equal(count_updated, (unsigned)24 + 3);
}
unsigned int expected_rand[] = { 1, 4, 8, 13, 19, 3, 14, 16, 20, 2, 11, 17,
23, 6, 12, 18, 0, 5, 9, 10, 15, 21, 22, 7 };
void test_next()
{
struct track *track;
TestQueue q(0);
test_fill_q(&q);
for (unsigned int i = 0; i < 24; i++) {
track = q.next();
test_loop_not_equal(track, NULL, i);
test_loop_equal(track->tr_dbe.dbe_index, i % 24, i);
} test_loop_passed();
test_equal(q.size(), (unsigned)0);
test_equal(q.length(), 0);
test_equal(q.next(), TRACK_NULL);
q.set_flag(Q_RANDOM);
random_seed(0);
test_fill_q(&q);
for (unsigned int i = 0; i < 24; i++) {
track = q.next();
test_loop_not_equal(track, NULL, i);
test_loop_equal(track->tr_dbe.dbe_index, expected_rand[i], i);
} test_loop_passed();
test_equal(q.size(), (unsigned)0);
test_equal(q.length(), 0);
test_equal(q.next(), TRACK_NULL);
q.set_flag(Q_REPEAT);
q.unset_flag(Q_RANDOM);
test_fill_q(&q);
for (unsigned int i = 0; i < 48; i++) {
track = q.next();
test_loop_not_equal(track, NULL, i);
test_loop_equal(track->tr_dbe.dbe_index, i % 24, i);
} test_loop_passed();
test_equal(q.size(), (unsigned)24);
}
void test_select()
{
TestQueue q(0);
test_fill_q(&q);
test_equal(q.size(), (unsigned)24);
q.track_selected(10);
test_equal(q.size(), (unsigned)23);
test_equal(q.next()->tr_dbe.dbe_index, (unsigned)11);
q.set_flag(Q_REPEAT);
q.track_selected(0);
test_equal(q.size(), (unsigned)22);
test_equal(q.next()->tr_dbe.dbe_index, (unsigned)1);
}
unsigned int exp_sort_title[] = { 1, 18, 19, 16, 20, 8, 2, 9, 23, 10, 17, 11,
3, 21, 4, 0, 5, 22, 6, 12, 7, 13, 14, 15 };
unsigned int exp_sort_ye_ti[] = { 0, 3, 2, 1, 7, 6, 5, 4, 11, 10, 9, 8,
17, 16, 19, 18, 22, 21, 23, 20, 15, 14, 13, 12 };
void test_sorting()
{
TestQueue q(0);
q.sort(COMPARE_TITLE, true);
test_equal(q.get_sorder().size(), (size_t)1);
test_fill_q(&q);
for (unsigned int i = 0; i < 24; i++)
test_loop_equal(q[i]->tr_dbe.dbe_index, exp_sort_title[i], i);
test_loop_passed();
q.sort(COMPARE_TITLE, false);
test_equal(q.get_sorder().size(), (size_t)1);
for (unsigned int i = 0; i < 24; i++)
test_loop_equal(q[i]->tr_dbe.dbe_index, exp_sort_title[23 - i], i);
test_loop_passed();
q.sort(COMPARE_LENGTH, true);
for (unsigned int i = 0; i < 24; i++)
test_loop_equal(q[i]->tr_dbe.dbe_index, i, i);
test_loop_passed();
q.sort(COMPARE_YEAR, true);
q.sort(COMPARE_TITLE, false);
q.sort(COMPARE_TITLE, false);
test_equal(q.get_sorder().size(), (size_t)2);
for (unsigned int i = 0; i < 24; i++)
test_loop_equal(q[i]->tr_dbe.dbe_index, exp_sort_ye_ti[i], i);
test_loop_passed();
}
void test_saving()
{
TestQueue q(Q_RANDOM);
TestQueue r(0);
file f;
test_fill_q(&q);
file_init(&f, "test.q", 0);
file_open(&f, OPEN_WRITE);
q.write(f);
file_close(&f);
file_open(&f, OPEN_READ);
r.read(f);
file_close(&f);
test_equal(r.has_flag(Q_RANDOM), q.has_flag(Q_RANDOM));
test_equal(r.size(), q.size());
test_equal(r.length(), q.length());
for (unsigned int i = 0; i < 24; i++)
test_loop_equal(q[i]->tr_dbe.dbe_index, r[i]->tr_dbe.dbe_index, i);
test_loop_passed();
}
DECLARE_UNIT_TESTS(
UNIT_TEST("Queue Default Constructor", test_default),
UNIT_TEST("Queue Constructor", test_constructor),
UNIT_TEST("Queue Flags", test_flags),
UNIT_TEST("Queue Add and Remove", test_add_remove),
UNIT_TEST("Queue Track Updated", test_updated),
UNIT_TEST("Queue Pick Next Track", test_next),
UNIT_TEST("Queue Select Track", test_select),
UNIT_TEST("Queue Sorting", test_sorting),
UNIT_TEST("Queue Save and Load", test_saving),
);