• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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