/* * Copyright 2014 (c) Anna Schumaker. */ #include extern "C" { #include #include #include } #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 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), );