1// 2// MuleUnit: A minimalistic C++ Unit testing framework based on EasyUnit. 3// 4// Copyright (c) 2005-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 5// Copyright (c) 2004-2011 Barthelemy Dagenais ( barthelemy@prologique.com ) 6// 7// This library is free software; you can redistribute it and/or 8// modify it under the terms of the GNU Lesser General Public 9// License as published by the Free Software Foundation; either 10// version 2.1 of the License, or (at your option) any later version. 11// 12// This library is distributed in the hope that it will be useful, 13// but WITHOUT ANY WARRANTY; without even the implied warranty of 14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15// Lesser General Public License for more details. 16// 17// You should have received a copy of the GNU Lesser General Public 18// License along with this library; if not, write to the Free Software 19// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20// 21 22#ifndef TEST_H 23#define TEST_H 24 25#include <exception> 26 27#include <wx/string.h> 28#include <list> 29#include <string> 30 31 32/** 33 * MuleUnit namespace. 34 * This is the namespace containing all muleunit classes. 35 */ 36namespace muleunit 37{ 38 39class TestCase; 40class BTList; 41 42 43/** Returns the size of a static array. */ 44template <typename T, size_t N> 45inline size_t ArraySize(T(&)[N]) 46{ 47 return N; 48} 49 50 51/** Print wide-char strings. */ 52inline void Print(const wxString& str) 53{ 54 wxPuts(str.c_str()); 55} 56 57 58/** This exception is raised if an ASSERT fails. */ 59struct CTestFailureException : public std::exception 60{ 61 /** Constructor, takes a snapshot of the current context, and adds the given information. */ 62 CTestFailureException(const wxString& msg, const wxChar* file, long lineNumber); 63 64 ~CTestFailureException() throw(); 65 66 /** Prints the context backtrace for the location where the exception was thrown. */ 67 void PrintBT() const; 68 69 virtual const char* what () const throw (); 70private: 71 //! Pointer to struct containing a snapshot of the contexts 72 //! taken at the time the exception was created. 73 struct BTList* m_bt; 74 75 //! The message passed in the constructor. 76 std::string m_message; 77}; 78 79/** This exception is raised if an wxASSERT fails. */ 80struct CAssertFailureException : public CTestFailureException 81{ 82public: 83 CAssertFailureException(const wxString& msg, const wxChar* file, long lineNumber) 84 : CTestFailureException(msg, file, lineNumber) 85 { 86 } 87}; 88 89 90/** 91 * This class is used to produce informative backtraces 92 * 93 * This is done by specifying a "context" for a given scope, using 94 * the CONTEXT macro, at which point a description is added to the 95 * current list of contexts. At destruction, when the scope is exited, 96 * the context is removed from the queue. 97 * 98 * The resulting "backtrace" can then be printed by calling the 99 * PrintBT() function of an CTestFailureException. 100 */ 101class CContext 102{ 103public: 104 /** Adds a context with the specified information and description. */ 105 CContext(const wxChar* file, int line, const wxString& desc); 106 107 /** Removes the context addded by the constructor. */ 108 ~CContext(); 109}; 110 111 112//! Used to join the CContext instance name with the line-number. 113//! This is done to prevent shadowing. 114#define DO_CONTEXT(x, y, z) x y##z 115 116//! Specifies the context of the current scope. 117#define CONTEXT(x) CContext wxCONCAT(context,__LINE__)(wxT(__FILE__), __LINE__, x) 118 119 120/** 121 * This class disables assertions while it is in scope. 122 */ 123class CAssertOff 124{ 125public: 126 CAssertOff(); 127 ~CAssertOff(); 128}; 129 130 131/** 132 * Test class containing all macros to do unit testing. 133 * A test object represents a test that will be executed. Once it has been 134 * executed, it reports all failures in the testPartResult linked list. 135 * 136 * A failure occurs when a test fails (condition is false). 137 */ 138class Test 139{ 140public: 141 /** 142 * Main Test constructor. Used to create a test that will register itself 143 * with TestRegistry and with its test case. 144 * @param testCaseName Name of the test case this test belongs to 145 * @param testName Name of this test 146 */ 147 Test(const wxString& testCaseName, const wxString& testName); 148 149 /** 150 * Main Test desctructor 151 * Delete the testPartResult linked list. This is why the user should 152 * only use the macro provided by muleunit to report a test result. 153 */ 154 virtual ~Test(); 155 156 /** 157 * Fixtures that will be called after run(). 158 */ 159 virtual void tearDown(); 160 161 /** 162 * Fixtures that will be called before run(). 163 */ 164 virtual void setUp(); 165 166 /** 167 * Test code should be in this method. 168 * run() will be called by the Test's TestCase, hence subclasses of Test 169 * should override this method. 170 */ 171 virtual void run(); 172 173 /** 174 * Get the name of the TestCase this test belongs to. The name of the 175 * TestCase is the first parameter of the test declaration. For example, 176 * if a test is declared as TEST(TESTCASE1, TEST1), this method will return 177 * "TESTCASE1". 178 * 179 * @return The TestCase name of this test 180 */ 181 const wxString& getTestCaseName() const; 182 183 /** 184 * Get the name of this test. The name of the test is the second 185 * parameter of the test declaration. For example, 186 * if a test is declared as TEST(TESTCASE1, TEST1), this method will return 187 * "TEST1". 188 * 189 * @return The name of this test. 190 */ 191 const wxString& getTestName() const; 192 193 template <typename A, typename B> 194 static void DoAssertEquals(const wxString& file, unsigned line, const A& a, const B& b) 195 { 196 if (!(a == b)) { 197 wxString message = wxT("Expected '") + StringFrom(a) + 198 wxT("' but got '") + StringFrom(b) + wxT("'"); 199 200 throw CTestFailureException(message, file, line); 201 } 202 } 203 204protected: 205 wxString m_testCaseName; 206 wxString m_testName; 207 TestCase* m_testCase; 208}; 209 210 211/** 212 * Helperfunction that converts basic types to strings. 213 */ 214template <typename TYPE> 215wxString StringFrom(const TYPE& value) 216{ 217 return wxString() << value; 218} 219 220inline wxString StringFrom(unsigned long long value) 221{ 222 return wxString::Format(wxT("%") wxLongLongFmtSpec wxT("u"), value); 223} 224 225inline wxString StringFrom(signed long long value) 226{ 227 return wxString::Format(wxT("%") wxLongLongFmtSpec wxT("i"), value); 228} 229 230 231#define THROW_TEST_FAILURE(message) \ 232 throw CTestFailureException(message, wxT(__FILE__), __LINE__) 233 234 235/** 236 * Asserts that a condition is true. 237 * If the condition is not true, a failure is generated. 238 * @param condition Condition to fullfill for the assertion to pass 239 * @param message Message that will be displayed if this assertion fails 240 */ 241#define ASSERT_TRUE_M(condition, message) \ 242{ \ 243 if (!(condition)) { \ 244 THROW_TEST_FAILURE(message); \ 245 } \ 246} 247 248 249/** 250 * Same as ASSERT_TRUE, but without an explicit message. 251 */ 252#define ASSERT_TRUE(condition) \ 253 ASSERT_TRUE_M(condition, wxString(wxT("Not true: ")) + wxT(#condition)); 254 255 256/** 257 * Same as ASSERT_TRUE, but without an explicit message and condition must be false. 258 */ 259#define ASSERT_FALSE(condition) \ 260 ASSERT_TRUE_M(!(condition), wxString(wxT("Not false: ")) + wxT(#condition)); 261 262 263/** 264 * Asserts that the two parameters are equals. Operator == must be defined. 265 * If the two parameters are not equals, a failure is generated. 266 * @param expected Expected value 267 * @param actual Actual value to be compared 268 * @param message Message that will be displayed if this assertion fails 269 */ 270#define ASSERT_EQUALS_M(expected,actual,message)\ 271{ \ 272 if (!(expected == actual)) { \ 273 THROW_TEST_FAILURE(message); \ 274 } \ 275} 276 277 278/** 279 * Same as ASSERT_EQUALS_M, but without an explicit message. 280 */ 281#define ASSERT_EQUALS(expected, actual) \ 282 Test::DoAssertEquals(wxT(__FILE__), __LINE__, expected, actual) 283 284 285/** 286 * Make a test fails with the given message. 287 * @param text Failure message 288 */ 289#define FAIL_M(text) \ 290 THROW_TEST_FAILURE(text) 291 292/** 293 * Same as FAIL_M, but without an explicit message. 294 */ 295#define FAIL() FAIL_M(wxT("Test failed.")) 296 297 298/** 299 * Requires that an exception of a certain type is raised. 300 */ 301#define ASSERT_RAISES_M(type, call, message) \ 302 try { \ 303 { call; }\ 304 THROW_TEST_FAILURE(message); \ 305 } catch (const type&) { \ 306 } catch (const std::exception& e) { \ 307 THROW_TEST_FAILURE(wxString::FromAscii(e.what())); \ 308 } 309 310 311 312/** 313 * Same as ASSERT_RAISES, but without an explicit message. 314 */ 315#define ASSERT_RAISES(type, call) \ 316 ASSERT_RAISES_M(type, (call), wxT("Exception of type ") wxT(#type) wxT(" not raised.")) 317 318 319 320/** 321 * Define a test in a TestCase using test fixtures. 322 * User should put his test code between brackets after using this macro. 323 * 324 * This macro should only be used if test fixtures were declared earlier in 325 * this order: DECLARE, SETUP, TEARDOWN. 326 * @param testCaseName TestCase name where the test belongs to. Should be 327 * the same name of DECLARE, SETUP and TEARDOWN. 328 * @param testName Unique test name. 329 * @param testDisplayName This will be displayed when running the test. 330 */ 331#define TEST_M(testCaseName, testName, testDisplayName) \ 332 class testCaseName##testName##Test : public testCaseName##Declare##Test \ 333 { \ 334 public: \ 335 testCaseName##testName##Test() \ 336 : testCaseName##Declare##Test(wxT(#testCaseName), testDisplayName) \ 337 { \ 338 } \ 339 \ 340 void run(); \ 341 } testCaseName##testName##Instance; \ 342 \ 343 void testCaseName##testName##Test::run() 344 345/** 346 * Define a test in a TestCase using test fixtures. 347 * User should put his test code between brackets after using this macro. 348 * 349 * This macro should only be used if test fixtures were declared earlier in 350 * this order: DECLARE, SETUP, TEARDOWN. 351 * @param testCaseName TestCase name where the test belongs to. Should be 352 * the same name of DECLARE, SETUP and TEARDOWN. 353 * @param testName Unique test name. 354 */ 355#define TEST(testCaseName, testName) TEST_M(testCaseName, testName, wxT(#testName)) 356 357/** 358 * Location to declare variables and objets. 359 * This is where user should declare members accessible by TESTF, 360 * SETUP and TEARDOWN. 361 * 362 * User should not use brackets after using this macro. User should 363 * not initialize any members here. 364 * 365 * @param testCaseName TestCase name of the fixtures 366 * @see END_DECLARE for more information. 367 */ 368#define DECLARE(testCaseName)\ 369 class testCaseName##Declare##Test : public Test \ 370 { \ 371 public: \ 372 testCaseName##Declare##Test(const wxString& testCaseName, const wxString& testName) \ 373 : Test (testCaseName, testName) {} \ 374 virtual void run() = 0; \ 375 376/** 377 * Ending macro used after DECLARE. 378 * 379 * User should use this macro after declaring members with 380 * DECLARE macro. 381 */ 382#define END_DECLARE }; 383 384 385/** 386 * Macro for creating a fixture with no setup/teardown or member variables. 387 */ 388#define DECLARE_SIMPLE(testCaseName) \ 389 DECLARE(testCaseName) \ 390 END_DECLARE; 391 392} // MuleUnit ns 393#endif // TEST_H 394 395