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/tools/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));