1#ifndef _XETESTCASE_HPP
2#define _XETESTCASE_HPP
3/*-------------------------------------------------------------------------
4 * drawElements Quality Program Test Executor
5 * ------------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Test case.
24 *//*--------------------------------------------------------------------*/
25
26#include "xeDefs.hpp"
27
28#include <string>
29#include <vector>
30#include <set>
31#include <map>
32
33namespace xe
34{
35
36enum TestCaseType
37{
38	TESTCASETYPE_SELF_VALIDATE,
39	TESTCASETYPE_CAPABILITY,
40	TESTCASETYPE_ACCURACY,
41	TESTCASETYPE_PERFORMANCE,
42
43	TESTCASETYPE_LAST
44};
45
46const char* getTestCaseTypeName (TestCaseType caseType);
47
48enum TestNodeType
49{
50	TESTNODETYPE_ROOT,
51	TESTNODETYPE_GROUP,
52	TESTNODETYPE_TEST_CASE,
53
54	TESTNODETYPE_LAST
55};
56
57class TestGroup;
58class TestCase;
59
60class TestNode
61{
62public:
63	virtual				~TestNode			(void) {}
64
65	TestNodeType		getNodeType			(void) const { return m_nodeType;		}
66	const char*			getName				(void) const { return m_name.c_str();	}
67	const TestGroup*	getParent			(void) const { return m_parent;			}
68
69	void				getFullPath			(std::string& path) const;
70	std::string			getFullPath			(void) const { std::string str; getFullPath(str); return str; }
71
72	const TestNode*		find				(const char* path) const;
73	TestNode*			find				(const char* path);
74
75protected:
76						TestNode			(TestGroup* parent, TestNodeType nodeType, const char* name, const char* desc);
77
78private:
79						TestNode			(const TestNode& other);
80	TestNode&			operator=			(const TestNode& other);
81
82	TestGroup*			m_parent;
83	TestNodeType		m_nodeType;
84	std::string			m_name;
85	std::string			m_description;
86};
87
88class TestGroup : public TestNode
89{
90public:
91								~TestGroup			(void);
92
93	int							getNumChildren		(void) const	{ return (int)m_children.size();	}
94	TestNode*					getChild			(int ndx)		{ return m_children[ndx];			}
95	const TestNode*				getChild			(int ndx) const	{ return m_children[ndx];			}
96
97	TestNode*					findChildNode		(const char* path);
98	const TestNode*				findChildNode		(const char* path) const;
99
100	TestGroup*					createGroup			(const char* name, const char* description);
101	TestCase*					createCase			(TestCaseType caseType, const char* name, const char* description);
102
103protected:
104								TestGroup			(TestGroup* parent, TestNodeType nodeType, const char* name, const char* description);
105
106private:
107	std::vector<TestNode*>		m_children;
108	std::set<std::string>		m_childNames;		//!< Used for checking for duplicate test case names.
109
110	// For adding TestCase to m_children. \todo [2012-06-15 pyry] Is the API broken perhaps?
111	friend class TestNode;
112};
113
114class TestRoot : public TestGroup
115{
116public:
117								TestRoot			(void);
118};
119
120class TestCase : public TestNode
121{
122public:
123								~TestCase			(void);
124
125	TestCaseType				getCaseType			(void) const { return m_caseType; }
126
127	static TestCase*			createAsChild		(TestGroup* parent, TestCaseType caseType, const char* name, const char* description);
128
129protected:
130								TestCase			(TestGroup* parent, TestCaseType caseType, const char* name, const char* description);
131
132private:
133	TestCaseType				m_caseType;
134};
135
136// Helper class for efficiently constructing TestCase hierarchy from test case list.
137class TestHierarchyBuilder
138{
139public:
140										TestHierarchyBuilder		(TestRoot* root);
141										~TestHierarchyBuilder		(void);
142
143	TestCase*							createCase					(const char* path, TestCaseType caseType);
144
145private:
146										TestHierarchyBuilder		(const TestHierarchyBuilder& other);
147	TestHierarchyBuilder&				operator=					(const TestHierarchyBuilder& other);
148
149	TestRoot*							m_root;
150	std::map<std::string, TestGroup*>	m_groupMap;
151};
152
153// Helper class for computing and iterating test sets.
154class TestSet
155{
156public:
157							TestSet			(void) {}
158							~TestSet		(void) {}
159
160	bool					empty			(void) const { return m_set.empty(); }
161
162	void					add				(const TestNode* node);
163	void					addCase			(const TestCase* testCase);
164	void					addGroup		(const TestGroup* testGroup);
165
166	void					remove			(const TestNode* node);
167	void					removeCase		(const TestCase* testCase);
168	void					removeGroup		(const TestGroup* testGroup);
169
170	bool					hasNode			(const TestNode* node) const { return m_set.find(node) != m_set.end(); }
171
172private:
173	std::set<const TestNode*> m_set;
174};
175
176class ConstTestNodeIterator
177{
178public:
179	static ConstTestNodeIterator	begin					(const TestNode* root);
180	static ConstTestNodeIterator	end						(const TestNode* root);
181
182	ConstTestNodeIterator&			operator++				(void);
183	ConstTestNodeIterator			operator++				(int);
184
185	const TestNode*					operator*				(void) const;
186
187	bool							operator!=				(const ConstTestNodeIterator& other) const;
188
189protected:
190									ConstTestNodeIterator	(const TestNode* root);
191
192private:
193	struct GroupState
194	{
195		GroupState (const TestGroup* group_) : group(group_), childNdx(0) {}
196
197		const TestGroup*	group;
198		int					childNdx;
199
200		bool operator!= (const GroupState& other) const
201		{
202			return group != other.group || childNdx != other.childNdx;
203		}
204
205		bool operator== (const GroupState& other) const
206		{
207			return group == other.group && childNdx == other.childNdx;
208		}
209	};
210
211	const TestNode*					m_root;
212	std::vector<GroupState>			m_iterStack;
213};
214
215// \todo [2012-06-19 pyry] Implement following iterators:
216//  - TestNodeIterator
217//  - ConstTestSetIterator
218//  - TestSetIterator
219
220} // xe
221
222#endif // _XETESTCASE_HPP
223