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_function.cpp
9 * \author Andrey Semashev
10 * \date 25.01.2009
11 *
12 * \brief This header contains tests for the function attribute.
13 */
14
15 #define BOOST_TEST_MODULE attr_function
16
17 #include <string>
18 #include <boost/mpl/vector.hpp>
19 #include <boost/utility/result_of.hpp>
20 #include <boost/test/unit_test.hpp>
21 #include <boost/log/attributes/function.hpp>
22 #include <boost/log/utility/type_dispatch/static_type_dispatcher.hpp>
23
24 namespace logging = boost::log;
25 namespace attrs = logging::attributes;
26
27 namespace {
28
29 // Type dispatcher for the supported types
30 struct my_dispatcher :
31 public logging::static_type_dispatcher<
32 boost::mpl::vector< int, std::string >
33 >
34 {
35 typedef logging::static_type_dispatcher<
36 boost::mpl::vector< int, std::string >
37 > base_type;
38
39 enum type_expected
40 {
41 none_expected,
42 int_expected,
43 string_expected
44 };
45
my_dispatcher__anon808023260111::my_dispatcher46 my_dispatcher() : base_type(*this), m_Expected(none_expected), m_Int(0) {}
47
set_expected__anon808023260111::my_dispatcher48 void set_expected()
49 {
50 m_Expected = none_expected;
51 }
set_expected__anon808023260111::my_dispatcher52 void set_expected(int value)
53 {
54 m_Expected = int_expected;
55 m_Int = value;
56 }
set_expected__anon808023260111::my_dispatcher57 void set_expected(std::string const& value)
58 {
59 m_Expected = string_expected;
60 m_String = value;
61 }
62
63 // Implement visitation logic for all supported types
operator ()__anon808023260111::my_dispatcher64 void operator() (int const& value) const
65 {
66 BOOST_CHECK_EQUAL(m_Expected, int_expected);
67 BOOST_CHECK_EQUAL(m_Int, value);
68 }
operator ()__anon808023260111::my_dispatcher69 void operator() (std::string const& value) const
70 {
71 BOOST_CHECK_EQUAL(m_Expected, string_expected);
72 BOOST_CHECK_EQUAL(m_String, value);
73 }
74
75 private:
76 type_expected m_Expected;
77 int m_Int;
78 std::string m_String;
79 };
80
81 // A test function that returns an attribute value
get_attr_value()82 int get_attr_value()
83 {
84 return 10;
85 }
86
87 // A test functional object that returns an attribute value
88 struct attr_value_generator
89 {
90 typedef std::string result_type;
91
attr_value_generator__anon808023260111::attr_value_generator92 explicit attr_value_generator(unsigned int& count) : m_CallsCount(count) {}
operator ()__anon808023260111::attr_value_generator93 result_type operator() () const
94 {
95 ++m_CallsCount;
96 return "Hello, world!";
97 }
98
99 private:
100 unsigned int& m_CallsCount;
101 };
102
103 } // namespace
104
105 // The test verifies that the attribute calls the specified functor and returns the value returned by the functor
BOOST_AUTO_TEST_CASE(calling)106 BOOST_AUTO_TEST_CASE(calling)
107 {
108 unsigned int call_count = 0;
109 my_dispatcher disp;
110
111 logging::attribute attr1 =
112 #ifndef BOOST_NO_RESULT_OF
113 attrs::make_function(&get_attr_value);
114 #else
115 attrs::make_function< int >(&get_attr_value);
116 #endif
117
118 logging::attribute attr2 =
119 #ifndef BOOST_NO_RESULT_OF
120 attrs::make_function(attr_value_generator(call_count));
121 #else
122 attrs::make_function< std::string >(attr_value_generator(call_count));
123 #endif
124
125 logging::attribute_value p1(attr1.get_value());
126 logging::attribute_value p2(attr2.get_value());
127 BOOST_CHECK_EQUAL(call_count, 1u);
128 logging::attribute_value p3(attr2.get_value());
129 BOOST_CHECK_EQUAL(call_count, 2u);
130
131 disp.set_expected(10);
132 BOOST_CHECK(p1.dispatch(disp));
133 BOOST_CHECK(p1.dispatch(disp)); // check that the contained value doesn't change over time or upon dispatching
134
135 disp.set_expected("Hello, world!");
136 BOOST_CHECK(p2.dispatch(disp));
137 BOOST_CHECK(p3.dispatch(disp));
138 }
139