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 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(std::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 BLocker *fPatchGroupLocker; 124 int32 fTLSDebuggerCall; 125 ElfSymbolPatchGroup *fPatchGroup; 126 void (*fOldDebuggerHook)(const char*); 127 image_id (*fOldLoadAddOnHook)(const char*); 128 status_t (*fOldUnloadAddOnHook)(image_id); 129 130 131 //! Prints a brief description of the program. 132 virtual void PrintDescription(int argc, char *argv[]); 133 134 //! Prints out command line argument instructions 135 void PrintHelp(); 136 137 /*! \brief Prints out the list of valid command line arguments. 138 Called by PrintHelp(). 139 */ 140 virtual void PrintValidArguments(); 141 142 //! Prints out a list of all the currently available tests 143 void PrintInstalledTests(); 144 145 /*! \brief Handles command line arguments; returns true if everything goes 146 okay, false if not (or if the program just needs to terminate without 147 running any tests). Modifies settings in "settings" as necessary. 148 */ 149 bool ProcessArguments(int argc, char *argv[]); 150 151 //! Processes a single argument, given by the \c arg parameter. 152 virtual bool ProcessArgument(std::string arg, int argc, char *argv[]); 153 154 //! Makes any necessary pre-test preparations 155 void InitOutput(); 156 157 /*! \brief Prints out the test results in the proper format per 158 the specified verbosity level. 159 */ 160 void PrintResults(); 161 162 /*! \brief Searches all the paths in \c fLibDirs, loading any dynamically 163 loadable suites it finds. 164 */ 165 virtual void LoadDynamicSuites(); 166 167 //! Sets the current test directory. 168 void UpdateTestDir(char *argv[]); 169 170 void InstallPatches(); 171 void UninstallPatches(); 172 173 private: 174 //! Prevents the use of the copy constructor. 175 BTestShell( const BTestShell © ); 176 177 //! Prevents the use of the copy operator. 178 void operator =( const BTestShell © ); 179 180 void _Debugger(const char* message); 181 image_id _LoadAddOn(const char* path); 182 status_t _UnloadAddOn(image_id image); 183 184 static void _DebuggerHook(const char* message); 185 static image_id _LoadAddOnHook(const char* path); 186 static status_t _UnloadAddOnHook(image_id image); 187 188 }; // class BTestShell 189 190 #endif // _beos_test_shell_h_ 191