diff options
| author | Bastiaan Bakker <bastiaan.bakker@lifeline.nl> | 2001-04-14 21:37:31 +0000 |
|---|---|---|
| committer | Bastiaan Bakker <bastiaan.bakker@lifeline.nl> | 2001-04-14 21:37:31 +0000 |
| commit | fb5695f7ca74f6557bdff1ceff009628ac3adc4a (patch) | |
| tree | 8e6c05a5db8ef1c3037a10f579c31f0eb38a087e /include/cppunit | |
| parent | f5f2b1d2761b1d81c042d51619182c7951fd23aa (diff) | |
| download | cppunit-fb5695f7ca74f6557bdff1ceff009628ac3adc4a.tar.gz | |
Moved public header files from cppunit dir to include/cppunit, to separate them from internal header files like estring.h.
Diffstat (limited to 'include/cppunit')
| -rw-r--r-- | include/cppunit/Exception.h | 45 | ||||
| -rw-r--r-- | include/cppunit/Makefile.am | 11 | ||||
| -rw-r--r-- | include/cppunit/Test.h | 32 | ||||
| -rw-r--r-- | include/cppunit/TestCaller.h | 92 | ||||
| -rw-r--r-- | include/cppunit/TestCase.h | 175 | ||||
| -rw-r--r-- | include/cppunit/TestFailure.h | 57 | ||||
| -rw-r--r-- | include/cppunit/TestRegistry.h | 40 | ||||
| -rw-r--r-- | include/cppunit/TestResult.h | 99 | ||||
| -rw-r--r-- | include/cppunit/TestSuite.h | 58 | ||||
| -rw-r--r-- | include/cppunit/TextTestResult.h | 32 |
10 files changed, 641 insertions, 0 deletions
diff --git a/include/cppunit/Exception.h b/include/cppunit/Exception.h new file mode 100644 index 0000000..eb43119 --- /dev/null +++ b/include/cppunit/Exception.h @@ -0,0 +1,45 @@ +#ifndef CPPUNIT_EXCEPTION_H +#define CPPUNIT_EXCEPTION_H + +#include <exception> +#include <string> + +namespace CppUnit { + + /** + * Exception is an exception that serves + * descriptive strings through its what() method + * + */ + + class Exception : public exception + { + public: + Exception (std::string message = "", + long lineNumber = UNKNOWNLINENUMBER, + std::string fileName = UNKNOWNFILENAME); + Exception (const Exception& other); + + virtual ~Exception (); + + Exception& operator= (const Exception& other); + + const char *what() const throw (); + + long lineNumber (); + std::string fileName (); + + static const std::string UNKNOWNFILENAME; + static const int UNKNOWNLINENUMBER; + + private: + std::string m_message; + long m_lineNumber; + std::string m_fileName; + + }; + +} // namespace CppUnit + +#endif // CPPUNIT_EXCEPTION_H + diff --git a/include/cppunit/Makefile.am b/include/cppunit/Makefile.am new file mode 100644 index 0000000..c837438 --- /dev/null +++ b/include/cppunit/Makefile.am @@ -0,0 +1,11 @@ +libcppunitincludedir = $(includedir)/cppunit +libcppunitinclude_HEADERS = \ + Exception.h \ + Test.h \ + TestCaller.h \ + TestCase.h \ + TestFailure.h \ + TestResult.h \ + TestRegistry.h \ + TestSuite.h \ + TextTestResult.h diff --git a/include/cppunit/Test.h b/include/cppunit/Test.h new file mode 100644 index 0000000..421e403 --- /dev/null +++ b/include/cppunit/Test.h @@ -0,0 +1,32 @@ +#ifndef CPPUNIT_TEST_H +#define CPPUNIT_TEST_H + +#include <string> + +namespace CppUnit { + + class TestResult; + + /** + * A Test can be run and collect its results. + * \see TestResult. + * + */ + class Test + { + public: + virtual ~Test () {}; + + virtual void run (TestResult *result) = 0; + virtual int countTestCases () const = 0; + virtual std::string toString () const = 0; + virtual std::string getName () const = 0; + + + }; + + +} // namespace CppUnit + +#endif // CPPUNIT_TEST_H + diff --git a/include/cppunit/TestCaller.h b/include/cppunit/TestCaller.h new file mode 100644 index 0000000..8c3f1b5 --- /dev/null +++ b/include/cppunit/TestCaller.h @@ -0,0 +1,92 @@ +#ifndef CPPUNIT_TESTCALLER_H +#define CPPUNIT_TESTCALLER_H + +#ifndef CPPUNIT_TESTCASE_H +#include "TestCase.h" +#endif + +#include <stl.h> + +namespace CppUnit { + + /** Provides access to a test case method. + * A test caller provides access to a test case method + * on a test case class. Test callers are useful when + * you want to run an individual test or add it to a + * suite. + * Test Callers invoke only one Test (i.e. test method) on one + * Fixture of a TestCase. + * + * Here is an example: + * \code + * class MathTest : public CppUnit::TestCase { + * ... + * public: + * void setUp (); + * void tearDown (); + * + * void testAdd (); + * void testSubtract (); + * }; + * + * CppUnit::Test *MathTest::suite () { + * CppUnit::TestSuite *suite = new CppUnit::TestSuite; + * + * suite->addTest (new CppUnit::TestCaller<MathTest> ("testAdd", testAdd)); + * return suite; + * } + * \endcode + * + * You can use a TestCaller to bind any test method on a TestCase + * class, as long as it accepts void and returns void. + * TestCallers are automatically registered in the TestRegistry. + * + * \see TestCase + */ + + template <class Fixture> + class TestCaller : public TestCase + { + typedef void (Fixture::*TestMethod)(); + + public: + TestCaller (std::string name, TestMethod test) : + TestCase (name), + m_fixture (new Fixture ()), + m_test (test) + {} + + protected: + void runTest () + { + (m_fixture.get ()->*m_test)(); + } + + void setUp () + { + m_fixture.get ()->setUp (); + } + + void tearDown () + { + m_fixture.get ()->tearDown (); + } + + std::string toString () const + { + return "TestCaller " + getName(); + } + + private: + TestCaller (const TestCaller& other); + TestCaller& operator= (const TestCaller& other); + + private: + std::auto_ptr<Fixture> m_fixture; + TestMethod m_test; + + }; + +} // namespace CppUnit + +#endif // CPPUNIT_TESTCALLER_H diff --git a/include/cppunit/TestCase.h b/include/cppunit/TestCase.h new file mode 100644 index 0000000..056159d --- /dev/null +++ b/include/cppunit/TestCase.h @@ -0,0 +1,175 @@ +#ifndef CPPUNIT_TESTCASE_H +#define CPPUNIT_TESTCASE_H + +#include <string> + +#ifndef CPPUNIT_TEST_H +#include "Test.h" +#endif + +#ifndef CPPUNIT_EXCEPTION_H +#include "Exception.h" +#endif + +namespace CppUnit { + + class TestResult; + + /** + * A test case defines the fixture to run multiple tests. + * To define a test case + * do the following: + * - implement a subclass of TestCase + * - the fixture is defined by instance variables + * - initialize the fixture state by overriding setUp + * (i.e. construct the instance variables of the fixture) + * - clean-up after a test by overriding tearDown. + * + * Each test runs in its own fixture so there + * can be no side effects among test runs. + * Here is an example: + * + * \code + * class MathTest : public TestCase { + * protected: int m_value1; + * protected: int m_value2; + * + * public: MathTest (string name) + * : TestCase (name) { + * } + * + * protected: void setUp () { + * m_value1 = 2; + * m_value2 = 3; + * } + * } + * \endcode + * + * For each test implement a method which interacts + * with the fixture. Verify the expected results with assertions specified + * by calling assert on the expression you want to test: + * + * \code + * protected: void testAdd () { + * int result = value1 + value2; + * assert (result == 5); + * } + * \endcode + * + * Once the methods are defined you can run them. To do this, use + * a TestCaller. + * + * \code + * Test *test = new TestCaller<MathTest>("testAdd", MathTest::testAdd); + * test->run (); + * \endcode + * + * + * The tests to be run can be collected into a TestSuite. + * + * \code + * public: static TestSuite *MathTest::suite () { + * TestSuite *suiteOfTests = new TestSuite; + * suiteOfTests->addTest(new TestCaller<MathTest>( + * "testAdd", testAdd)); + * suiteOfTests->addTest(new TestCaller<MathTest>( + * "testDivideByZero", testDivideByZero)); + * return suiteOfTests; + * } + * \endcode + * + * + * \see TestResult + * \see TestSuite + * \see TestCaller + * + */ + + class TestCase : public Test + { + public: + TestCase (); + TestCase (std::string Name); + ~TestCase (); + + virtual void run (TestResult *result); + virtual TestResult *run (); + virtual int countTestCases () const; + std::string getName () const; + std::string toString () const; + + virtual void setUp (); + virtual void tearDown (); + + protected: + virtual void runTest (); + + TestResult *defaultResult (); + void assertImplementation( + bool condition, + std::string conditionExpression = "", + long lineNumber = Exception::UNKNOWNLINENUMBER, + std::string fileName = Exception::UNKNOWNFILENAME); + + void assertEquals (long expected, + long actual, + long lineNumber = Exception::UNKNOWNLINENUMBER, + std::string fileName = Exception::UNKNOWNFILENAME); + + void assertEquals (double expected, + double actual, + double delta, + long lineNumber = Exception::UNKNOWNLINENUMBER, + std::string fileName = Exception::UNKNOWNFILENAME); + + std::string notEqualsMessage (long expected, + long actual); + + std::string notEqualsMessage (double expected, + double actual); + + private: + TestCase (const TestCase& other); + TestCase& operator= (const TestCase& other); + + private: + const std::string m_name; + }; + + +/** A set of macros which allow us to get the line number + * and file name at the point of an error. + * Just goes to show that preprocessors do have some + * redeeming qualities. + */ +#define CPPUNIT_SOURCEANNOTATION + +#ifdef CPPUNIT_SOURCEANNOTATION + + #undef assert + #define assert(condition)\ + (this->assertImplementation ((condition),(#condition),\ + __LINE__, __FILE__)) + +#else + + #undef assert + #define assert(condition)\ + (this->assertImplementation ((condition),"",\ + __LINE__, __FILE__)) + +#endif + + +/// Macro for primitive value comparisons +#define assertDoublesEqual(expected,actual,delta)\ +(this->assertEquals ((expected),\ + (actual),(delta),__LINE__,__FILE__)) + +/// Macro for primitive value comparisons +#define assertLongsEqual(expected,actual)\ +(this->assertEquals ((expected),\ + (actual),__LINE__,__FILE__)) +} // namespace CppUnit + +#endif // CPPUNIT_TESTCASE_H diff --git a/include/cppunit/TestFailure.h b/include/cppunit/TestFailure.h new file mode 100644 index 0000000..f8dae91 --- /dev/null +++ b/include/cppunit/TestFailure.h @@ -0,0 +1,57 @@ +#ifndef CPPUNIT_TESTFAILURE_H +#define CPPUNIT_TESTFAILURE_H + +#include <string> + +namespace CppUnit { + + class Test; + class Exception; + + + /** + * A TestFailure collects a failed test together with + * the caught exception. + * + * TestFailure assumes lifetime control for any exception + * passed to it. The lifetime of tests is handled by + * their TestSuite (if they have been added to one) or + * whomever creates them. + * + * see TestResult + * see TestSuite + * + */ + class TestFailure + { + public: + TestFailure (Test *failedTest, Exception *thrownException); + ~TestFailure (); + + Test* failedTest (); + + Exception* thrownException (); + + std::string toString () const; + + protected: + Test *m_failedTest; + Exception *m_thrownException; + + private: + TestFailure (const TestFailure& other); + TestFailure& operator= (const TestFailure& other); + }; + + /// Gets the failed test. + inline Test *TestFailure::failedTest () + { return m_failedTest; } + + + /// Gets the thrown exception. + inline Exception *TestFailure::thrownException () + { return m_thrownException; } + +} // namespace CppUnit + +#endif // CPPUNIT_TESTFAILURE_H diff --git a/include/cppunit/TestRegistry.h b/include/cppunit/TestRegistry.h new file mode 100644 index 0000000..754f9fb --- /dev/null +++ b/include/cppunit/TestRegistry.h @@ -0,0 +1,40 @@ +#ifndef CPPUNIT_TESTREGISTRY_H +#define CPPUNIT_TESTREGISTRY_H + + +#include <vector> +#include <string> + + +namespace CppUnit { + + class Test; + + /** This class is used to register tests and testcases. + * + * It implements a registry to place the test cases into. + * The test cases can then register themselves. + * All TestCallers and those TestCases that are constructed + * register themselve automatically. + * + */ + class TestRegistry { + public: + static TestRegistry& getRegistry(); + + ~TestRegistry(); + + const std::vector<std::string>& getAllTestNames() const; + const std::vector<Test*>& getAllTests() const; + std::vector<Test*> getTest(const std::string& name) const; + void addTest(std::string name, Test* test); + + private: + TestRegistry(); + + }; + +} // namespace CppUnit + +#endif // CPPUNIT_TESTREGISTRY_H + diff --git a/include/cppunit/TestResult.h b/include/cppunit/TestResult.h new file mode 100644 index 0000000..8da0c18 --- /dev/null +++ b/include/cppunit/TestResult.h @@ -0,0 +1,99 @@ +#ifndef CPPUNIT_TESTRESULT_H +#define CPPUNIT_TESTRESULT_H + +#include <vector> + +#ifndef CPPUNIT_TESTFAILURE_H +#include "TestFailure.h" +#endif + +namespace CppUnit { + + class Exception; + class Test; + + + /** + * A TestResult collects the results of executing a test case. It is an + * instance of the Collecting Parameter pattern. + * + * The test framework distinguishes between failures and errors. + * A failure is anticipated and checked for with assertions. Errors are + * unanticipated problems signified by exceptions that are not generated + * by the framework. + * + * TestResult supplies a template method 'setSynchronizationObject ()' + * so that subclasses can provide mutual exclusion in the face of multiple + * threads. This can be useful when tests execute in one thread and + * they fill a subclass of TestResult which effects change in another + * thread. To have mutual exclusion, override setSynchronizationObject () + * and make sure that you create an instance of ExclusiveZone at the + * beginning of each method. + * + * \see Test + */ + + class TestResult + { + + public: + TestResult (); + virtual ~TestResult (); + + virtual void addError (Test *test, Exception *e); + virtual void addFailure (Test *test, Exception *e); + virtual void startTest (Test *test); + virtual void endTest (Test *test); + virtual int runTests (); + virtual int testErrors (); + virtual int testFailures (); + virtual bool wasSuccessful (); + virtual bool shouldStop (); + virtual void stop (); + + virtual std::vector<TestFailure *>& errors (); + virtual std::vector<TestFailure *>& failures (); + + + class SynchronizationObject + { + public: + SynchronizationObject () {} + virtual ~SynchronizationObject () {} + + virtual void lock () {} + virtual void unlock () {} + }; + + class ExclusiveZone + { + SynchronizationObject *m_syncObject; + + public: + ExclusiveZone (SynchronizationObject *syncObject) + : m_syncObject (syncObject) + { m_syncObject->lock (); } + + ~ExclusiveZone () + { m_syncObject->unlock (); } + }; + + protected: + virtual void setSynchronizationObject (SynchronizationObject *syncObject); + + std::vector<TestFailure *> m_errors; + std::vector<TestFailure *> m_failures; + int m_runTests; + bool m_stop; + SynchronizationObject *m_syncObject; + private: + TestResult (const TestResult& other); + TestResult& operator= (const TestResult& other); + + }; + +} // namespace CppUnit + +#endif // CPPUNIT_TESTRESULT_H + + diff --git a/include/cppunit/TestSuite.h b/include/cppunit/TestSuite.h new file mode 100644 index 0000000..ffa21a8 --- /dev/null +++ b/include/cppunit/TestSuite.h @@ -0,0 +1,58 @@ +#ifndef CPPUNIT_TESTSUITE_H +#define CPPUNIT_TESTSUITE_H + +#include <vector> +#include <string> + +#ifndef CPPUNIT_TEST_H +#include "Test.h" +#endif + +namespace CppUnit { + + class TestResult; + + /** + * A TestSuite is a Composite of Tests. + * It runs a collection of test cases. Here is an example. + * \code + * CppUnit::TestSuite *suite= new CppUnit::TestSuite(); + * suite->addTest(new CppUnit::TestCaller<MathTest> ( + * "testAdd", testAdd)); + * suite->addTest(new CppUnit::TestCaller<MathTest> ( + * "testDivideByZero", testDivideByZero)); + * \endcode + * Note that TestSuites assume lifetime + * control for any tests added to them. + * + * TestSuites do not register themselves in the TestRegistry. + * \see Test + * \see TestCaller + */ + + + class TestSuite : public Test + { + public: + TestSuite (std::string name = ""); + ~TestSuite (); + + void run (TestResult *result); + int countTestCases () const; + void addTest (Test *test); + std::string getName () const; + std::string toString () const; + + virtual void deleteContents (); + + private: + TestSuite (const TestSuite& other); + TestSuite& operator= (const TestSuite& other); + + private: + std::vector<Test *> m_tests; + const std::string m_name; + }; +} // namespace CppUnit + +#endif // CPPUNIT_TESTSUITE_H diff --git a/include/cppunit/TextTestResult.h b/include/cppunit/TextTestResult.h new file mode 100644 index 0000000..2176b2c --- /dev/null +++ b/include/cppunit/TextTestResult.h @@ -0,0 +1,32 @@ +#ifndef CPPUNIT_TEXTTESTRESULT_H +#define CPPUNIT_TEXTTESTRESULT_H + +#include <iosfwd> +#include "TestResult.h" + +namespace CppUnit { + + class Exception; + class Test; + + class TextTestResult : public TestResult + { + public: + virtual void addError (Test *test, Exception *e); + virtual void addFailure (Test *test, Exception *e); + virtual void startTest (Test *test); + virtual void print (std::ostream& stream); + virtual void printErrors (std::ostream& stream); + virtual void printFailures (std::ostream& stream); + virtual void printHeader (std::ostream& stream); + + }; + + /** insertion operator for easy output */ + std::ostream& operator<< (std::ostream& stream, TextTestResult& result); + +} // namespace CppUnit + +#endif // CPPUNIT_TEXTTESTRESULT_H + + |
