xref: /haiku/headers/tools/cppunit/TestShell.h (revision 16d5c24e533eb14b7b8a99ee9f3ec9ba66335b1e)
1 #ifndef _beos_test_shell_h_
2 #define _beos_test_shell_h_
3 
4 #include <LockerSyncObject.h>
5 #include <cppunit/Exception.h>
6 #include <cppunit/Test.h>
7 #include <cppunit/TestListener.h>
8 #include <cppunit/TestResult.h>
9 #include <cppunit/TestResultCollector.h>
10 #include <image.h>
11 #include <TestSuite.h>
12 #include <map>
13 #include <set>
14 #include <string>
15 
16 class BDirectory;
17 class BLocker;
18 class BPath;
19 
20 class ElfSymbolPatchGroup;
21 
22 // Defines SuiteFunction to be a pointer to a function that
23 // takes no arguments and returns a pointer to a CppUnit::Test
24 typedef CppUnit::Test* (*SuiteFunction)(void);
25 
26 // This is just absurd to have to type...
27 typedef CppUnit::SynchronizedObject::SynchronizationObject SyncObject;
28 
29 /*!	\brief Executes a statement that is supposed to call debugger().
30 	An exception is thrown if the debugger is not invoked by the
31 	statement.
32 */
33 #define CPPUNIT_ASSERT_DEBUGGER(statement)					\
34 	BTestShell::GlobalShell()->ExpectDebuggerCall();		\
35 	statement;												\
36 	::CppUnit::Asserter::failIf(							\
37 		!BTestShell::GlobalShell()->WasDebuggerCalled(),	\
38 		(#statement),										\
39 		CPPUNIT_SOURCELINE() );
40 
41 
42 //! BeOS savvy command line interface for the CppUnit testing framework.
43 /*! This class provides a fully functional command-line testing interface
44 	built on top of the CppUnit testing library. You add named test suites
45 	via AddSuite(), and then call Run(), which does all the dirty work. The
46 	user can get a list of each test installed via AddSuite(), and optionally
47 	can opt to run only a specified set of them.
48 */
49 class CPPUNIT_API BTestShell {
50 public:
51 	BTestShell(const std::string &description = "", SyncObject *syncObject = 0);
52 	virtual ~BTestShell();
53 
54 	// This function is used to add the tests for a given kit (as contained
55 	// in a BTestSuite object) to the list of available tests. The shell assumes
56 	// ownership of the BTestSuite object. Each test in the kit is added to
57 	// the list of tests via a call to AddTest(string
58 	status_t AddSuite(BTestSuite *kit);
59 
60 	// This function is used to add test suites to the list of available
61 	// tests. A SuiteFunction is just a function that takes no parameters
62 	// and returns a pointer to a CppUnit::Test object. Return NULL at
63 	// your own risk :-). The name given is the name that will be presented
64 	// when the program is run with "--list" as an argument. Usually the
65 	// given suite would be a test suite for an entire class, but that's
66 	// not a requirement.
67 	void AddTest(const std::string &name, CppUnit::Test* test);
68 
69 	// This function loads all the test addons it finds in the given
70 	// directory, returning the number of tests actually loaded.
71 	int32 LoadSuitesFrom(BDirectory *libDir);
72 
73 	// This is the function you call after you've added all your test
74 	// suites with calls to AddSuite(). It runs the test, or displays
75 	// help, or lists installed tests, or whatever, depending on the
76 	// command-line arguments passed in.
77 	int Run(int argc, char *argv[]);
78 
79 	// Verbosity Level enumeration and accessor function
80 	enum VerbosityLevel { v0, v1, v2, v3, v4 };
81 	VerbosityLevel Verbosity() const;
82 
83 	// Returns true if verbosity is high enough that individual tests are
84 	// allowed to make noise.
85 	bool BeVerbose() const { return Verbosity() >= v2; };
86 
87 	static bool GlobalBeVerbose() { return (fGlobalShell ? fGlobalShell->BeVerbose() : true); };
88 
89 	// Returns a pointer to a global BTestShell object. This function is
90 	// something of a hack, used to give BTestCase and its subclasses
91 	// access to verbosity information. Don't rely on it if you don't
92 	// have to (and always make sure the pointer it returns isn't NULL
93 	// before you try to use it :-).
94 	static BTestShell* GlobalShell() { return fGlobalShell; };
95 
96 	// Sets the global BTestShell pointer. The BTestShell class does
97 	// not assume ownership of the object.
98 	static void SetGlobalShell(BTestShell *shell) { fGlobalShell = shell; };
99 
100 	const char* TestDir() const;
101 	static const char* GlobalTestDir() { return (fGlobalShell ? fGlobalShell->TestDir() : NULL); };
102 
103 	void ExpectDebuggerCall();
104 	bool WasDebuggerCalled();
105 
106 protected:
107 	typedef std::map<std::string, CppUnit::Test*> TestMap;
108 	typedef std::map<std::string, BTestSuite*> SuiteMap;
109 
110 	VerbosityLevel fVerbosityLevel;
111 	std::set<std::string> fTestsToRun;
112 	std::set<std::string> fSuitesToRun;
113 	TestMap fTests;
114 	SuiteMap fSuites;
115 	std::set<std::string> fLibDirs;
116 	CppUnit::TestResult fTestResults;
117 	CppUnit::TestResultCollector fResultsCollector;
118 	std::string fDescription;
119 	static BTestShell* fGlobalShell;
120 	static const char indent[];
121 	bool fListTestsAndExit;
122 	BPath *fTestDir;
123 	int32 fTLSDebuggerCall;
124 #ifndef NO_ELF_SYMBOL_PATCHING
125 	BLocker *fPatchGroupLocker;
126 	ElfSymbolPatchGroup *fPatchGroup;
127 	void (*fOldDebuggerHook)(const char*);
128 	image_id (*fOldLoadAddOnHook)(const char*);
129 	status_t (*fOldUnloadAddOnHook)(image_id);
130 #endif // ! NO_ELF_SYMBOL_PATCHING
131 
132 	//! Prints a brief description of the program.
133 	virtual void PrintDescription(int argc, char *argv[]);
134 
135 	//! Prints out command line argument instructions
136 	void PrintHelp();
137 
138 	/*! \brief Prints out the list of valid command line arguments.
139 		Called by PrintHelp().
140 	*/
141 	virtual void PrintValidArguments();
142 
143 	//! Prints out a list of all the currently available tests
144 	void PrintInstalledTests();
145 
146 	/*! \brief Handles command line arguments; returns true if everything goes
147 		okay, false if not (or if the program just needs to terminate without
148 		running any tests). Modifies settings in "settings" as necessary.
149 	*/
150 	bool ProcessArguments(int argc, char *argv[]);
151 
152 	//! Processes a single argument, given by the \c arg parameter.
153 	virtual bool ProcessArgument(std::string arg, int argc, char *argv[]);
154 
155 	//! Makes any necessary pre-test preparations
156 	void InitOutput();
157 
158 	/*! \brief Prints out the test results in the proper format per
159 		the specified verbosity level.
160 	*/
161 	void PrintResults();
162 
163 	/*! \brief Searches all the paths in \c fLibDirs, loading any dynamically
164 		loadable suites it finds.
165 	*/
166 	virtual void LoadDynamicSuites();
167 
168 	//! Sets the current test directory.
169 	void UpdateTestDir(char *argv[]);
170 
171 	void InstallPatches();
172 	void UninstallPatches();
173 
174 private:
175 	//! Prevents the use of the copy constructor.
176 	BTestShell( const BTestShell &copy );
177 
178 	//! Prevents the use of the copy operator.
179 	void operator =( const BTestShell &copy );
180 
181 #ifndef NO_ELF_SYMBOL_PATCHING
182 	void _Debugger(const char* message);
183 	image_id _LoadAddOn(const char* path);
184 	status_t _UnloadAddOn(image_id image);
185 
186 	static void _DebuggerHook(const char* message);
187 	static image_id _LoadAddOnHook(const char* path);
188 	static status_t _UnloadAddOnHook(image_id image);
189 #endif	// ! NO_ELF_SYMBOL_PATCHING
190 
191 };	// class BTestShell
192 
193 #endif // _beos_test_shell_h_
194