Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
8.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #ifndef UNITLIB_H
  9. #define UNITLIB_H
  10. #ifdef _WIN32
  11. #pragma once
  12. #endif
  13. #include "tier0/platform.h"
  14. #include "tier1/interface.h"
  15. #include "appframework/IAppSystem.h"
  16. //-----------------------------------------------------------------------------
  17. // Usage model for the UnitTest library
  18. //
  19. // The general methodology here is that clients are expected to create unit
  20. // test DLLs that statically link to the unit test DLL and which implement
  21. // tests of various libraries. The unit test application will dynamically
  22. // load all DLLs in a directory, which causes them to install their test cases
  23. // into the unit test system. The application then runs through all tests and
  24. // executes them all, displaying the results.
  25. //
  26. // *** NOTE: The test suites are compiled in both debug and release builds,
  27. // even though it's expected to only be useful in debug builds. This is because
  28. // I couldn't come up with a good way of disabling the code in release builds.
  29. // (The only options I could come up with would still compile in the functions,
  30. // just not install them into the unit test library, or would make it so that
  31. // you couldn't step through the unit test code).
  32. //
  33. // Even though this is the case, there's no reason not to add test cases
  34. // directly into your shipping DLLs, as long as you surround the code with
  35. // #ifdef _DEBUG. To error check a project to make sure it's not compiling
  36. // in unit tests in Release build, just don't link in unitlib.lib in Release.
  37. // You can of course also put your test suites into separate DLLs.
  38. //
  39. // All tests inherit from the ITestCase interface. There are two major kinds
  40. // of tests; the first is a single test case meant to run a piece of
  41. // code and check its results match expected values using the Assert macros.
  42. // The second kind is a test suite which is simply a list of other tests.
  43. //
  44. // The following classes and macros are used to easily create unit test cases
  45. // and suites:
  46. //
  47. // Use DEFINE_TESTSUITE to define a particular test suite, and DEFINE_TESTCASE
  48. // to add as many test cases as you like to that test suite, as follows:
  49. //
  50. // DEFINE_TESTSUITE( VectorTestSuite )
  51. //
  52. // DEFINE_TESTCASE( VectorAdditionTest, VectorTestSuite )
  53. // {
  54. // .. test code here ..
  55. // }
  56. //
  57. // Note that the definition of the test suite can occur in a different file
  58. // as the test case. A link error will occur if the test suite to which a
  59. // test case is added has not been defined.
  60. //
  61. // To create a test case that is not part of a suite, use...
  62. //
  63. // DEFINE_TESTCASE_NOSUITE( VectorAdditionTest )
  64. // {
  65. // .. test code here ..
  66. // }
  67. //
  68. // You can also create a suite which is a child of another suite using
  69. //
  70. // DEFINE_SUBSUITE( VectorTestSuite, MathTestSuite )
  71. //
  72. //-----------------------------------------------------------------------------
  73. //-----------------------------------------------------------------------------
  74. // dll export stuff
  75. //-----------------------------------------------------------------------------
  76. #ifdef UNITLIB_DLL_EXPORT
  77. #define UNITLIB_INTERFACE DLL_EXPORT
  78. #define UNITLIB_CLASS_INTERFACE DLL_CLASS_EXPORT
  79. #define UNITLIB_GLOBAL_INTERFACE DLL_GLOBAL_EXPORT
  80. #else
  81. #define UNITLIB_INTERFACE DLL_IMPORT
  82. #define UNITLIB_CLASS_INTERFACE DLL_CLASS_IMPORT
  83. #define UNITLIB_GLOBAL_INTERFACE DLL_GLOBAL_IMPORT
  84. #endif
  85. //-----------------------------------------------------------------------------
  86. // All unit test libraries can be asked for a unit test
  87. // AppSystem to perform connection
  88. //-----------------------------------------------------------------------------
  89. #define UNITTEST_INTERFACE_VERSION "UnitTestV001"
  90. //-----------------------------------------------------------------------------
  91. //
  92. // NOTE: All classes and interfaces below you shouldn't use directly.
  93. // Use the DEFINE_TESTSUITE and DEFINE_TESTCASE macros instead.
  94. //
  95. //-----------------------------------------------------------------------------
  96. //-----------------------------------------------------------------------------
  97. // Test case + suite interface
  98. //-----------------------------------------------------------------------------
  99. class ITestCase
  100. {
  101. public:
  102. // This returns the test name
  103. virtual char const* GetName() = 0;
  104. // This runs the test
  105. virtual void RunTest() = 0;
  106. };
  107. class ITestSuite : public ITestCase
  108. {
  109. public:
  110. // Add a test to the suite...
  111. virtual void AddTest( ITestCase* pTest ) = 0;
  112. };
  113. //-----------------------------------------------------------------------------
  114. // This is the main function exported by the unit test library used by
  115. // unit test DLLs to install their test cases into a list to be run
  116. //-----------------------------------------------------------------------------
  117. UNITLIB_INTERFACE void UnitTestInstallTestCase( ITestCase* pTest );
  118. //-----------------------------------------------------------------------------
  119. // These are the methods used by the unit test running program to run all tests
  120. //-----------------------------------------------------------------------------
  121. UNITLIB_INTERFACE int UnitTestCount();
  122. UNITLIB_INTERFACE ITestCase* GetUnitTest( int i );
  123. //-----------------------------------------------------------------------------
  124. // Helper for unit test DLLs to expose IAppSystems
  125. //-----------------------------------------------------------------------------
  126. #define USE_UNITTEST_APPSYSTEM( _className ) \
  127. static _className s_UnitTest ## _className; \
  128. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( _className, IAppSystem, UNITTEST_INTERFACE_VERSION, s_UnitTest ## _className );
  129. //-----------------------------------------------------------------------------
  130. // Base class for test cases
  131. //-----------------------------------------------------------------------------
  132. class UNITLIB_CLASS_INTERFACE CTestCase : public ITestCase
  133. {
  134. public:
  135. CTestCase( char const* pName, ITestSuite* pParent = 0 );
  136. ~CTestCase();
  137. // Returns the test name
  138. char const* GetName();
  139. private:
  140. char* m_pName;
  141. };
  142. //-----------------------------------------------------------------------------
  143. // Test suite class
  144. //-----------------------------------------------------------------------------
  145. class UNITLIB_CLASS_INTERFACE CTestSuite : public ITestSuite
  146. {
  147. public:
  148. CTestSuite( char const* pName, ITestSuite* pParent = 0 );
  149. ~CTestSuite();
  150. // This runs the test
  151. void RunTest();
  152. // Add a test to the suite...
  153. void AddTest( ITestCase* pTest );
  154. // Returns the test name
  155. char const* GetName();
  156. protected:
  157. int m_TestCount;
  158. ITestCase** m_ppTestCases;
  159. char* m_pName;
  160. };
  161. #define TESTSUITE_CLASS( _suite ) \
  162. class CTS ## _suite : public CTestSuite \
  163. { \
  164. public: \
  165. CTS ## _suite(); \
  166. };
  167. #define TESTSUITE_ACCESSOR( _suite ) \
  168. CTS ## _suite* GetTS ## _suite() \
  169. { \
  170. static CTS ## _suite s_TS ## _suite; \
  171. return &s_TS ## _suite; \
  172. }
  173. #define FWD_DECLARE_TESTSUITE( _suite ) \
  174. class CTS ## _suite; \
  175. CTS ## _suite* GetTS ## _suite();
  176. #define DEFINE_TESTSUITE( _suite ) \
  177. TESTSUITE_CLASS( _suite ) \
  178. TESTSUITE_ACCESSOR( _suite ) \
  179. CTS ## _suite::CTS ## _suite() : CTestSuite( #_suite ) {}
  180. #define DEFINE_SUBSUITE( _suite, _parent ) \
  181. TESTSUITE_CLASS( _suite ) \
  182. TESTSUITE_ACCESSOR( _suite ) \
  183. FWD_DECLARE_TESTSUITE( _parent ) \
  184. CTS ## _suite::CTS ## _suite() : CTestSuite( #_suite, GetTS ## _parent() ) {}
  185. #define TESTCASE_CLASS( _case ) \
  186. class CTC ## _case : public CTestCase \
  187. { \
  188. public: \
  189. CTC ## _case (); \
  190. void RunTest(); \
  191. };
  192. #define DEFINE_TESTCASE_NOSUITE( _case ) \
  193. TESTCASE_CLASS( _case ) \
  194. CTC ## _case::CTC ## _case () : CTestCase( #_case ) {} \
  195. \
  196. CTC ## _case s_TC ## _case; \
  197. \
  198. void CTC ## _case ::RunTest()
  199. #define DEFINE_TESTCASE( _case, _suite ) \
  200. TESTCASE_CLASS( _case ) \
  201. FWD_DECLARE_TESTSUITE( _suite ) \
  202. CTC ## _case::CTC ## _case () : CTestCase( #_case, GetTS ## _suite() ) {} \
  203. \
  204. CTC ## _case s_TC ## _case; \
  205. \
  206. void CTC ## _case ::RunTest()
  207. #define _Shipping_AssertMsg( _exp, _msg, _executeExp, _bFatal ) \
  208. do { \
  209. if (!(_exp)) \
  210. { \
  211. _SpewInfo( SPEW_ASSERT, __TFILE__, __LINE__ ); \
  212. SpewRetval_t ret = _SpewMessage(_msg); \
  213. _executeExp; \
  214. if ( ret == SPEW_DEBUGGER) \
  215. { \
  216. if ( !ShouldUseNewAssertDialog() || DoNewAssertDialog( __TFILE__, __LINE__, _msg ) ) \
  217. DebuggerBreak(); \
  218. if ( _bFatal ) \
  219. _ExitOnFatalAssert( __TFILE__, __LINE__ ); \
  220. } \
  221. } \
  222. } while (0)
  223. #define Shipping_Assert( _exp ) _Shipping_AssertMsg( _exp, _T("Assertion Failed: ") _T(#_exp), ((void)0), false )
  224. #endif // UNITLIB_H