/******************************************************************************** * ReactPhysics3D physics library, http://www.reactphysics3d.com * * Copyright (c) 2010-2015 Daniel Chappuis * ********************************************************************************* * * * This software is provided 'as-is', without any express or implied warranty. * * In no event will the authors be held liable for any damages arising from the * * use of this software. * * * * Permission is granted to anyone to use this software for any purpose, * * including commercial applications, and to alter it and redistribute it * * freely, subject to the following restrictions: * * * * 1. The origin of this software must not be misrepresented; you must not claim * * that you wrote the original software. If you use this software in a * * product, an acknowledgment in the product documentation would be * * appreciated but is not required. * * * * 2. Altered source versions must be plainly marked as such, and must not be * * misrepresented as being the original software. * * * * 3. This notice may not be removed or altered from any source distribution. * * * ********************************************************************************/ #ifndef TEST_H #define TEST_H // Libraries #include #include #include /// Reactphysics3D namespace namespace reactphysics3d { // Macros #define test(condition) applyTest(condition, #condition, __FILE__, __LINE__) #define fail(text) applyFail(text, __FILE__, __LINE__); // Class Test /** * This abstract class represents a unit test. To create a unit test, you simply * need to create a class that inherits from the Test class, override the run() method and * use the test() and fail() macros. */ class Test { private : // ---------- Attributes ---------- // /// Name of the test std::string mName; /// Number of tests that passed long mNbPassedTests; /// Number of tests that failed long mNbFailedTests; /// Output stream std::ostream* mOutputStream; // ---------- Methods ---------- // /// Copy constructor is private Test(const Test&); /// Assignment operator is private Test& operator=(const Test& test); protected : // ---------- Methods ---------- // /// Called to test a boolean condition. /// This method should not be called directly in your test but you should /// call test() instead (macro) void applyTest(bool condition, const std::string& testText, const char* filename, long lineNumber); /// Called when a test has failed. /// This method should not be called directly in your test buy you should /// call fail() instead (macro) void applyFail(const std::string& testText, const char* filename, long lineNumber); public : // ---------- Methods ---------- // /// Constructor Test(const std::string& name, std::ostream* stream = &std::cout); /// Destructor virtual ~Test(); /// Return the number of passed tests long getNbPassedTests() const; /// Return the number of failed tests long getNbFailedTests() const; /// Return the output stream const std::ostream* getOutputStream() const; /// Set the output stream void setOutputStream(std::ostream *stream); /// Run the unit test virtual void run() = 0; /// Called when a test passed void succeed(); /// Reset the unit test virtual void reset(); /// Display the report of the unit test and return the number of failed tests long report() const; }; // Called when a test passed inline void Test::succeed() { mNbPassedTests++; } // Reset the unit test inline void Test::reset() { mNbPassedTests = 0; mNbFailedTests = 0; } // Return the number of passed tests inline long Test::getNbPassedTests() const { return mNbPassedTests; } // Return the number of failed tests inline long Test::getNbFailedTests() const { return mNbFailedTests; } // Return the output stream inline const std::ostream* Test::getOutputStream() const { return mOutputStream; } // Set the output stream inline void Test::setOutputStream(std::ostream* stream) { mOutputStream = stream; } } #endif