/* * Copyright 2014 (c) Anna Schumaker. */ #include #include #include #include #include unsigned int count_add = 0; unsigned int count_del = 0; unsigned int count_updated = 0; unsigned int last_update = 0; Track *TRACK_NULL = NULL; class TestQueue : public Queue { public: TestQueue() : Queue() {} TestQueue(unsigned int f) : Queue(f) {} unsigned int get_cur() { return _cur; } unsigned int get_flags() { return _flags; } unsigned int get_length() { return _length; } std::vector get_sorder() { return _sort_order; }; }; void test_add_cb_noop(Queue *q, unsigned int id) { } void test_del_cb_noop(Queue *q, unsigned int id) { } void test_default() { TestQueue q; test_equal(q.get_cur(), (unsigned)-1); test_equal(q.get_flags(), (unsigned)0); test_equal(q.get_length(), (unsigned)0); test_equal(q.get_sorder().size(), (size_t)0); test_equal(q.next(), (Track *)NULL); } void test_constructor(unsigned int flags) { TestQueue q(flags | (1 << 30)); test_equal(q.get_cur(), (unsigned)-1); test_equal(q.get_flags(), flags); test_equal(q.get_length(), (unsigned)0); test_equal(q.get_sorder().size(), (size_t)0); test_equal(q.next(), (Track *)NULL); } 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_cb(Queue *q, unsigned int id) { check_equal(id, count_add); count_add++; } void test_del_cb(Queue *q, unsigned int id) { if (count_del % 2 == 0) check_equal(id, (unsigned)0); else check_equal(id, 24 - ((count_del + 1) / 2)); count_del++; } void test_del_cb2(Queue *q, unsigned int id) { check_equal(id, 23 - count_del); count_del++; } void test_del_cb3(Queue *q, unsigned int id) { check_equal(id, (unsigned)0); } void test_add_remove() { Track *track; TestQueue q(0); unsigned int expected = 0; get_callbacks()->on_queue_track_add = test_add_cb; get_callbacks()->on_queue_track_del = test_del_cb; test_equal(q.get_length(), expected); test_equal(q.length_str(), (std::string)""); test_equal(q.size(), (unsigned)0); test_equal(q.size_str(), (std::string)"0"); /* Add tracks */ test :: begin(); for (unsigned int i = 0; i < 24; i++) { check_equal(q.add(tags :: get_track(i)), i); expected += 100 + (i * 10); } test :: success(); test_equal(q.get_length(), expected); test_equal(q.length_str(), (std::string)"1 hour, 26 minutes"); test_equal(q.size(), (unsigned)24); test_equal(q.size_str(), (std::string)"24"); /* Add everything again */ test :: begin(); for (unsigned int i = 0; i < 24; i++) { check_equal(q.add(tags :: get_track(i)), i + 24); expected += 100 + (i * 10); } test :: success(); test_equal(q.get_length(), expected); test_equal(q.length_str(), (std::string)"2 hours, 52 minutes"); test_equal(q.size(), (unsigned)48); test_equal(q.size_str(), (std::string)"48"); /* Test removing multiple tracks at once */ test :: begin(); for (unsigned int i = 0; i < 12; i++) { track = tags :: get_track(i); q.del(track); expected -= 2 * (100 + (i * 10)); } test :: success(); test_equal(q.get_length(), expected); test_equal(q.length_str(), (std::string)"1 hour, 50 minutes"); test_equal(q.size(), (unsigned)24); test_equal(q.size_str(), (std::string)"24"); /* Test removing tracks one at a time */ count_del = 0; get_callbacks()->on_queue_track_del = test_del_cb2; test :: begin(); for (unsigned int i = 23; i >= 12; i--) { expected -= q[i]->length(); q.del(i); } test :: success(); test_equal(q.get_length(), expected); test_equal(q.length_str(), (std::string)"55 minutes"); test_equal(q.size(), (unsigned)12); test_equal(q.size_str(), (std::string)"12"); /* Remove remaining tracks */ get_callbacks()->on_queue_track_del = test_del_cb3; test :: begin(); while (q.size() > 0) q.del((unsigned)0); test :: success(); test_equal(q.get_length(), (unsigned)0); test_equal(q.length_str(), (std::string)""); test_equal(q.size(), (unsigned)0); test_equal(q.size_str(), (std::string)"0"); } void test_updated_cb(Queue *q, unsigned int row) { last_update = row; } void test_updated_cb2(Queue *q, unsigned int row) { switch (row) { case 0: case 24: case 25: count_updated++; default: break; } } void test_updated() { Track *track; TestQueue q(0); get_callbacks()->on_queue_track_add = test_add_cb_noop; get_callbacks()->on_queue_track_changed = test_updated_cb; /* Add tracks */ test :: begin(); for (unsigned int i = 0; i < 24; i++) check_equal(q.add(tags :: get_track(i)), i); test :: success(); test :: begin(); for (unsigned int i = 0; i < 24; i++) q.updated(tags :: get_track(i)); test :: success(); get_callbacks()->on_queue_track_changed = test_updated_cb2; track = tags :: get_track(0); q.add(track); q.add(track); q.updated(track); test_equal(count_updated, (unsigned)3); } static void test_fill_q(TestQueue *q) { for (unsigned int i = 0; i < 24; i++) q->add(tags :: get_track(i)); } 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() { Track *track; TestQueue q(0); get_callbacks()->on_queue_track_del = test_del_cb_noop; test_fill_q(&q); test :: begin(); for (unsigned int i = 0; i < 24; i++) { track = q.next(); check_not_equal(track, TRACK_NULL); check_equal(track->index(), i); } test :: success(); test_equal(q.size(), (unsigned)0); test_equal(q.length_str(), (std::string)""); test_equal(q.next(), TRACK_NULL); q.set_flag(Q_RANDOM); random_seed(0); test_fill_q(&q); test :: begin(); for (unsigned int i = 0; i < 24; i++) { track = q.next(); check_not_equal(track, TRACK_NULL); check_equal(track->index(), expected_rand[i]); } test :: success(); test_equal(q.size(), (unsigned)0); test_equal(q.length_str(), (std::string)""); test_equal(q.next(), TRACK_NULL); q.set_flag(Q_REPEAT); q.unset_flag(Q_RANDOM); test_fill_q(&q); test :: begin(); for (unsigned int i = 0; i < 48; i++) { track = q.next(); check_not_equal(track, TRACK_NULL); check_equal(track->index(), i % 24); } test :: success(); 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()->index(), (unsigned)11); q.set_flag(Q_REPEAT); q.track_selected(0); test_equal(q.size(), (unsigned)22); test_equal(q.next()->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, 22, 21, 17, 23, 20, 16, 19, 18, 15, 14, 13, 12 }; void test_sorting() { TestQueue q(0); q.sort(SORT_TITLE, true); test_equal(q.get_sorder().size(), (size_t)1); test_fill_q(&q); test :: begin(); for (unsigned int i = 0; i < 24; i++) check_equal(q[i]->index(), exp_sort_title[i]); test :: success(); q.sort(SORT_TITLE, false); test_equal(q.get_sorder().size(), (size_t)1); test :: begin(); for (unsigned int i = 0; i < 24; i++) check_equal(q[i]->index(), exp_sort_title[23 - i]); test :: success(); q.sort(SORT_LENGTH, true); test :: begin(); for (unsigned int i = 0; i < 24; i++) check_equal(q[i]->index(), i); test :: success(); q.sort(SORT_YEAR, true); q.sort(SORT_TITLE, false); q.sort(SORT_TITLE, false); test_equal(q.get_sorder().size(), (size_t)2); test :: begin(); for (unsigned int i = 0; i < 24; i++) check_equal(q[i]->index(), exp_sort_ye_ti[i]); test :: success(); } void test_saving() { TestQueue q(Q_RANDOM); TestQueue r(0); File f("test.q", 0); test_fill_q(&q); test :: begin(); f.open(OPEN_WRITE); q.write(f); f.close(); test :: success(); test :: begin(); f.open(OPEN_READ); r.read(f); f.close(); test :: success(); test_equal(r.has_flag(Q_RANDOM), q.has_flag(Q_RANDOM)); test_equal(r.size(), q.size()); test_equal(r.size_str(), q.size_str()); test_equal(r.length_str(), q.length_str()); test :: begin(); for (unsigned int i = 0; i < q.size(); i++) check_equal(r[i]->index(), q[i]->index()); test :: success(); } int main(int argc, char **argv) { test :: cp_data_dir(); tags :: init(); run_test("Queue Default Constructor Test", test_default); run_test("Queue Constructor Test", test_constructor, Q_ENABLED | Q_RANDOM); run_test("Queue Flag Test", test_flags); run_test("Queue Add and Remove Test", test_add_remove); run_test("Queue Track Updated Test", test_updated); run_test("Queue Pick Next Test", test_next); run_test("Queue Select Track Test", test_select); run_test("Queue Sorting Test", test_sorting); run_test("Queue Save and Load Test", test_saving); return 0; }