aboutsummaryrefslogtreecommitdiff
path: root/test/test_queue_priority.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_queue_priority.cxx')
-rw-r--r--test/test_queue_priority.cxx186
1 files changed, 186 insertions, 0 deletions
diff --git a/test/test_queue_priority.cxx b/test/test_queue_priority.cxx
new file mode 100644
index 00000000..cab56d82
--- /dev/null
+++ b/test/test_queue_priority.cxx
@@ -0,0 +1,186 @@
+#include "config.h"
+#include "Queue.hxx"
+#include "song.h"
+#include "Directory.hxx"
+
+Directory detached_root;
+
+Directory::Directory() {}
+Directory::~Directory() {}
+
+struct song *
+song_dup_detached(const struct song *src)
+{
+ return const_cast<song *>(src);
+}
+
+void
+song_free(G_GNUC_UNUSED struct song *song)
+{
+}
+
+G_GNUC_UNUSED
+static void
+dump_order(const struct queue *queue)
+{
+ g_printerr("queue length=%u, order:\n", queue->GetLength());
+ for (unsigned i = 0; i < queue->GetLength(); ++i)
+ g_printerr(" [%u] -> %u (prio=%u)\n", i, queue->order[i],
+ queue->items[queue->order[i]].priority);
+}
+
+static void
+check_descending_priority(const struct queue *queue,
+ unsigned start_order)
+{
+ assert(start_order < queue->GetLength());
+
+ uint8_t last_priority = 0xff;
+ for (unsigned order = start_order; order < queue->GetLength(); ++order) {
+ unsigned position = queue->OrderToPosition(order);
+ uint8_t priority = queue->items[position].priority;
+ assert(priority <= last_priority);
+ (void)last_priority;
+ last_priority = priority;
+ }
+}
+
+int
+main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
+{
+ static struct song songs[16];
+
+ struct queue queue(32);
+
+ for (unsigned i = 0; i < G_N_ELEMENTS(songs); ++i)
+ queue.Append(&songs[i], 0);
+
+ assert(queue.GetLength() == G_N_ELEMENTS(songs));
+
+ /* priority=10 for 4 items */
+
+ queue.SetPriorityRange(4, 8, 10, -1);
+
+ queue.random = true;
+ queue.ShuffleOrder();
+ check_descending_priority(&queue, 0);
+
+ for (unsigned i = 0; i < 4; ++i) {
+ assert(queue.PositionToOrder(i) >= 4);
+ }
+
+ for (unsigned i = 4; i < 8; ++i) {
+ assert(queue.PositionToOrder(i) < 4);
+ }
+
+ for (unsigned i = 8; i < G_N_ELEMENTS(songs); ++i) {
+ assert(queue.PositionToOrder(i) >= 4);
+ }
+
+ /* priority=50 one more item */
+
+ queue.SetPriorityRange(15, 16, 50, -1);
+ check_descending_priority(&queue, 0);
+
+ assert(queue.PositionToOrder(15) == 0);
+
+ for (unsigned i = 0; i < 4; ++i) {
+ assert(queue.PositionToOrder(i) >= 4);
+ }
+
+ for (unsigned i = 4; i < 8; ++i) {
+ assert(queue.PositionToOrder(i) >= 1 &&
+ queue.PositionToOrder(i) < 5);
+ }
+
+ for (unsigned i = 8; i < 15; ++i) {
+ assert(queue.PositionToOrder(i) >= 5);
+ }
+
+ /* priority=20 for one of the 4 priority=10 items */
+
+ queue.SetPriorityRange(3, 4, 20, -1);
+ check_descending_priority(&queue, 0);
+
+ assert(queue.PositionToOrder(3) == 1);
+ assert(queue.PositionToOrder(15) == 0);
+
+ for (unsigned i = 0; i < 3; ++i) {
+ assert(queue.PositionToOrder(i) >= 5);
+ }
+
+ for (unsigned i = 4; i < 8; ++i) {
+ assert(queue.PositionToOrder(i) >= 2 &&
+ queue.PositionToOrder(i) < 6);
+ }
+
+ for (unsigned i = 8; i < 15; ++i) {
+ assert(queue.PositionToOrder(i) >= 6);
+ }
+
+ /* priority=20 for another one of the 4 priority=10 items;
+ pass "after_order" (with priority=10) and see if it's moved
+ after that one */
+
+ unsigned current_order = 4;
+ unsigned current_position =
+ queue.OrderToPosition(current_order);
+
+ unsigned a_order = 3;
+ unsigned a_position = queue.OrderToPosition(a_order);
+ assert(queue.items[a_position].priority == 10);
+ queue.SetPriority(a_position, 20, current_order);
+
+ current_order = queue.PositionToOrder(current_position);
+ assert(current_order == 3);
+
+ a_order = queue.PositionToOrder(a_position);
+ assert(a_order == 4);
+
+ check_descending_priority(&queue, current_order + 1);
+
+ /* priority=70 for one of the last items; must be inserted
+ right after the current song, before the priority=20 one we
+ just created */
+
+ unsigned b_order = 10;
+ unsigned b_position = queue.OrderToPosition(b_order);
+ assert(queue.items[b_position].priority == 0);
+ queue.SetPriority(b_position, 70, current_order);
+
+ current_order = queue.PositionToOrder(current_position);
+ assert(current_order == 3);
+
+ b_order = queue.PositionToOrder(b_position);
+ assert(b_order == 4);
+
+ check_descending_priority(&queue, current_order + 1);
+
+ /* priority=60 for the old prio50 item; must not be moved,
+ because it's before the current song, and it's status
+ hasn't changed (it was already higher before) */
+
+ unsigned c_order = 0;
+ unsigned c_position = queue.OrderToPosition(c_order);
+ assert(queue.items[c_position].priority == 50);
+ queue.SetPriority(c_position, 60, current_order);
+
+ current_order = queue.PositionToOrder(current_position);
+ assert(current_order == 3);
+
+ c_order = queue.PositionToOrder(c_position);
+ assert(c_order == 0);
+
+ /* move the prio=20 item back */
+
+ a_order = queue.PositionToOrder(a_position);
+ assert(a_order == 5);
+ assert(queue.items[a_position].priority == 20);
+ queue.SetPriority(a_position, 5, current_order);
+
+ current_order = queue.PositionToOrder(current_position);
+ assert(current_order == 3);
+
+ a_order = queue.PositionToOrder(a_position);
+ assert(a_order == 6);
+}