attr_value_visitation.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file attr_value_visitation.cpp
  9. * \author Andrey Semashev
  10. * \date 21.01.2009
  11. *
  12. * \brief This header contains tests for the attribute value extraction helpers.
  13. */
  14. #define BOOST_TEST_MODULE attr_value_visitation
  15. #include <string>
  16. #include <boost/mpl/vector.hpp>
  17. #include <boost/test/unit_test.hpp>
  18. #include <boost/test/tools/floating_point_comparison.hpp>
  19. #include <boost/log/attributes/value_visitation.hpp>
  20. #include <boost/log/attributes/constant.hpp>
  21. #include <boost/log/attributes/attribute_set.hpp>
  22. #include <boost/log/attributes/attribute_value_set.hpp>
  23. #include "char_definitions.hpp"
  24. namespace mpl = boost::mpl;
  25. namespace logging = boost::log;
  26. namespace attrs = logging::attributes;
  27. namespace {
  28. // The receiver functional object that verifies the extracted attribute values
  29. struct my_receiver
  30. {
  31. typedef void result_type;
  32. enum type_expected
  33. {
  34. none_expected,
  35. int_expected,
  36. double_expected,
  37. string_expected
  38. };
  39. my_receiver() : m_Expected(none_expected), m_Int(0), m_Double(0.0) {}
  40. void set_expected()
  41. {
  42. m_Expected = none_expected;
  43. }
  44. void set_expected(int value)
  45. {
  46. m_Expected = int_expected;
  47. m_Int = value;
  48. }
  49. void set_expected(double value)
  50. {
  51. m_Expected = double_expected;
  52. m_Double = value;
  53. }
  54. void set_expected(std::string const& value)
  55. {
  56. m_Expected = string_expected;
  57. m_String = value;
  58. }
  59. // Implement visitation logic for all supported types
  60. void operator() (int const& value)
  61. {
  62. BOOST_CHECK_EQUAL(m_Expected, int_expected);
  63. BOOST_CHECK_EQUAL(m_Int, value);
  64. }
  65. void operator() (double const& value)
  66. {
  67. BOOST_CHECK_EQUAL(m_Expected, double_expected);
  68. BOOST_CHECK_CLOSE(m_Double, value, 0.001);
  69. }
  70. void operator() (std::string const& value)
  71. {
  72. BOOST_CHECK_EQUAL(m_Expected, string_expected);
  73. BOOST_CHECK_EQUAL(m_String, value);
  74. }
  75. void operator() (char value)
  76. {
  77. // This one should not be called
  78. BOOST_ERROR("The unexpected operator() has been called");
  79. }
  80. private:
  81. type_expected m_Expected;
  82. int m_Int;
  83. double m_Double;
  84. std::string m_String;
  85. };
  86. } // namespace
  87. // The test checks invokers specialized on a single attribute value type
  88. BOOST_AUTO_TEST_CASE(single_type)
  89. {
  90. typedef logging::attribute_set attr_set;
  91. typedef logging::attribute_value_set attr_values;
  92. typedef test_data< char > data;
  93. attrs::constant< int > attr1(10);
  94. attrs::constant< double > attr2(5.5);
  95. attrs::constant< std::string > attr3("Hello, world!");
  96. attr_set set1, set2, set3;
  97. set1[data::attr1()] = attr1;
  98. set1[data::attr2()] = attr2;
  99. attr_values values1(set1, set2, set3);
  100. values1.freeze();
  101. my_receiver recv;
  102. logging::value_visitor_invoker< int > invoker1;
  103. logging::value_visitor_invoker< double > invoker2;
  104. logging::value_visitor_invoker< std::string > invoker3;
  105. logging::value_visitor_invoker< char > invoker4;
  106. // These two extractors will find their values in the set
  107. recv.set_expected(10);
  108. BOOST_CHECK(invoker1(data::attr1(), values1, recv));
  109. recv.set_expected(5.5);
  110. BOOST_CHECK(invoker2(data::attr2(), values1, recv));
  111. // This one will not
  112. recv.set_expected();
  113. BOOST_CHECK(!invoker3(data::attr3(), values1, recv));
  114. // But it will find it in this set
  115. set1[data::attr3()] = attr3;
  116. attr_values values2(set1, set2, set3);
  117. values2.freeze();
  118. recv.set_expected("Hello, world!");
  119. BOOST_CHECK(invoker3(data::attr3(), values2, recv));
  120. // This one will find the sought attribute value, but it will have an incorrect type
  121. recv.set_expected();
  122. BOOST_CHECK(!invoker4(data::attr1(), values1, recv));
  123. // This one is the same, but there is a value of the requested type in the set
  124. BOOST_CHECK(!invoker1(data::attr2(), values1, recv));
  125. }
  126. // The test checks invokers specialized with type lists
  127. BOOST_AUTO_TEST_CASE(multiple_types)
  128. {
  129. typedef logging::attribute_set attr_set;
  130. typedef logging::attribute_value_set attr_values;
  131. typedef test_data< char > data;
  132. typedef mpl::vector< int, double, std::string, char >::type types;
  133. attrs::constant< int > attr1(10);
  134. attrs::constant< double > attr2(5.5);
  135. attrs::constant< std::string > attr3("Hello, world!");
  136. attr_set set1, set2, set3;
  137. set1[data::attr1()] = attr1;
  138. set1[data::attr2()] = attr2;
  139. attr_values values1(set1, set2, set3);
  140. values1.freeze();
  141. my_receiver recv;
  142. logging::value_visitor_invoker< types > invoker;
  143. // These two extractors will find their values in the set
  144. recv.set_expected(10);
  145. BOOST_CHECK(invoker(data::attr1(), values1, recv));
  146. recv.set_expected(5.5);
  147. BOOST_CHECK(invoker(data::attr2(), values1, recv));
  148. // This one will not
  149. recv.set_expected();
  150. BOOST_CHECK(!invoker(data::attr3(), values1, recv));
  151. // But it will find it in this set
  152. set1[data::attr3()] = attr3;
  153. attr_values values2(set1, set2, set3);
  154. values2.freeze();
  155. recv.set_expected("Hello, world!");
  156. BOOST_CHECK(invoker(data::attr3(), values2, recv));
  157. }
  158. // The test verifies the visit function
  159. BOOST_AUTO_TEST_CASE(visit_function)
  160. {
  161. typedef logging::attribute_set attr_set;
  162. typedef logging::attribute_value_set attr_values;
  163. typedef test_data< char > data;
  164. typedef mpl::vector< int, double, std::string, char >::type types;
  165. attrs::constant< int > attr1(10);
  166. attrs::constant< double > attr2(5.5);
  167. attrs::constant< std::string > attr3("Hello, world!");
  168. attr_set set1, set2, set3;
  169. set1[data::attr1()] = attr1;
  170. set1[data::attr2()] = attr2;
  171. attr_values values1(set1, set2, set3);
  172. values1.freeze();
  173. my_receiver recv;
  174. // These two extractors will find their values in the set
  175. recv.set_expected(10);
  176. BOOST_CHECK(logging::visit< types >(data::attr1(), values1, recv));
  177. recv.set_expected(5.5);
  178. BOOST_CHECK(logging::visit< double >(data::attr2(), values1, recv));
  179. // These will not
  180. recv.set_expected();
  181. BOOST_CHECK(!logging::visit< types >(data::attr3(), values1, recv));
  182. BOOST_CHECK(!logging::visit< char >(data::attr1(), values1, recv));
  183. // But it will find it in this set
  184. set1[data::attr3()] = attr3;
  185. attr_values values2(set1, set2, set3);
  186. values2.freeze();
  187. recv.set_expected("Hello, world!");
  188. BOOST_CHECK(logging::visit< std::string >(data::attr3(), values2, recv));
  189. }