attr_attribute_set.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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_attribute_set.cpp
  9. * \author Andrey Semashev
  10. * \date 24.01.2009
  11. *
  12. * \brief This header contains tests for the attribute set class.
  13. */
  14. #define BOOST_TEST_MODULE attr_attribute_set
  15. #include <list>
  16. #include <vector>
  17. #include <string>
  18. #include <utility>
  19. #include <iterator>
  20. #include <boost/test/unit_test.hpp>
  21. #include <boost/log/attributes/constant.hpp>
  22. #include <boost/log/attributes/attribute_set.hpp>
  23. #include "char_definitions.hpp"
  24. #include "attr_comparison.hpp"
  25. namespace logging = boost::log;
  26. namespace attrs = logging::attributes;
  27. // The test checks construction and assignment
  28. BOOST_AUTO_TEST_CASE(construction)
  29. {
  30. typedef logging::attribute_set attr_set;
  31. typedef test_data< char > data;
  32. attrs::constant< int > attr1(10);
  33. attrs::constant< double > attr2(5.5);
  34. attrs::constant< std::string > attr3("Hello, world!");
  35. attr_set set1;
  36. BOOST_CHECK(set1.empty());
  37. BOOST_CHECK_EQUAL(set1.size(), 0UL);
  38. attr_set set2 = set1;
  39. BOOST_CHECK(set2.empty());
  40. BOOST_CHECK_EQUAL(set2.size(), 0UL);
  41. set2[data::attr1()] = attr1;
  42. set2[data::attr2()] = attr2;
  43. BOOST_CHECK(set1.empty());
  44. BOOST_CHECK_EQUAL(set1.size(), 0UL);
  45. BOOST_CHECK(!set2.empty());
  46. BOOST_CHECK_EQUAL(set2.size(), 2UL);
  47. attr_set set3 = set2;
  48. BOOST_CHECK(!set3.empty());
  49. BOOST_CHECK_EQUAL(set3.size(), 2UL);
  50. BOOST_CHECK_EQUAL(set3.count(data::attr1()), 1UL);
  51. BOOST_CHECK_EQUAL(set3.count(data::attr2()), 1UL);
  52. BOOST_CHECK_EQUAL(set3.count(data::attr3()), 0UL);
  53. set1[data::attr3()] = attr3;
  54. BOOST_CHECK(!set1.empty());
  55. BOOST_CHECK_EQUAL(set1.size(), 1UL);
  56. BOOST_CHECK_EQUAL(set1.count(data::attr3()), 1UL);
  57. set2 = set1;
  58. BOOST_REQUIRE_EQUAL(set1.size(), set2.size());
  59. BOOST_CHECK(std::equal(set1.begin(), set1.end(), set2.begin()));
  60. }
  61. // The test checks lookup methods
  62. BOOST_AUTO_TEST_CASE(lookup)
  63. {
  64. typedef logging::attribute_set attr_set;
  65. typedef test_data< char > data;
  66. typedef std::basic_string< char > string;
  67. attrs::constant< int > attr1(10);
  68. attrs::constant< double > attr2(5.5);
  69. attr_set set1;
  70. set1[data::attr1()] = attr1;
  71. set1[data::attr2()] = attr2;
  72. // Traditional find methods
  73. attr_set::iterator it = set1.find(data::attr1());
  74. BOOST_CHECK(it != set1.end());
  75. BOOST_CHECK_EQUAL(it->second, attr1);
  76. string s1 = data::attr2();
  77. it = set1.find(s1);
  78. BOOST_CHECK(it != set1.end());
  79. BOOST_CHECK_EQUAL(it->second, attr2);
  80. it = set1.find(data::attr1());
  81. BOOST_CHECK(it != set1.end());
  82. BOOST_CHECK_EQUAL(it->second, attr1);
  83. it = set1.find(data::attr3());
  84. BOOST_CHECK(it == set1.end());
  85. // Subscript operator
  86. logging::attribute p = set1[data::attr1()];
  87. BOOST_CHECK_EQUAL(p, attr1);
  88. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  89. p = set1[s1];
  90. BOOST_CHECK_EQUAL(p, attr2);
  91. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  92. p = set1[data::attr1()];
  93. BOOST_CHECK_EQUAL(p, attr1);
  94. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  95. p = set1[data::attr3()];
  96. BOOST_CHECK(!p);
  97. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  98. // Counting elements
  99. BOOST_CHECK_EQUAL(set1.count(data::attr1()), 1UL);
  100. BOOST_CHECK_EQUAL(set1.count(s1), 1UL);
  101. BOOST_CHECK_EQUAL(set1.count(data::attr1()), 1UL);
  102. BOOST_CHECK_EQUAL(set1.count(data::attr3()), 0UL);
  103. }
  104. // The test checks insertion methods
  105. BOOST_AUTO_TEST_CASE(insertion)
  106. {
  107. typedef logging::attribute_set attr_set;
  108. typedef test_data< char > data;
  109. typedef std::basic_string< char > string;
  110. attrs::constant< int > attr1(10);
  111. attrs::constant< double > attr2(5.5);
  112. attrs::constant< std::string > attr3("Hello, world!");
  113. attr_set set1;
  114. // Traditional insert methods
  115. std::pair< attr_set::iterator, bool > res = set1.insert(data::attr1(), attr1);
  116. BOOST_CHECK(res.second);
  117. BOOST_CHECK(res.first != set1.end());
  118. BOOST_CHECK(res.first->first == data::attr1());
  119. BOOST_CHECK_EQUAL(res.first->second, attr1);
  120. BOOST_CHECK(!set1.empty());
  121. BOOST_CHECK_EQUAL(set1.size(), 1UL);
  122. res = set1.insert(std::make_pair(attr_set::key_type(data::attr2()), attr2));
  123. BOOST_CHECK(res.second);
  124. BOOST_CHECK(res.first != set1.end());
  125. BOOST_CHECK(res.first->first == data::attr2());
  126. BOOST_CHECK_EQUAL(res.first->second, attr2);
  127. BOOST_CHECK(!set1.empty());
  128. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  129. // Insertion attempt of an attribute with the name of an already existing attribute
  130. res = set1.insert(std::make_pair(attr_set::key_type(data::attr2()), attr3));
  131. BOOST_CHECK(!res.second);
  132. BOOST_CHECK(res.first != set1.end());
  133. BOOST_CHECK(res.first->first == data::attr2());
  134. BOOST_CHECK_EQUAL(res.first->second, attr2);
  135. BOOST_CHECK(!set1.empty());
  136. BOOST_CHECK_EQUAL(set1.size(), 2UL);
  137. // Mass insertion
  138. typedef attr_set::key_type key_type;
  139. std::list< std::pair< key_type, logging::attribute > > elems;
  140. elems.push_back(std::make_pair(key_type(data::attr2()), attr2));
  141. elems.push_back(std::make_pair(key_type(data::attr1()), attr1));
  142. elems.push_back(std::make_pair(key_type(data::attr3()), attr3));
  143. // ... with element duplication
  144. elems.push_back(std::make_pair(key_type(data::attr1()), attr3));
  145. attr_set set2;
  146. set2.insert(elems.begin(), elems.end());
  147. BOOST_CHECK(!set2.empty());
  148. BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
  149. typedef attr_set::mapped_type mapped_type;
  150. BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr1()]), attr1);
  151. BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr2()]), attr2);
  152. BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr3()]), attr3);
  153. // The same, but with insertion results collection
  154. std::vector< std::pair< attr_set::iterator, bool > > results;
  155. attr_set set3;
  156. set3.insert(elems.begin(), elems.end(), std::back_inserter(results));
  157. BOOST_REQUIRE_EQUAL(results.size(), elems.size());
  158. BOOST_CHECK(!set3.empty());
  159. BOOST_REQUIRE_EQUAL(set3.size(), 3UL);
  160. attr_set::iterator it = set3.find(data::attr1());
  161. BOOST_REQUIRE(it != set3.end());
  162. BOOST_CHECK(it->first == data::attr1());
  163. BOOST_CHECK_EQUAL(it->second, attr1);
  164. BOOST_CHECK(it == results[1].first);
  165. it = set3.find(data::attr2());
  166. BOOST_REQUIRE(it != set3.end());
  167. BOOST_CHECK(it->first == data::attr2());
  168. BOOST_CHECK_EQUAL(it->second, attr2);
  169. BOOST_CHECK(it == results[0].first);
  170. it = set3.find(data::attr3());
  171. BOOST_REQUIRE(it != set3.end());
  172. BOOST_CHECK(it->first == data::attr3());
  173. BOOST_CHECK_EQUAL(it->second, attr3);
  174. BOOST_CHECK(it == results[2].first);
  175. BOOST_CHECK(results[0].second);
  176. BOOST_CHECK(results[1].second);
  177. BOOST_CHECK(results[2].second);
  178. BOOST_CHECK(!results[3].second);
  179. // Subscript operator
  180. attr_set set4;
  181. logging::attribute& p1 = (set4[data::attr1()] = attr1);
  182. BOOST_CHECK_EQUAL(set4.size(), 1UL);
  183. BOOST_CHECK_EQUAL(p1, attr1);
  184. logging::attribute& p2 = (set4[string(data::attr2())] = attr2);
  185. BOOST_CHECK_EQUAL(set4.size(), 2UL);
  186. BOOST_CHECK_EQUAL(p2, attr2);
  187. logging::attribute& p3 = (set4[key_type(data::attr3())] = attr3);
  188. BOOST_CHECK_EQUAL(set4.size(), 3UL);
  189. BOOST_CHECK_EQUAL(p3, attr3);
  190. // subscript operator can replace existing elements
  191. logging::attribute& p4 = (set4[data::attr3()] = attr1);
  192. BOOST_CHECK_EQUAL(set4.size(), 3UL);
  193. BOOST_CHECK_EQUAL(p4, attr1);
  194. }
  195. // The test checks erasure methods
  196. BOOST_AUTO_TEST_CASE(erasure)
  197. {
  198. typedef logging::attribute_set attr_set;
  199. typedef test_data< char > data;
  200. attrs::constant< int > attr1(10);
  201. attrs::constant< double > attr2(5.5);
  202. attrs::constant< std::string > attr3("Hello, world!");
  203. attr_set set1;
  204. set1[data::attr1()] = attr1;
  205. set1[data::attr2()] = attr2;
  206. set1[data::attr3()] = attr3;
  207. attr_set set2 = set1;
  208. BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
  209. BOOST_CHECK_EQUAL(set2.erase(data::attr1()), 1UL);
  210. BOOST_CHECK_EQUAL(set2.size(), 2UL);
  211. BOOST_CHECK_EQUAL(set2.count(data::attr1()), 0UL);
  212. BOOST_CHECK_EQUAL(set2.erase(data::attr1()), 0UL);
  213. BOOST_CHECK_EQUAL(set2.size(), 2UL);
  214. set2.erase(set2.begin());
  215. BOOST_CHECK_EQUAL(set2.size(), 1UL);
  216. BOOST_CHECK_EQUAL(set2.count(data::attr2()), 0UL);
  217. set2 = set1;
  218. BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
  219. attr_set::iterator it = set2.begin();
  220. set2.erase(++it, set2.end());
  221. BOOST_CHECK_EQUAL(set2.size(), 1UL);
  222. BOOST_CHECK_EQUAL(set2.count(data::attr1()), 1UL);
  223. BOOST_CHECK_EQUAL(set2.count(data::attr2()), 0UL);
  224. BOOST_CHECK_EQUAL(set2.count(data::attr3()), 0UL);
  225. set2 = set1;
  226. BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
  227. set2.clear();
  228. BOOST_CHECK(set2.empty());
  229. BOOST_CHECK_EQUAL(set2.size(), 0UL);
  230. }