test_queue_priority.cxx 4.9 KB
Newer Older
1
#include "config.h"
Max Kellermann's avatar
Max Kellermann committed
2
#include "queue/Queue.hxx"
3
#include "DetachedSong.hxx"
4
#include "util/Macros.hxx"
5

6 7 8 9
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
10

11
Tag::Tag(const Tag &) noexcept {}
12
void Tag::Clear() noexcept {}
13 14

static void
15
check_descending_priority(const Queue *queue,
16
			  unsigned start_order)
17
{
18
	assert(start_order < queue->GetLength());
19 20

	uint8_t last_priority = 0xff;
21 22
	for (unsigned order = start_order; order < queue->GetLength(); ++order) {
		unsigned position = queue->OrderToPosition(order);
23 24
		uint8_t priority = queue->items[position].priority;
		assert(priority <= last_priority);
25
		(void)last_priority;
26 27 28 29
		last_priority = priority;
	}
}

30 31 32 33 34 35 36 37 38 39 40
class QueuePriorityTest : public CppUnit::TestFixture {
	CPPUNIT_TEST_SUITE(QueuePriorityTest);
	CPPUNIT_TEST(TestPriority);
	CPPUNIT_TEST_SUITE_END();

public:
	void TestPriority();
};

void
QueuePriorityTest::TestPriority()
41
{
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
	DetachedSong songs[16] = {
		DetachedSong("0.ogg"),
		DetachedSong("1.ogg"),
		DetachedSong("2.ogg"),
		DetachedSong("3.ogg"),
		DetachedSong("4.ogg"),
		DetachedSong("5.ogg"),
		DetachedSong("6.ogg"),
		DetachedSong("7.ogg"),
		DetachedSong("8.ogg"),
		DetachedSong("9.ogg"),
		DetachedSong("a.ogg"),
		DetachedSong("b.ogg"),
		DetachedSong("c.ogg"),
		DetachedSong("d.ogg"),
		DetachedSong("e.ogg"),
		DetachedSong("f.ogg"),
	};
60

61
	Queue queue(32);
62

63
	for (unsigned i = 0; i < ARRAY_SIZE(songs); ++i)
64
		queue.Append(DetachedSong(songs[i]), 0);
65

66
	CPPUNIT_ASSERT_EQUAL(unsigned(ARRAY_SIZE(songs)), queue.GetLength());
67 68 69

	/* priority=10 for 4 items */

70
	queue.SetPriorityRange(4, 8, 10, -1);
71 72

	queue.random = true;
73
	queue.ShuffleOrder();
74 75 76
	check_descending_priority(&queue, 0);

	for (unsigned i = 0; i < 4; ++i) {
77
		assert(queue.PositionToOrder(i) >= 4);
78 79 80
	}

	for (unsigned i = 4; i < 8; ++i) {
81
		assert(queue.PositionToOrder(i) < 4);
82 83
	}

84
	for (unsigned i = 8; i < ARRAY_SIZE(songs); ++i) {
85
		assert(queue.PositionToOrder(i) >= 4);
86 87 88 89
	}

	/* priority=50 one more item */

90
	queue.SetPriorityRange(15, 16, 50, -1);
91 92
	check_descending_priority(&queue, 0);

93
	CPPUNIT_ASSERT_EQUAL(0u, queue.PositionToOrder(15));
94 95

	for (unsigned i = 0; i < 4; ++i) {
96
		assert(queue.PositionToOrder(i) >= 4);
97 98 99
	}

	for (unsigned i = 4; i < 8; ++i) {
100 101
		assert(queue.PositionToOrder(i) >= 1 &&
		       queue.PositionToOrder(i) < 5);
102 103 104
	}

	for (unsigned i = 8; i < 15; ++i) {
105
		assert(queue.PositionToOrder(i) >= 5);
106 107 108 109
	}

	/* priority=20 for one of the 4 priority=10 items */

110
	queue.SetPriorityRange(3, 4, 20, -1);
111 112
	check_descending_priority(&queue, 0);

113 114
	CPPUNIT_ASSERT_EQUAL(1u, queue.PositionToOrder(3));
	CPPUNIT_ASSERT_EQUAL(0u, queue.PositionToOrder(15));
115 116

	for (unsigned i = 0; i < 3; ++i) {
117
		assert(queue.PositionToOrder(i) >= 5);
118 119 120
	}

	for (unsigned i = 4; i < 8; ++i) {
121 122
		assert(queue.PositionToOrder(i) >= 2 &&
		       queue.PositionToOrder(i) < 6);
123 124 125
	}

	for (unsigned i = 8; i < 15; ++i) {
126
		assert(queue.PositionToOrder(i) >= 6);
127 128 129 130 131 132 133 134
	}

	/* 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 =
135
		queue.OrderToPosition(current_order);
136 137

	unsigned a_order = 3;
138
	unsigned a_position = queue.OrderToPosition(a_order);
139
	CPPUNIT_ASSERT_EQUAL(10u, unsigned(queue.items[a_position].priority));
140
	queue.SetPriority(a_position, 20, current_order);
141

142
	current_order = queue.PositionToOrder(current_position);
143
	CPPUNIT_ASSERT_EQUAL(3u, current_order);
144

145
	a_order = queue.PositionToOrder(a_position);
146
	CPPUNIT_ASSERT_EQUAL(4u, a_order);
147 148 149 150 151 152 153 154

	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;
155
	unsigned b_position = queue.OrderToPosition(b_order);
156
	CPPUNIT_ASSERT_EQUAL(0u, unsigned(queue.items[b_position].priority));
157
	queue.SetPriority(b_position, 70, current_order);
158

159
	current_order = queue.PositionToOrder(current_position);
160
	CPPUNIT_ASSERT_EQUAL(3u, current_order);
161

162
	b_order = queue.PositionToOrder(b_position);
163
	CPPUNIT_ASSERT_EQUAL(4u, b_order);
164 165 166 167 168

	check_descending_priority(&queue, current_order + 1);

	/* move the prio=20 item back */

169
	a_order = queue.PositionToOrder(a_position);
170 171
	CPPUNIT_ASSERT_EQUAL(5u, a_order);
	CPPUNIT_ASSERT_EQUAL(20u, unsigned(queue.items[a_position].priority));
172
	queue.SetPriority(a_position, 5, current_order);
173

174
	current_order = queue.PositionToOrder(current_position);
175
	CPPUNIT_ASSERT_EQUAL(3u, current_order);
176

177
	a_order = queue.PositionToOrder(a_position);
178 179 180 181 182 183 184 185 186 187 188 189
	CPPUNIT_ASSERT_EQUAL(6u, a_order);
}

CPPUNIT_TEST_SUITE_REGISTRATION(QueuePriorityTest);

int
main(gcc_unused int argc, gcc_unused char **argv)
{
	CppUnit::TextUi::TestRunner runner;
	auto &registry = CppUnit::TestFactoryRegistry::getRegistry();
	runner.addTest(registry.makeTest());
	return runner.run() ? EXIT_SUCCESS : EXIT_FAILURE;
190
}