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
10SinglyLinkedListTest::SinglyLinkedListTest(std::string name)
11	: BTestCase(name)
12{
13}
14
15CppUnit::Test*
16SinglyLinkedListTest::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
22	return suite;
23}
24
25// Class used for testing default User strategy
26class Link {
27public:
28	SinglyLinkedListLink<Link> next;
29	long data;
30
31	SinglyLinkedListLink<Link>* GetSinglyLinkedListLink() {
32		return &next;
33	}
34
35	bool operator==(const Link &ref) {
36		return data == ref.data;
37	}
38};
39
40// Class used for testing custom User strategy
41class MyLink {
42public:
43	SinglyLinkedListLink<MyLink> mynext;
44	long data;
45
46	bool operator==(const MyLink &ref) {
47		return data == ref.data;
48	}
49};
50
51//! Tests the given list
52template <class List, class Element>
53void
54SinglyLinkedListTest::TestList(List &list, Element *values, int valueCount)
55{
56	list.MakeEmpty();
57
58	// PushFront
59	for (int i = 0; i < valueCount; i++) {
60		NextSubTest();
61		CHK(list.Size() == i);
62		list.Add(&values[i]);
63		CHK(list.Size() == i+1);
64	}
65
66	// Prefix increment
67	int preIndex = valueCount-1;
68	for (typename List::Iterator iterator = list.GetIterator();
69			iterator.HasNext(); --preIndex) {
70		NextSubTest();
71
72 		Element* element = iterator.Next();
73		CHK(*element == values[preIndex]);
74	}
75	CHK(preIndex == -1);
76	list.MakeEmpty();
77}
78
79//! Test using the User strategy with the default NextMember.
80void
81SinglyLinkedListTest::UserDefaultTest() {
82	SinglyLinkedList<Link> list;
83	const int valueCount = 10;
84	Link values[valueCount];
85	for (int i = 0; i < valueCount; i++) {
86		values[i].data = i;
87		if (i % 2)
88			values[i].next.next = NULL;	// Leave some next pointers invalid just for fun
89	}
90
91	TestList(list, values, valueCount);
92}
93
94//! Test using the User strategy with a custom NextMember.
95void
96SinglyLinkedListTest::UserCustomTest() {
97	SinglyLinkedList<MyLink, SinglyLinkedListMemberGetLink<MyLink, &MyLink::mynext> > list;
98	const int valueCount = 10;
99	MyLink values[valueCount];
100	for (int i = 0; i < valueCount; i++) {
101		values[i].data = i*2;
102		if (!(i % 2))
103			values[i].mynext.next = NULL;	// Leave some next pointers invalid just for fun
104	}
105
106	TestList(list, values, valueCount);
107}
108