xref: /haiku/src/tests/system/kernel/util/SinglyLinkedListTest.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
1 #include <cppunit/Test.h>
2 #include <cppunit/TestCaller.h>
3 #include <cppunit/TestSuite.h>
4 #include <stdio.h>
5 #include <TestUtils.h>
6 
7 #include "SinglyLinkedListTest.h"
8 #include "SinglyLinkedList.h"
9 
10 SinglyLinkedListTest::SinglyLinkedListTest(std::string name)
11 	: BTestCase(name)
12 {
13 }
14 
15 CppUnit::Test*
16 SinglyLinkedListTest::Suite() {
17 	CppUnit::TestSuite *suite = new CppUnit::TestSuite("SLL");
18 
19 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::User Strategy Test (default next parameter)", &SinglyLinkedListTest::UserDefaultTest));
20 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::User Strategy Test (custom next parameter)", &SinglyLinkedListTest::UserCustomTest));
21 	suite->addTest(new CppUnit::TestCaller<SinglyLinkedListTest>("SinglyLinkedList::Auto Strategy Test (MallocFreeAllocator)", &SinglyLinkedListTest::AutoTest));
22 
23 	return suite;
24 }
25 
26 // Class used for testing default User strategy
27 class Link {
28 public:
29 	Link* next;
30 	long data;
31 
32 	bool operator==(const Link &ref) {
33 		return data == ref.data;
34 	}
35 };
36 
37 // Class used for testing custom User strategy
38 class MyLink {
39 public:
40 	MyLink* mynext;
41 	long data;
42 
43 	bool operator==(const MyLink &ref) {
44 		return data == ref.data;
45 	}
46 };
47 
48 using Strategy::SinglyLinkedList::User;
49 using Strategy::SinglyLinkedList::Auto;
50 
51 //! Tests the given list
52 template <class List>
53 void
54 SinglyLinkedListTest::TestList(List &list, typename List::ValueType *values, int valueCount)
55 {
56 	list.MakeEmpty();
57 
58 	// PushFront
59 	for (int i = 0; i < valueCount; i++) {
60 		NextSubTest();
61 		CHK(list.Count() == i);
62 		CHK(list.PushFront(values[i]) == B_OK);
63 		CHK(list.Count() == i+1);
64 	}
65 
66 {
67 	// Prefix increment
68 	int preIndex = valueCount-1;
69 	typename List::Iterator iterator;
70 	for (iterator = list.Begin(); iterator != list.End(); --preIndex) {
71 		NextSubTest();
72 // 		printf("(%p, %ld) %s (%p, %ld)\n", iterator->next, iterator->data, ((*iterator == values[preIndex]) ? "==" : "!="), values[preIndex].next, values[preIndex].data);
73 		CHK(*iterator == values[preIndex]);
74 		typename List::Iterator copy = iterator;
75 		CHK(copy == iterator);
76 		CHK(copy != ++iterator);
77 	}
78 	CHK(preIndex == -1);
79 }
80 	list.MakeEmpty();
81 
82 	// PushBack
83 	for (int i = 0; i < valueCount; i++) {
84 		NextSubTest();
85 		CHK(list.Count() == i);
86 		CHK(list.PushBack(values[i]) == B_OK);
87 		CHK(list.Count() == i+1);
88 	}
89 
90 	// Postfix increment
91 	int postIndex = 0;
92 	for (typename List::Iterator iterator = list.Begin(); iterator != list.End(); ++postIndex) {
93 		NextSubTest();
94 // 		printf("(%p, %ld) %s (%p, %ld)\n", iterator->next, iterator->data, ((*iterator == values[postIndex]) ? "==" : "!="), values[postIndex].next, values[postIndex].data);
95 		CHK(*iterator == values[postIndex]);
96 		typename List::Iterator copy = iterator;
97 		CHK(copy == iterator);
98 		CHK(copy == iterator++);
99 	}
100 	CHK(postIndex == valueCount);
101 
102 }
103 
104 //! Test using the User strategy with the default NextMember.
105 void
106 SinglyLinkedListTest::UserDefaultTest() {
107 	SinglyLinkedList<Link, User<Link> > list;
108 	const int valueCount = 10;
109 	Link values[valueCount];
110 	for (int i = 0; i < valueCount; i++) {
111 		values[i].data = i;
112 		if (i % 2)
113 			values[i].next = NULL;	// Leave some next pointers invalid just for fun
114 	}
115 
116 	TestList(list, values, valueCount);
117 }
118 
119 //! Test using the User strategy with a custom NextMember.
120 void
121 SinglyLinkedListTest::UserCustomTest() {
122 	SinglyLinkedList<MyLink, User<MyLink, &MyLink::mynext> > list;
123 	const int valueCount = 10;
124 	MyLink values[valueCount];
125 	for (int i = 0; i < valueCount; i++) {
126 		values[i].data = i*2;
127 		if (!(i % 2))
128 			values[i].mynext = NULL;	// Leave some next pointers invalid just for fun
129 	}
130 
131 	TestList(list, values, valueCount);
132 }
133 
134 //! Test using the Auto strategy.
135 void
136 SinglyLinkedListTest::AutoTest() {
137 	SinglyLinkedList<long> list;
138 	const int valueCount = 10;
139 	long values[valueCount];
140 	for (int i = 0; i < valueCount; i++) {
141 		values[i] = i*3;
142 	}
143 
144 	TestList(list, values, valueCount);
145 }
146