1// StatableTest.h
2
3#ifndef __sk_statable_test_h__
4#define __sk_statable_test_h__
5
6#include <cppunit/TestCaller.h>
7#include <cppunit/TestSuite.h>
8
9#include <list>
10using std::list;
11
12#include "BasicTest.h"
13
14class BStatable;
15class BEntry;
16class BNode;
17
18// TestEntries
19
20template <typename C>
21struct TestEntries
22{
23	~TestEntries()
24	{
25		delete_all();
26	}
27
28	void delete_all()
29	{
30		for (typename list<C*>::iterator it = entries.begin();
31			 it != entries.end();
32			 it++) {
33			// Arghh, BStatable has no virtual destructor!
34			// Workaround: try to cast to one of the subclasses
35			if (BNode *node = dynamic_cast<BNode*>(*it))
36				delete node;
37			else if (BEntry *entry = dynamic_cast<BEntry*>(*it))
38				delete entry;
39			else
40				delete *it;
41		}
42		clear();
43	}
44
45	void clear()
46	{
47		entries.clear();
48		entryNames.clear();
49		rewind();
50	}
51
52	void add(C *entry, string entryName)
53	{
54		entries.push_back(entry);
55		entryNames.push_back(entryName);
56	}
57
58	bool getNext(C *&entry, string &entryName)
59	{
60		bool result = (entryIt != entries.end()
61					   && entryNameIt != entryNames.end());
62		if (result) {
63			entry = *entryIt;
64			entryName = *entryNameIt;
65			entryIt++;
66			entryNameIt++;
67		}
68		return result;
69	}
70
71	void rewind()
72	{
73		entryIt = entries.begin();
74		entryNameIt = entryNames.begin();
75	}
76
77	list<C*>						entries;
78	list<string>					entryNames;
79	typename list<C*>::iterator		entryIt;
80	typename list<string>::iterator	entryNameIt;
81};
82
83typedef TestEntries<BStatable> TestStatables;
84
85
86// StatableTest
87
88class StatableTest : public BasicTest
89{
90public:
91	template<typename DerivedClass>
92	static inline void AddBaseClassTests(const char *prefix,
93										 CppUnit::TestSuite *suite);
94
95	virtual void CreateROStatables(TestStatables& testEntries) = 0;
96	virtual void CreateRWStatables(TestStatables& testEntries) = 0;
97	virtual void CreateUninitializedStatables(TestStatables& testEntries) = 0;
98
99	// This function called before *each* test added in Suite()
100	void setUp();
101
102	// This function called after *each* test added in Suite()
103	void tearDown();
104
105	void GetStatTest();
106	void IsXYZTest();
107	void GetXYZTest();
108	void SetXYZTest();
109};
110
111// AddBaseClassTests
112template<typename DerivedClass>
113inline void
114StatableTest::AddBaseClassTests(const char *prefix, CppUnit::TestSuite *suite)
115{
116	typedef CppUnit::TestCaller<DerivedClass> TC;
117	string p(prefix);
118
119	suite->addTest( new TC(p + "BStatable::GetStat Test",
120						   &StatableTest::GetStatTest) );
121	suite->addTest( new TC(p + "BStatable::IsXYZ Test",
122						   &StatableTest::IsXYZTest) );
123	suite->addTest( new TC(p + "BStatable::GetXYZ Test",
124						   &StatableTest::GetXYZTest) );
125	suite->addTest( new TC(p + "BStatable::SetXYZ Test",
126						   &StatableTest::SetXYZTest) );
127}
128
129#endif	// __sk_statable_test_h__
130