1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef TEST_H
6#define TEST_H
7
8
9#include "TestContext.h"
10
11
12class TestSuite;
13class TestVisitor;
14
15
16class Test {
17public:
18								Test(const char* name);
19	virtual						~Test();
20
21			const char*			Name() const	{ return fName; }
22
23			TestSuite*			Suite() const	{ return fSuite; }
24			void				SetSuite(TestSuite* suite);
25
26	virtual	bool				IsLeafTest() const;
27	virtual	status_t			Setup(TestContext& context);
28	virtual	bool				Run(TestContext& context) = 0;
29	virtual	bool				Run(TestContext& context, const char* name);
30	virtual	void				Cleanup(TestContext& context, bool setupOK);
31
32	virtual	Test*				Visit(TestVisitor& visitor);
33
34private:
35			const char*			fName;
36			TestSuite*			fSuite;
37};
38
39
40class StandardTestDelegate {
41public:
42								StandardTestDelegate();
43	virtual						~StandardTestDelegate();
44
45	virtual	status_t			Setup(TestContext& context);
46	virtual	void				Cleanup(TestContext& context, bool setupOK);
47};
48
49
50template<typename TestClass>
51class StandardTest : public Test {
52public:
53								StandardTest(const char* name,
54									TestClass* object,
55									bool (TestClass::*method)(TestContext&));
56	virtual						~StandardTest();
57
58	virtual	status_t			Setup(TestContext& context);
59	virtual	bool				Run(TestContext& context);
60	virtual	void				Cleanup(TestContext& context, bool setupOK);
61
62private:
63			TestClass*			fObject;
64			bool				(TestClass::*fMethod)(TestContext&);
65};
66
67
68template<typename TestClass>
69StandardTest<TestClass>::StandardTest(const char* name, TestClass* object,
70	bool (TestClass::*method)(TestContext&))
71	:
72	Test(name),
73	fObject(object),
74	fMethod(method)
75{
76}
77
78
79template<typename TestClass>
80StandardTest<TestClass>::~StandardTest()
81{
82	delete fObject;
83}
84
85
86template<typename TestClass>
87status_t
88StandardTest<TestClass>::Setup(TestContext& context)
89{
90	return fObject->Setup(context);
91}
92
93
94template<typename TestClass>
95bool
96StandardTest<TestClass>::Run(TestContext& context)
97{
98	return (fObject->*fMethod)(context);
99}
100
101
102template<typename TestClass>
103void
104StandardTest<TestClass>::Cleanup(TestContext& context, bool setupOK)
105{
106	fObject->Cleanup(context, setupOK);
107}
108
109
110#define TEST_ASSERT(condition)											\
111	do {																\
112		if (!(condition)) {												\
113			TestContext::Current()->AssertFailed(__FILE__, __LINE__,	\
114				__PRETTY_FUNCTION__, #condition);						\
115			return false;												\
116		}																\
117	} while (false)
118
119#define TEST_ASSERT_PRINT(condition, format...)							\
120	do {																\
121		if (!(condition)) {												\
122			TestContext::Current()->AssertFailed(__FILE__, __LINE__,	\
123				__PRETTY_FUNCTION__, #condition, format);				\
124			return false;												\
125		}																\
126	} while (false)
127
128#define TEST_PROPAGATE(result)											\
129	do {																\
130		if (!(result))													\
131			return false;												\
132	} while (false)
133
134
135#endif	// TEST_H
136