logged_expectations.ipp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // (C) Copyright Gennadiy Rozental 2005-2008.
  2. // Use, modification, and distribution are subject to the
  3. // Boost Software License, ELOG_VER 1.0. (See accompanying file
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision: 54633 $
  10. //
  11. // Description : Facilities to perform interaction based testng of logged expectations
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
  14. #define BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
  15. // Boost.Test
  16. #include <boost/test/detail/config.hpp>
  17. #if BOOST_TEST_SUPPORT_INTERACTION_TESTING
  18. #include <boost/test/detail/global_typedef.hpp>
  19. #include <boost/test/utils/callback.hpp>
  20. #include <boost/test/utils/iterator/token_iterator.hpp>
  21. #include <boost/test/interaction_based.hpp>
  22. #include <boost/test/test_tools.hpp>
  23. #include <boost/test/detail/suppress_warnings.hpp>
  24. // Boost
  25. #include <boost/lexical_cast.hpp>
  26. // STL
  27. #include <fstream>
  28. //____________________________________________________________________________//
  29. namespace boost {
  30. using namespace ::boost::unit_test;
  31. namespace itest {
  32. // ************************************************************************** //
  33. // ************** logged expectation test implementation ************** //
  34. // ************************************************************************** //
  35. struct expectations_logger : itest::manager {
  36. // Constructor
  37. expectations_logger( const_string log_file_name, bool test_or_log );
  38. virtual bool decision_point( const_string, std::size_t );
  39. virtual unsigned enter_scope( const_string, std::size_t, const_string scope_name );
  40. virtual void allocated( const_string, std::size_t, void*, std::size_t s );
  41. virtual void data_flow( const_string d );
  42. virtual std::string return_value( const_string default_value );
  43. private:
  44. // Data members
  45. bool m_test_or_log;
  46. std::fstream m_log_file;
  47. };
  48. literal_string ELOG_VER = "1.0";
  49. literal_string CLMN_SEP = "|";
  50. static const char LINE_SEP = '\n';
  51. literal_string FILE_SIG = "ELOG";
  52. literal_string SCOPE_SIG = "SCOPE";
  53. literal_string ALLOC_SIG = "ALLOC";
  54. literal_string DP_SIG = "SWITCH";
  55. literal_string DATA_SIG = "DATA";
  56. literal_string RETURN_SIG = "RETURN";
  57. //____________________________________________________________________________//
  58. expectations_logger::expectations_logger( const_string log_file_name, bool test_or_log )
  59. : m_test_or_log( test_or_log )
  60. {
  61. BOOST_REQUIRE_MESSAGE( !log_file_name.is_empty(), "Empty expectations log file name" );
  62. m_log_file.open( log_file_name.begin(), test_or_log ? std::ios::in : std::ios::out );
  63. BOOST_REQUIRE_MESSAGE( m_log_file.is_open(),
  64. "Can't open expectations log file " << log_file_name
  65. << " for " << ( m_test_or_log ? "reading" : "writing") );
  66. if( m_test_or_log ) {
  67. std::string line;
  68. std::getline( m_log_file, line, LINE_SEP );
  69. const_string cline( line );
  70. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  71. BOOST_CHECK_EQUAL( *tit, FILE_SIG );
  72. ++tit;
  73. BOOST_CHECK_EQUAL( *tit, ELOG_VER );
  74. }
  75. else {
  76. m_log_file << FILE_SIG << CLMN_SEP << ELOG_VER << LINE_SEP;
  77. }
  78. }
  79. //____________________________________________________________________________//
  80. bool
  81. expectations_logger::decision_point( const_string, std::size_t )
  82. {
  83. if( m_test_or_log ) {
  84. std::string line;
  85. std::getline( m_log_file, line, LINE_SEP );
  86. const_string cline( line );
  87. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  88. BOOST_CHECK_EQUAL( *tit, DP_SIG ); ++tit;
  89. return lexical_cast<bool>( *tit );
  90. }
  91. else {
  92. m_log_file << DP_SIG << CLMN_SEP << std::boolalpha << true << LINE_SEP;
  93. return true;
  94. }
  95. }
  96. //____________________________________________________________________________//
  97. unsigned
  98. expectations_logger::enter_scope( const_string, std::size_t, const_string scope_name )
  99. {
  100. if( m_test_or_log ) {
  101. std::string line;
  102. std::getline( m_log_file, line, LINE_SEP );
  103. const_string cline( line );
  104. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  105. BOOST_CHECK_EQUAL( *tit, SCOPE_SIG ); ++tit;
  106. BOOST_CHECK_EQUAL( *tit, scope_name );
  107. }
  108. else {
  109. m_log_file << SCOPE_SIG << CLMN_SEP << scope_name << LINE_SEP;
  110. }
  111. return 0;
  112. }
  113. //____________________________________________________________________________//
  114. void
  115. expectations_logger::allocated( const_string, std::size_t, void*, std::size_t s )
  116. {
  117. if( m_test_or_log ) {
  118. std::string line;
  119. std::getline( m_log_file, line, LINE_SEP );
  120. const_string cline( line );
  121. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  122. BOOST_CHECK_EQUAL( *tit, ALLOC_SIG ); ++tit;
  123. BOOST_CHECK_EQUAL( lexical_cast<std::size_t>( *tit ), s );
  124. }
  125. else {
  126. m_log_file << ALLOC_SIG << CLMN_SEP << s << LINE_SEP;
  127. }
  128. }
  129. //____________________________________________________________________________//
  130. void
  131. expectations_logger::data_flow( const_string d )
  132. {
  133. if( m_test_or_log ) {
  134. std::string line;
  135. std::getline( m_log_file, line, LINE_SEP );
  136. const_string cline( line );
  137. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  138. BOOST_CHECK_EQUAL( *tit, DATA_SIG ); ++tit;
  139. BOOST_CHECK_EQUAL( *tit, d );
  140. }
  141. else {
  142. m_log_file << DATA_SIG << CLMN_SEP << d << LINE_SEP;
  143. }
  144. }
  145. //____________________________________________________________________________//
  146. std::string
  147. expectations_logger::return_value( const_string default_value )
  148. {
  149. if( m_test_or_log ) {
  150. std::string line;
  151. std::getline( m_log_file, line, LINE_SEP );
  152. const_string cline( line );
  153. string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
  154. BOOST_CHECK_EQUAL( *tit, RETURN_SIG ); ++tit;
  155. return std::string( tit->begin(), tit->size() );
  156. }
  157. else {
  158. m_log_file << RETURN_SIG << CLMN_SEP << default_value << LINE_SEP;
  159. return std::string();
  160. }
  161. }
  162. //____________________________________________________________________________//
  163. // ************************************************************************** //
  164. // ************** logged expectations test ************** //
  165. // ************************************************************************** //
  166. void BOOST_TEST_DECL
  167. logged_expectations( callback0<> const& F, const_string log_file_name, bool test_or_log )
  168. {
  169. expectations_logger el( log_file_name, test_or_log );
  170. F();
  171. }
  172. //____________________________________________________________________________//
  173. } // namespace itest
  174. } // namespace boost
  175. //____________________________________________________________________________//
  176. #include <boost/test/detail/enable_warnings.hpp>
  177. #endif // not ancient compiler
  178. #endif // BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER