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.

291 lines
8.7 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: unittest/unittest.hpp
  3. *
  4. * Purpose: Defines various classes and functions used by the STLSoft
  5. * unit-test framework.
  6. *
  7. * Created: 26th February 2004
  8. * Updated: 10th August 2009
  9. *
  10. * Home: http://stlsoft.org/
  11. *
  12. * Copyright (c) 2004-2009, Matthew Wilson and Synesis Software
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions are met:
  17. *
  18. * - Redistributions of source code must retain the above copyright notice, this
  19. * list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright notice,
  21. * this list of conditions and the following disclaimer in the documentation
  22. * and/or other materials provided with the distribution.
  23. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  24. * any contributors may be used to endorse or promote products derived from
  25. * this software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  31. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  32. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  34. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  35. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  36. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. * POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * ////////////////////////////////////////////////////////////////////// */
  40. /** \file unittest/unittest.hpp
  41. *
  42. * \brief [C++ only] Defines various classes and functions used by the
  43. * STLSoft unit-test framework
  44. * (\ref group__library__unittest "Unit Test" Library).
  45. */
  46. #ifndef STLSOFT_INCL_UNITTEST_HPP_UNITTEST
  47. #define STLSOFT_INCL_UNITTEST_HPP_UNITTEST
  48. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  49. # define STLSOFT_VER_UNITTEST_HPP_UNITTEST_MAJOR 4
  50. # define STLSOFT_VER_UNITTEST_HPP_UNITTEST_MINOR 2
  51. # define STLSOFT_VER_UNITTEST_HPP_UNITTEST_REVISION 2
  52. # define STLSOFT_VER_UNITTEST_HPP_UNITTEST_EDIT 38
  53. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  54. /* /////////////////////////////////////////////////////////////////////////
  55. * Compatibility
  56. */
  57. /*
  58. [<[STLSOFT-AUTO:NO-DOCFILELABEL]>]
  59. */
  60. /* /////////////////////////////////////////////////////////////////////////
  61. * Includes
  62. */
  63. #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
  64. # include <stlsoft/stlsoft.h>
  65. #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */
  66. #ifndef STLSOFT_UNITTEST
  67. # error This file should not be used when STLSOFT_UNITTEST is not defined. You should probably refrain from including it directly, since it is an internal implementation feature, and subject to change at any time
  68. #endif /* !STLSOFT_UNITTEST */
  69. #ifndef STLSOFT_INCL_H_STDIO
  70. # define STLSOFT_INCL_H_STDIO
  71. # include <stdio.h>
  72. #endif /* !STLSOFT_INCL_H_STDIO */
  73. #ifndef STLSOFT_INCL_H_WCHAR
  74. # define STLSOFT_INCL_H_WCHAR
  75. # include <wchar.h>
  76. #endif /* !STLSOFT_INCL_H_WCHAR */
  77. /* /////////////////////////////////////////////////////////////////////////
  78. * Namespace
  79. */
  80. #ifndef _STLSOFT_NO_NAMESPACE
  81. namespace stlsoft
  82. {
  83. namespace unittest
  84. {
  85. #endif /* _STLSOFT_NO_NAMESPACE */
  86. /* /////////////////////////////////////////////////////////////////////////
  87. * Globals
  88. */
  89. extern FILE *err;
  90. extern FILE *out;
  91. /* /////////////////////////////////////////////////////////////////////////
  92. * Functions
  93. */
  94. using ::fprintf;
  95. using ::fwprintf;
  96. /* /////////////////////////////////////////////////////////////////////////
  97. * Unit test interfaces
  98. */
  99. #ifndef __STLSOFT_UNITTEST_BASE_FILE
  100. # define __STLSOFT_UNITTEST_BASE_FILE NULL
  101. #endif /* !__STLSOFT_UNITTEST_BASE_FILE */
  102. /* /////////////////////////////////////////////////////////////////////////
  103. * Unit test interfaces
  104. */
  105. /** \brief Interface for the unit test reporter
  106. *
  107. * \ingroup group__library__unittest
  108. */
  109. struct unittest_reporter
  110. {
  111. public:
  112. virtual void set_project(char const* projectName) = 0;
  113. virtual void set_component(char const* componentName) = 0;
  114. virtual void set_file(char const* fileName) = 0;
  115. virtual void start() = 0;
  116. virtual void report(char const* message, int line = 0, char const* baseFile = __STLSOFT_UNITTEST_BASE_FILE) = 0;
  117. virtual void start_section(char const* message, int line = 0, char const* baseFile = __STLSOFT_UNITTEST_BASE_FILE) = 0;
  118. virtual void end_section(char const* message, int line = 0, char const* baseFile = __STLSOFT_UNITTEST_BASE_FILE) = 0;
  119. virtual void stop() = 0;
  120. virtual int verbosity() const = 0;
  121. };
  122. typedef ss_bool_t (*unittest_function)(unittest_reporter *);
  123. /** \brief Interface for the unit test host
  124. *
  125. * \ingroup group__library__unittest
  126. */
  127. struct unittest_host
  128. {
  129. public:
  130. virtual ss_uint32_t register_unittest_fn(unittest_function ) = 0;
  131. virtual void deregister_unittest_fn(ss_uint32_t unittestId) = 0;
  132. };
  133. /* /////////////////////////////////////////////////////////////////////////
  134. * Unit test functions
  135. */
  136. /** \brief This function must be defined by the test program, and should return
  137. * an instance of a class implementing the unittest_host interface (protocol)
  138. *
  139. * \ingroup group__library__unittest
  140. *
  141. * \note Because the STLSoft components use a scoping initialiser (Schwarz
  142. * counter) it is important that the implementing object is a heap instance, to
  143. * ensure that it is not destroyed prior to the destructors for the unit test
  144. * initialisers using it to deregister themselves.
  145. */
  146. extern "C" unittest_host *get_unittest_host(void);
  147. /* /////////////////////////////////////////////////////////////////////////
  148. * Unit test classes
  149. */
  150. /** \brief This class is used to automatically register the unit-tests for a
  151. * given compilation unit with the unit test host.
  152. *
  153. * \ingroup group__library__unittest
  154. *
  155. * To use it you simply declare an instance of it, inside a
  156. */
  157. class unittest_registrar
  158. {
  159. typedef unittest_registrar class_type;
  160. public:
  161. unittest_registrar(unittest_function pfn)
  162. : m_host(get_unittest_host())
  163. {
  164. m_key = m_host->register_unittest_fn(pfn);
  165. }
  166. ~unittest_registrar() stlsoft_throw_0()
  167. {
  168. if(0 != m_key)
  169. {
  170. m_host->deregister_unittest_fn(m_key);
  171. }
  172. }
  173. private:
  174. unittest_host *const m_host;
  175. ss_uint32_t m_key;
  176. // Not to be implemented
  177. private:
  178. unittest_registrar(class_type const& rhs);
  179. unittest_registrar& operator =(class_type const& rhs);
  180. };
  181. /** \brief This class is used within unit tests to simplify the
  182. * process of registering the test information, and calling
  183. * \c start() and \c stop() on the reporter.
  184. *
  185. * \ingroup group__library__unittest
  186. *
  187. */
  188. class unittest_initialiser
  189. {
  190. typedef unittest_initialiser class_type;
  191. public:
  192. /// Constructor
  193. ///
  194. /// \param reporter The reporter to be used
  195. /// \param project The project name
  196. /// \param component The component name
  197. /// \param file The file name
  198. unittest_initialiser( unittest_reporter* reporter
  199. , char const* project
  200. , char const* component
  201. , char const* file)
  202. : m_reporter(reporter)
  203. {
  204. STLSOFT_ASSERT(NULL != reporter);
  205. STLSOFT_ASSERT(NULL != project);
  206. STLSOFT_ASSERT(NULL != component);
  207. STLSOFT_ASSERT(NULL != file);
  208. m_reporter->set_project(project);
  209. m_reporter->set_file(file);
  210. m_reporter->set_component(component);
  211. m_reporter->start();
  212. }
  213. ~unittest_initialiser() stlsoft_throw_0()
  214. {
  215. m_reporter->stop();
  216. }
  217. private:
  218. unittest_reporter *const m_reporter;
  219. // Not to be implemented
  220. private:
  221. unittest_initialiser(class_type const& rhs);
  222. unittest_initialiser& operator =(class_type const& rhs);
  223. };
  224. /* ////////////////////////////////////////////////////////////////////// */
  225. #ifndef _STLSOFT_NO_NAMESPACE
  226. } // namespace unittest
  227. using unittest::unittest_reporter;
  228. using unittest::unittest_registrar;
  229. #if 0
  230. using unittest::fprintf;
  231. using unittest::fwprintf;
  232. #endif /* 0 */
  233. using unittest::err;
  234. using unittest::out;
  235. } // namespace stlsoft
  236. #endif /* _STLSOFT_NO_NAMESPACE */
  237. /* ////////////////////////////////////////////////////////////////////// */
  238. #endif /* !STLSOFT_INCL_UNITTEST_HPP_UNITTEST */
  239. /* ///////////////////////////// end of file //////////////////////////// */