1 #include <cxxtest/TestSuite.h>
3 #include <stdarg.h>
4 #include "util/list-container.h"
6 using Inkscape::Util::ListContainer;
8 #define ARRAY_RANGE(array) (array), (array)+sizeof((array))/sizeof((array)[0])
10 static bool check_values(ListContainer<int> const &c, unsigned n_values, ...) {
11 bool ret = true;
12 va_list args;
13 va_start(args, n_values);
14 ListContainer<int>::const_iterator iter(c.begin());
15 while ( n_values && iter != c.end() ) {
16 int const value = va_arg(args, int);
17 if ( value != *iter ) {
18 ret = false;
19 }
20 if ( n_values == 1 && &c.back() != &*iter ) {
21 ret = false;
22 }
23 n_values--;
24 ++iter;
25 }
26 va_end(args);
27 return ret && n_values == 0 && iter == c.end();
28 }
30 class ListContainerTest : public CxxTest::TestSuite {
31 public:
32 ListContainerTest()
33 {
34 Inkscape::GC::init();
35 }
36 virtual ~ListContainerTest() {}
38 // createSuite and destroySuite get us per-suite setup and teardown
39 // without us having to worry about static initialization order, etc.
40 static ListContainerTest *createSuite() { return new ListContainerTest(); }
41 static void destroySuite( ListContainerTest *suite ) { delete suite; }
43 void testRangeConstructor()
44 {
45 int const values[]={1,2,3,4};
46 int const * const values_end=values+4;
47 ListContainer<int> container(values, values_end);
49 ListContainer<int>::iterator container_iter=container.begin();
50 int const * values_iter=values;
52 while ( values_iter != values_end && container_iter != container.end() ) {
53 TS_ASSERT_EQUALS(*values_iter , *container_iter);
54 ++values_iter;
55 ++container_iter;
56 }
58 TS_ASSERT_EQUALS(values_iter , values_end);
59 TS_ASSERT_EQUALS(container_iter , container.end());
60 }
62 void testEqualityTests()
63 {
64 int const a[] = { 1, 2, 3, 4 };
65 int const b[] = { 1, 2, 3, 4 };
66 int const c[] = { 1, 2, 3 };
67 int const d[] = { 1, 2, 3, 5 };
68 ListContainer<int> c_a(ARRAY_RANGE(a));
69 ListContainer<int> c_b(ARRAY_RANGE(b));
70 ListContainer<int> c_c(ARRAY_RANGE(c));
71 ListContainer<int> c_d(ARRAY_RANGE(d));
73 TS_ASSERT(c_a == c_b);
74 TS_ASSERT(!( c_a != c_b ));
75 TS_ASSERT(!( c_a == c_c ));
76 TS_ASSERT(c_a != c_c);
77 TS_ASSERT(!( c_a == c_d ));
78 TS_ASSERT(c_a != c_d);
79 }
81 void testLessThan()
82 {
83 int const a[] = { 1, 2, 3, 4 };
84 int const b[] = { 1, 2, 2, 4 };
85 int const c[] = { 1, 2, 4, 4 };
86 int const d[] = { 1, 2, 3 };
87 ListContainer<int> c_a(ARRAY_RANGE(a));
88 ListContainer<int> c_b(ARRAY_RANGE(b));
89 ListContainer<int> c_c(ARRAY_RANGE(c));
90 ListContainer<int> c_d(ARRAY_RANGE(d));
91 TS_ASSERT(c_a >= c_b);
92 TS_ASSERT(!( c_a < c_b ));
93 TS_ASSERT(!( c_a >= c_c ));
94 TS_ASSERT(c_a < c_c);
95 TS_ASSERT(!( c_a < c_d ));
96 TS_ASSERT(c_a >= c_d);
97 TS_ASSERT(c_d < c_a);
98 }
100 void testAssignmentOperator()
101 {
102 int const a[] = { 1, 2, 3, 4 };
103 ListContainer<int> c_a(ARRAY_RANGE(a));
104 ListContainer<int> c_c;
105 TS_ASSERT(c_a != c_c);
106 c_c = c_a;
107 TS_ASSERT(c_a == c_c);
108 c_c = c_a;
109 TS_ASSERT(c_a == c_c);
110 }
112 void testFillConstructor()
113 {
114 ListContainer<int> filled((std::size_t)3, 2);
115 TS_ASSERT(check_values(filled, 3, 2, 2, 2));
116 }
118 void testContainerSize()
119 {
120 ListContainer<int> empty;
121 TS_ASSERT(empty.empty());
122 TS_ASSERT_EQUALS(empty.size() , 0);
123 int const a[] = { 1, 2, 3 };
124 ListContainer<int> c_a(ARRAY_RANGE(a));
125 TS_ASSERT(!c_a.empty());
126 TS_ASSERT_EQUALS(c_a.size() , 3);
128 TS_ASSERT_LESS_THAN(0 , empty.max_size());
129 }
131 void testAppending()
132 {
133 ListContainer<int> c;
134 c.push_back(1);
135 TS_ASSERT(check_values(c, 1, 1));
136 c.push_back(2);
137 TS_ASSERT(check_values(c, 2, 1, 2));
138 c.push_back(3);
139 TS_ASSERT(check_values(c, 3, 1, 2, 3));
140 }
142 void testBulkAppending()
143 {
144 int const a[] = { 1, 2, 3, 4 };
145 int const b[] = { 5, 6, 7 };
146 ListContainer<int> c_a(ARRAY_RANGE(a));
147 ListContainer<int> c_b(ARRAY_RANGE(b));
148 c_a.insert(c_a.end(), c_b.begin(), c_b.end());
149 TS_ASSERT(check_values(c_a, 7, 1, 2, 3, 4, 5, 6, 7));
150 }
152 void testPrepending()
153 {
154 ListContainer<int> c;
155 c.push_front(1);
156 TS_ASSERT(check_values(c, 1, 1));
157 c.push_front(2);
158 TS_ASSERT(check_values(c, 2, 2, 1));
159 c.push_front(3);
160 TS_ASSERT(check_values(c, 3, 3, 2, 1));
161 }
163 void testSingleValueInsertion()
164 {
165 ListContainer<int> c;
167 c.insert(c.begin(), 1);
168 TS_ASSERT(check_values(c, 1, 1));
170 c.insert(c.end(), 2);
171 TS_ASSERT(check_values(c, 2, 1, 2));
173 c.insert(c.begin(), 3);
174 TS_ASSERT(check_values(c, 3, 3, 1, 2));
176 ListContainer<int>::iterator pos=c.begin();
177 ++pos;
178 c.insert(pos, 4);
179 TS_ASSERT(check_values(c, 4, 3, 4, 1, 2));
180 }
182 void testSingleValueErasure()
183 {
184 int const values[] = { 1, 2, 3, 4 };
185 ListContainer<int> c(ARRAY_RANGE(values));
187 c.erase(c.begin());
188 TS_ASSERT(check_values(c, 3, 2, 3, 4));
190 ListContainer<int>::iterator pos=c.begin();
191 ++pos;
192 c.erase(pos);
193 TS_ASSERT(check_values(c, 2, 2, 4));
195 pos=c.begin();
196 ++pos;
197 c.erase(pos);
198 TS_ASSERT(check_values(c, 1, 2));
200 c.erase(c.begin());
201 TS_ASSERT(check_values(c, 0));
202 }
204 void testPopFront()
205 {
206 int const full_ary[] = { 1, 2, 3 };
207 ListContainer<int> t(ARRAY_RANGE(full_ary));
208 TS_ASSERT(check_values(t, 3, 1, 2, 3));
209 TS_ASSERT_EQUALS(t.back() , 3);
210 t.pop_front();
211 TS_ASSERT(check_values(t, 2, 2, 3));
212 TS_ASSERT_EQUALS(t.back() , 3);
213 t.push_back(23);
214 TS_ASSERT(check_values(t, 3, 2, 3, 23));
215 TS_ASSERT_EQUALS(t.back() , 23);
216 t.pop_front();
217 TS_ASSERT(check_values(t, 2, 3, 23));
218 TS_ASSERT_EQUALS(t.back() , 23);
219 t.pop_front();
220 TS_ASSERT(check_values(t, 1, 23));
221 TS_ASSERT_EQUALS(t.back() , 23);
222 t.pop_front();
223 TS_ASSERT(check_values(t, 0));
224 t.push_back(42);
225 TS_ASSERT(check_values(t, 1, 42));
226 TS_ASSERT_EQUALS(t.back() , 42);
227 }
229 void testEraseAfter()
230 {
231 int const full_ary[] = { 1, 2, 3, 4 };
232 int const exp_ary[] = { 1, 3, 4 };
233 ListContainer<int> full_list(ARRAY_RANGE(full_ary));
234 ListContainer<int> exp_list(ARRAY_RANGE(exp_ary));
235 TS_ASSERT(full_list != exp_list);
236 full_list.erase_after(full_list.begin());
237 TS_ASSERT(full_list == exp_list);
238 }
239 };
241 /*
242 Local Variables:
243 mode:c++
244 c-file-style:"stroustrup"
245 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
246 indent-tabs-mode:nil
247 fill-column:99
248 End:
249 */
250 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :