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)
8 * \file attr_value_visitation.cpp
9 * \author Andrey Semashev
12 * \brief This header contains tests for the attribute value extraction helpers.
15 #define BOOST_TEST_MODULE attr_value_visitation
18 #include <boost/mpl/vector.hpp>
19 #include <boost/test/unit_test.hpp>
20 #include <boost/test/floating_point_comparison.hpp>
21 #include <boost/log/attributes/value_visitation.hpp>
22 #include <boost/log/attributes/constant.hpp>
23 #include <boost/log/attributes/attribute_set.hpp>
24 #include <boost/log/attributes/attribute_value_set.hpp>
25 #include "char_definitions.hpp"
27 namespace mpl
= boost::mpl
;
28 namespace logging
= boost::log
;
29 namespace attrs
= logging::attributes
;
33 // The receiver functional object that verifies the extracted attribute values
36 typedef void result_type
;
46 my_receiver() : m_Expected(none_expected
), m_Int(0), m_Double(0.0) {}
50 m_Expected
= none_expected
;
52 void set_expected(int value
)
54 m_Expected
= int_expected
;
57 void set_expected(double value
)
59 m_Expected
= double_expected
;
62 void set_expected(std::string
const& value
)
64 m_Expected
= string_expected
;
68 // Implement visitation logic for all supported types
69 void operator() (int const& value
)
71 BOOST_CHECK_EQUAL(m_Expected
, int_expected
);
72 BOOST_CHECK_EQUAL(m_Int
, value
);
74 void operator() (double const& value
)
76 BOOST_CHECK_EQUAL(m_Expected
, double_expected
);
77 BOOST_CHECK_CLOSE(m_Double
, value
, 0.001);
79 void operator() (std::string
const& value
)
81 BOOST_CHECK_EQUAL(m_Expected
, string_expected
);
82 BOOST_CHECK_EQUAL(m_String
, value
);
84 void operator() (char value
)
86 // This one should not be called
87 BOOST_ERROR("The unexpected operator() has been called");
91 type_expected m_Expected
;
99 // The test checks invokers specialized on a single attribute value type
100 BOOST_AUTO_TEST_CASE(single_type
)
102 typedef logging::attribute_set attr_set
;
103 typedef logging::attribute_value_set attr_values
;
104 typedef test_data
< char > data
;
106 attrs::constant
< int > attr1(10);
107 attrs::constant
< double > attr2(5.5);
108 attrs::constant
< std::string
> attr3("Hello, world!");
110 attr_set set1
, set2
, set3
;
111 set1
[data::attr1()] = attr1
;
112 set1
[data::attr2()] = attr2
;
114 attr_values
values1(set1
, set2
, set3
);
119 logging::value_visitor_invoker
< int > invoker1
;
120 logging::value_visitor_invoker
< double > invoker2
;
121 logging::value_visitor_invoker
< std::string
> invoker3
;
122 logging::value_visitor_invoker
< char > invoker4
;
124 // These two extractors will find their values in the set
125 recv
.set_expected(10);
126 BOOST_CHECK(invoker1(data::attr1(), values1
, recv
));
128 recv
.set_expected(5.5);
129 BOOST_CHECK(invoker2(data::attr2(), values1
, recv
));
133 BOOST_CHECK(!invoker3(data::attr3(), values1
, recv
));
135 // But it will find it in this set
136 set1
[data::attr3()] = attr3
;
138 attr_values
values2(set1
, set2
, set3
);
141 recv
.set_expected("Hello, world!");
142 BOOST_CHECK(invoker3(data::attr3(), values2
, recv
));
144 // This one will find the sought attribute value, but it will have an incorrect type
146 BOOST_CHECK(!invoker4(data::attr1(), values1
, recv
));
148 // This one is the same, but there is a value of the requested type in the set
149 BOOST_CHECK(!invoker1(data::attr2(), values1
, recv
));
153 // The test checks invokers specialized with type lists
154 BOOST_AUTO_TEST_CASE(multiple_types
)
156 typedef logging::attribute_set attr_set
;
157 typedef logging::attribute_value_set attr_values
;
158 typedef test_data
< char > data
;
159 typedef mpl::vector
< int, double, std::string
, char >::type types
;
161 attrs::constant
< int > attr1(10);
162 attrs::constant
< double > attr2(5.5);
163 attrs::constant
< std::string
> attr3("Hello, world!");
165 attr_set set1
, set2
, set3
;
166 set1
[data::attr1()] = attr1
;
167 set1
[data::attr2()] = attr2
;
169 attr_values
values1(set1
, set2
, set3
);
174 logging::value_visitor_invoker
< types
> invoker
;
176 // These two extractors will find their values in the set
177 recv
.set_expected(10);
178 BOOST_CHECK(invoker(data::attr1(), values1
, recv
));
180 recv
.set_expected(5.5);
181 BOOST_CHECK(invoker(data::attr2(), values1
, recv
));
185 BOOST_CHECK(!invoker(data::attr3(), values1
, recv
));
187 // But it will find it in this set
188 set1
[data::attr3()] = attr3
;
190 attr_values
values2(set1
, set2
, set3
);
193 recv
.set_expected("Hello, world!");
194 BOOST_CHECK(invoker(data::attr3(), values2
, recv
));
197 // The test verifies the visit function
198 BOOST_AUTO_TEST_CASE(visit_function
)
200 typedef logging::attribute_set attr_set
;
201 typedef logging::attribute_value_set attr_values
;
202 typedef test_data
< char > data
;
203 typedef mpl::vector
< int, double, std::string
, char >::type types
;
205 attrs::constant
< int > attr1(10);
206 attrs::constant
< double > attr2(5.5);
207 attrs::constant
< std::string
> attr3("Hello, world!");
209 attr_set set1
, set2
, set3
;
210 set1
[data::attr1()] = attr1
;
211 set1
[data::attr2()] = attr2
;
213 attr_values
values1(set1
, set2
, set3
);
218 // These two extractors will find their values in the set
219 recv
.set_expected(10);
220 BOOST_CHECK(logging::visit
< types
>(data::attr1(), values1
, recv
));
222 recv
.set_expected(5.5);
223 BOOST_CHECK(logging::visit
< double >(data::attr2(), values1
, recv
));
227 BOOST_CHECK(!logging::visit
< types
>(data::attr3(), values1
, recv
));
228 BOOST_CHECK(!logging::visit
< char >(data::attr1(), values1
, recv
));
230 // But it will find it in this set
231 set1
[data::attr3()] = attr3
;
233 attr_values
values2(set1
, set2
, set3
);
236 recv
.set_expected("Hello, world!");
237 BOOST_CHECK(logging::visit
< std::string
>(data::attr3(), values2
, recv
));