#ifndef _beos_test_shell_h_
#define _beos_test_shell_h_
#include <LockerSyncObject.h>
#include <cppunit/Exception.h>
#include <cppunit/Test.h>
#include <cppunit/TestListener.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <image.h>
#include <TestSuite.h>
#include <map>
#include <set>
#include <string>
class BDirectory;
class BLocker;
class BPath;
#ifndef NO_ELF_SYMBOL_PATCHING
#include <tools/elfsymbolpatcher/ElfSymbolPatcher.h>
#else
class ElfSymbolPatchGroup;
#endif
typedef CppUnit::Test* (*SuiteFunction)(void);
typedef CppUnit::SynchronizedObject::SynchronizationObject SyncObject;
An exception is thrown if the debugger is not invoked by the
statement.
*/
#define CPPUNIT_ASSERT_DEBUGGER(statement) \
BTestShell::GlobalShell()->ExpectDebuggerCall(); \
statement; \
::CppUnit::Asserter::failIf( \
!BTestShell::GlobalShell()->WasDebuggerCalled(), \
(#statement), \
CPPUNIT_SOURCELINE() );
built on top of the CppUnit testing library. You add named test suites
via AddSuite(), and then call Run(), which does all the dirty work. The
user can get a list of each test installed via AddSuite(), and optionally
can opt to run only a specified set of them.
*/
class CPPUNIT_API BTestShell {
public:
BTestShell(const std::string &description = "", SyncObject *syncObject = 0);
virtual ~BTestShell();
status_t AddSuite(BTestSuite *kit);
void AddTest(const std::string &name, CppUnit::Test* test);
int32 LoadSuitesFrom(BDirectory *libDir);
int Run(int argc, char *argv[]);
enum VerbosityLevel { v0, v1, v2, v3, v4 };
VerbosityLevel Verbosity() const;
bool BeVerbose() const { return Verbosity() >= v2; };
static bool GlobalBeVerbose() { return (fGlobalShell ? fGlobalShell->BeVerbose() : true); };
static BTestShell* GlobalShell() { return fGlobalShell; };
static void SetGlobalShell(BTestShell *shell) { fGlobalShell = shell; };
const char* TestDir() const;
static const char* GlobalTestDir() { return (fGlobalShell ? fGlobalShell->TestDir() : NULL); };
void ExpectDebuggerCall();
bool WasDebuggerCalled();
protected:
typedef std::map<std::string, CppUnit::Test*> TestMap;
typedef std::map<std::string, BTestSuite*> SuiteMap;
VerbosityLevel fVerbosityLevel;
std::set<std::string> fTestsToRun;
std::set<std::string> fSuitesToRun;
TestMap fTests;
SuiteMap fSuites;
std::set<std::string> fLibDirs;
CppUnit::TestResult fTestResults;
CppUnit::TestResultCollector fResultsCollector;
std::string fDescription;
static BTestShell* fGlobalShell;
static const char indent[];
bool fListTestsAndExit;
BPath *fTestDir;
int32 fTLSDebuggerCall;
BLocker *fPatchGroupLocker;
ElfSymbolPatchGroup *fPatchGroup;
void (*fOldDebuggerHook)(const char*);
image_id (*fOldLoadAddOnHook)(const char*);
status_t (*fOldUnloadAddOnHook)(image_id);
virtual void PrintDescription(int argc, char *argv[]);
void PrintHelp();
Called by PrintHelp().
*/
virtual void PrintValidArguments();
void PrintInstalledTests();
okay, false if not (or if the program just needs to terminate without
running any tests). Modifies settings in "settings" as necessary.
*/
bool ProcessArguments(int argc, char *argv[]);
virtual bool ProcessArgument(std::string arg, int argc, char *argv[]);
void InitOutput();
the specified verbosity level.
*/
void PrintResults();
loadable suites it finds.
*/
virtual void LoadDynamicSuites();
void UpdateTestDir(char *argv[]);
void InstallPatches();
void UninstallPatches();
private:
BTestShell( const BTestShell © );
void operator =( const BTestShell © );
void _Debugger(const char* message);
image_id _LoadAddOn(const char* path);
status_t _UnloadAddOn(image_id image);
static void _DebuggerHook(const char* message);
static image_id _LoadAddOnHook(const char* path);
static status_t _UnloadAddOnHook(image_id image);
};
#endif