Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / log / test / run / attr_value_visitation.cpp
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
15 #define BOOST_TEST_MODULE attr_value_visitation
16
17 #include <string>
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"
26
27 namespace mpl = boost::mpl;
28 namespace logging = boost::log;
29 namespace attrs = logging::attributes;
30
31 namespace {
32
33     // The receiver functional object that verifies the extracted attribute values
34     struct my_receiver
35     {
36         typedef void result_type;
37
38         enum type_expected
39         {
40             none_expected,
41             int_expected,
42             double_expected,
43             string_expected
44         };
45
46         my_receiver() : m_Expected(none_expected), m_Int(0), m_Double(0.0) {}
47
48         void set_expected()
49         {
50             m_Expected = none_expected;
51         }
52         void set_expected(int value)
53         {
54             m_Expected = int_expected;
55             m_Int = value;
56         }
57         void set_expected(double value)
58         {
59             m_Expected = double_expected;
60             m_Double = value;
61         }
62         void set_expected(std::string const& value)
63         {
64             m_Expected = string_expected;
65             m_String = value;
66         }
67
68         // Implement visitation logic for all supported types
69         void operator() (int const& value)
70         {
71             BOOST_CHECK_EQUAL(m_Expected, int_expected);
72             BOOST_CHECK_EQUAL(m_Int, value);
73         }
74         void operator() (double const& value)
75         {
76             BOOST_CHECK_EQUAL(m_Expected, double_expected);
77             BOOST_CHECK_CLOSE(m_Double, value, 0.001);
78         }
79         void operator() (std::string const& value)
80         {
81             BOOST_CHECK_EQUAL(m_Expected, string_expected);
82             BOOST_CHECK_EQUAL(m_String, value);
83         }
84         void operator() (char value)
85         {
86             // This one should not be called
87             BOOST_ERROR("The unexpected operator() has been called");
88         }
89
90     private:
91         type_expected m_Expected;
92         int m_Int;
93         double m_Double;
94         std::string m_String;
95     };
96
97 } // namespace
98
99 // The test checks invokers specialized on a single attribute value type
100 BOOST_AUTO_TEST_CASE(single_type)
101 {
102     typedef logging::attribute_set attr_set;
103     typedef logging::attribute_value_set attr_values;
104     typedef test_data< char > data;
105
106     attrs::constant< int > attr1(10);
107     attrs::constant< double > attr2(5.5);
108     attrs::constant< std::string > attr3("Hello, world!");
109
110     attr_set set1, set2, set3;
111     set1[data::attr1()] = attr1;
112     set1[data::attr2()] = attr2;
113
114     attr_values values1(set1, set2, set3);
115     values1.freeze();
116
117     my_receiver recv;
118
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;
123
124     // These two extractors will find their values in the set
125     recv.set_expected(10);
126     BOOST_CHECK(invoker1(data::attr1(), values1, recv));
127
128     recv.set_expected(5.5);
129     BOOST_CHECK(invoker2(data::attr2(), values1, recv));
130
131     // This one will not
132     recv.set_expected();
133     BOOST_CHECK(!invoker3(data::attr3(), values1, recv));
134
135     // But it will find it in this set
136     set1[data::attr3()] = attr3;
137
138     attr_values values2(set1, set2, set3);
139     values2.freeze();
140
141     recv.set_expected("Hello, world!");
142     BOOST_CHECK(invoker3(data::attr3(), values2, recv));
143
144     // This one will find the sought attribute value, but it will have an incorrect type
145     recv.set_expected();
146     BOOST_CHECK(!invoker4(data::attr1(), values1, recv));
147
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));
150 }
151
152
153 // The test checks invokers specialized with type lists
154 BOOST_AUTO_TEST_CASE(multiple_types)
155 {
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;
160
161     attrs::constant< int > attr1(10);
162     attrs::constant< double > attr2(5.5);
163     attrs::constant< std::string > attr3("Hello, world!");
164
165     attr_set set1, set2, set3;
166     set1[data::attr1()] = attr1;
167     set1[data::attr2()] = attr2;
168
169     attr_values values1(set1, set2, set3);
170     values1.freeze();
171
172     my_receiver recv;
173
174     logging::value_visitor_invoker< types > invoker;
175
176     // These two extractors will find their values in the set
177     recv.set_expected(10);
178     BOOST_CHECK(invoker(data::attr1(), values1, recv));
179
180     recv.set_expected(5.5);
181     BOOST_CHECK(invoker(data::attr2(), values1, recv));
182
183     // This one will not
184     recv.set_expected();
185     BOOST_CHECK(!invoker(data::attr3(), values1, recv));
186
187     // But it will find it in this set
188     set1[data::attr3()] = attr3;
189
190     attr_values values2(set1, set2, set3);
191     values2.freeze();
192
193     recv.set_expected("Hello, world!");
194     BOOST_CHECK(invoker(data::attr3(), values2, recv));
195 }
196
197 // The test verifies the visit function
198 BOOST_AUTO_TEST_CASE(visit_function)
199 {
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;
204
205     attrs::constant< int > attr1(10);
206     attrs::constant< double > attr2(5.5);
207     attrs::constant< std::string > attr3("Hello, world!");
208
209     attr_set set1, set2, set3;
210     set1[data::attr1()] = attr1;
211     set1[data::attr2()] = attr2;
212
213     attr_values values1(set1, set2, set3);
214     values1.freeze();
215
216     my_receiver recv;
217
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));
221
222     recv.set_expected(5.5);
223     BOOST_CHECK(logging::visit< double >(data::attr2(), values1, recv));
224
225     // These will not
226     recv.set_expected();
227     BOOST_CHECK(!logging::visit< types >(data::attr3(), values1, recv));
228     BOOST_CHECK(!logging::visit< char >(data::attr1(), values1, recv));
229
230     // But it will find it in this set
231     set1[data::attr3()] = attr3;
232
233     attr_values values2(set1, set2, set3);
234     values2.freeze();
235
236     recv.set_expected("Hello, world!");
237     BOOST_CHECK(logging::visit< std::string >(data::attr3(), values2, recv));
238 }