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 
33 namespace xe
34 {
35 
36 enum TestCaseType
37 {
38 	TESTCASETYPE_SELF_VALIDATE,
39 	TESTCASETYPE_CAPABILITY,
40 	TESTCASETYPE_ACCURACY,
41 	TESTCASETYPE_PERFORMANCE,
42 
43 	TESTCASETYPE_LAST
44 };
45 
46 const char* getTestCaseTypeName (TestCaseType caseType);
47 
48 enum TestNodeType
49 {
50 	TESTNODETYPE_ROOT,
51 	TESTNODETYPE_GROUP,
52 	TESTNODETYPE_TEST_CASE,
53 
54 	TESTNODETYPE_LAST
55 };
56 
57 class TestGroup;
58 class TestCase;
59 
60 class TestNode
61 {
62 public:
~TestNode(void)63 	virtual				~TestNode			(void) {}
64 
getNodeType(void) const65 	TestNodeType		getNodeType			(void) const { return m_nodeType;		}
getName(void) const66 	const char*			getName				(void) const { return m_name.c_str();	}
getParent(void) const67 	const TestGroup*	getParent			(void) const { return m_parent;			}
68 
69 	void				getFullPath			(std::string& path) const;
getFullPath(void) const70 	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 
75 protected:
76 						TestNode			(TestGroup* parent, TestNodeType nodeType, const char* name, const char* desc);
77 
78 private:
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 
88 class TestGroup : public TestNode
89 {
90 public:
91 								~TestGroup			(void);
92 
getNumChildren(void) const93 	int							getNumChildren		(void) const	{ return (int)m_children.size();	}
getChild(int ndx)94 	TestNode*					getChild			(int ndx)		{ return m_children[ndx];			}
getChild(int ndx) const95 	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 
103 protected:
104 								TestGroup			(TestGroup* parent, TestNodeType nodeType, const char* name, const char* description);
105 
106 private:
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 
114 class TestRoot : public TestGroup
115 {
116 public:
117 								TestRoot			(void);
118 };
119 
120 class TestCase : public TestNode
121 {
122 public:
123 								~TestCase			(void);
124 
getCaseType(void) const125 	TestCaseType				getCaseType			(void) const { return m_caseType; }
126 
127 	static TestCase*			createAsChild		(TestGroup* parent, TestCaseType caseType, const char* name, const char* description);
128 
129 protected:
130 								TestCase			(TestGroup* parent, TestCaseType caseType, const char* name, const char* description);
131 
132 private:
133 	TestCaseType				m_caseType;
134 };
135 
136 // Helper class for efficiently constructing TestCase hierarchy from test case list.
137 class TestHierarchyBuilder
138 {
139 public:
140 										TestHierarchyBuilder		(TestRoot* root);
141 										~TestHierarchyBuilder		(void);
142 
143 	TestCase*							createCase					(const char* path, TestCaseType caseType);
144 
145 private:
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.
154 class TestSet
155 {
156 public:
TestSet(void)157 							TestSet			(void) {}
~TestSet(void)158 							~TestSet		(void) {}
159 
empty(void) const160 	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 
hasNode(const TestNode * node) const170 	bool					hasNode			(const TestNode* node) const { return m_set.find(node) != m_set.end(); }
171 
172 private:
173 	std::set<const TestNode*> m_set;
174 };
175 
176 class ConstTestNodeIterator
177 {
178 public:
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 
189 protected:
190 									ConstTestNodeIterator	(const TestNode* root);
191 
192 private:
193 	struct GroupState
194 	{
GroupStatexe::ConstTestNodeIterator::GroupState195 		GroupState (const TestGroup* group_) : group(group_), childNdx(0) {}
196 
197 		const TestGroup*	group;
198 		int					childNdx;
199 
operator !=xe::ConstTestNodeIterator::GroupState200 		bool operator!= (const GroupState& other) const
201 		{
202 			return group != other.group || childNdx != other.childNdx;
203 		}
204 
operator ==xe::ConstTestNodeIterator::GroupState205 		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