xref: /haiku/headers/tools/cppunit/TestShell.h (revision 529cd177b573aaba391c8adc9c9f5ad76a14bf81)
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. The test pointer may not be NULL. The name given is the name that
62 	// will be presented when the program is run with "--list" as an argument.
63 	// Usually the given suite would be a test suite for an entire class, but
64 	// that's not a requirement.
65 	void AddTest(const std::string &name, CppUnit::Test* test);
66 
67 	// This function loads all the test addons it finds in the given
68 	// directory, returning the number of tests actually loaded.
69 	int32 LoadSuitesFrom(BDirectory *libDir);
70 
71 	// This is the function you call after you've added all your test
72 	// suites with calls to AddSuite(). It runs the test, or displays
73 	// help, or lists installed tests, or whatever, depending on the
74 	// command-line arguments passed in.
75 	int Run(int argc, char *argv[]);
76 
77 	// Verbosity Level enumeration and accessor function
78 	enum VerbosityLevel { v0, v1, v2, v3, v4 };
79 	VerbosityLevel Verbosity() const;
80 
81 	// Returns true if verbosity is high enough that individual tests are
82 	// allowed to make noise.
83 	bool BeVerbose() const { return Verbosity() >= v2; };
84 
85 	static bool GlobalBeVerbose() { return (fGlobalShell ? fGlobalShell->BeVerbose() : true); };
86 
87 	// Returns a pointer to a global BTestShell object. This function is
88 	// something of a hack, used to give BTestCase and its subclasses
89 	// access to verbosity information. Don't rely on it if you don't
90 	// have to (and always make sure the pointer it returns isn't NULL
91 	// before you try to use it :-).
92 	static BTestShell* GlobalShell() { return fGlobalShell; };
93 
94 	// Sets the global BTestShell pointer. The BTestShell class does
95 	// not assume ownership of the object.
96 	static void SetGlobalShell(BTestShell *shell) { fGlobalShell = shell; };
97 
98 	const char* TestDir() const;
99 	static const char* GlobalTestDir() { return (fGlobalShell ? fGlobalShell->TestDir() : NULL); };
100 
101 	void ExpectDebuggerCall();
102 	bool WasDebuggerCalled();
103 
104 protected:
105 	typedef std::map<std::string, CppUnit::Test*> TestMap;
106 	typedef std::map<std::string, BTestSuite*> SuiteMap;
107 
108 	VerbosityLevel fVerbosityLevel;
109 	std::set<std::string> fTestsToRun;
110 	std::set<std::string> fSuitesToRun;
111 	TestMap fTests;
112 	SuiteMap fSuites;
113 	std::set<std::string> fLibDirs;
114 	CppUnit::TestResult fTestResults;
115 	CppUnit::TestResultCollector fResultsCollector;
116 	std::string fDescription;
117 	static BTestShell* fGlobalShell;
118 	static const char indent[];
119 	bool fListTestsAndExit;
120 	BPath *fTestDir;
121 	int32 fTLSDebuggerCall;
122 
123 	BLocker *fPatchGroupLocker;
124 	ElfSymbolPatchGroup *fPatchGroup;
125 	void (*fOldDebuggerHook)(const char*);
126 	image_id (*fOldLoadAddOnHook)(const char*);
127 	status_t (*fOldUnloadAddOnHook)(image_id);
128 
129 	//! Prints a brief description of the program.
130 	virtual void PrintDescription(int argc, char *argv[]);
131 
132 	//! Prints out command line argument instructions
133 	void PrintHelp();
134 
135 	/*! \brief Prints out the list of valid command line arguments.
136 		Called by PrintHelp().
137 	*/
138 	virtual void PrintValidArguments();
139 
140 	//! Prints out a list of all the currently available tests
141 	void PrintInstalledTests();
142 
143 	/*! \brief Handles command line arguments; returns true if everything goes
144 		okay, false if not (or if the program just needs to terminate without
145 		running any tests). Modifies settings in "settings" as necessary.
146 	*/
147 	bool ProcessArguments(int argc, char *argv[]);
148 
149 	//! Processes a single argument, given by the \c arg parameter.
150 	virtual bool ProcessArgument(std::string arg, int argc, char *argv[]);
151 
152 	//! Makes any necessary pre-test preparations
153 	void InitOutput();
154 
155 	/*! \brief Prints out the test results in the proper format per
156 		the specified verbosity level.
157 	*/
158 	void PrintResults();
159 
160 	/*! \brief Searches all the paths in \c fLibDirs, loading any dynamically
161 		loadable suites it finds.
162 	*/
163 	virtual void LoadDynamicSuites();
164 
165 	//! Sets the current test directory.
166 	void UpdateTestDir(char *argv[]);
167 
168 	void InstallPatches();
169 	void UninstallPatches();
170 
171 private:
172 	//! Prevents the use of the copy constructor.
173 	BTestShell( const BTestShell &copy );
174 
175 	//! Prevents the use of the copy operator.
176 	void operator =( const BTestShell &copy );
177 
178 	void _Debugger(const char* message);
179 	image_id _LoadAddOn(const char* path);
180 	status_t _UnloadAddOn(image_id image);
181 
182 	static void _DebuggerHook(const char* message);
183 	static image_id _LoadAddOnHook(const char* path);
184 	static status_t _UnloadAddOnHook(image_id image);
185 };	// class BTestShell
186 
187 #endif // _beos_test_shell_h_
188