• 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   setup_formatter_parser.cpp
9  * \author Andrey Semashev
10  * \date   25.08.2013
11  *
12  * \brief  This header contains tests for the formatter parser.
13  */
14 
15 #define BOOST_TEST_MODULE setup_formatter_parser
16 
17 #include <string>
18 #include <boost/test/unit_test.hpp>
19 #include <boost/log/utility/setup/formatter_parser.hpp>
20 
21 #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
22 
23 #include <boost/smart_ptr/shared_ptr.hpp>
24 #include <boost/log/exceptions.hpp>
25 #include <boost/log/core/record.hpp>
26 #include <boost/log/core/record_view.hpp>
27 #include <boost/log/attributes/constant.hpp>
28 #include <boost/log/attributes/attribute_set.hpp>
29 #include <boost/log/attributes/attribute_value_set.hpp>
30 #include <boost/log/utility/formatting_ostream.hpp>
31 #include <boost/log/expressions/formatter.hpp>
32 #include "make_record.hpp"
33 
34 namespace logging = boost::log;
35 namespace attrs = logging::attributes;
36 
37 typedef logging::attribute_set attr_set;
38 typedef logging::attribute_value_set attr_values;
39 typedef logging::record_view record_view;
40 
41 typedef logging::basic_formatting_ostream< char > osstream;
42 typedef logging::basic_formatter< char > formatter;
43 
44 // Tests for simple attribute placeholders in formatters
BOOST_AUTO_TEST_CASE(attr_placeholders)45 BOOST_AUTO_TEST_CASE(attr_placeholders)
46 {
47     attrs::constant< int > attr1(10);
48     attrs::constant< std::string > attr2("hello");
49     attr_set set1;
50 
51     set1["MyAttr"] = attr1;
52     set1["MyStr"] = attr2;
53 
54     record_view rec = make_record_view(set1);
55 
56     {
57         formatter f = logging::parse_formatter("String literal");
58         std::string str1, str2;
59         osstream strm1(str1), strm2(str2);
60         f(rec, strm1);
61         strm2 << "String literal";
62         BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
63     }
64     {
65         formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MyStr: %MyStr%");
66         std::string str1, str2;
67         osstream strm1(str1), strm2(str2);
68         f(rec, strm1);
69         strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
70         BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
71     }
72     {
73         formatter f = logging::parse_formatter("MyAttr: % MyAttr %, MyStr: % MyStr %");
74         std::string str1, str2;
75         osstream strm1(str1), strm2(str2);
76         f(rec, strm1);
77         strm2 << "MyAttr: " << attr1.get() << ", MyStr: " << attr2.get();
78         BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
79     }
80     {
81         formatter f = logging::parse_formatter("%MyAttr%%MyStr%");
82         std::string str1, str2;
83         osstream strm1(str1), strm2(str2);
84         f(rec, strm1);
85         strm2 << attr1.get() << attr2.get();
86         BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
87     }
88     {
89         formatter f = logging::parse_formatter("MyAttr: %MyAttr%, MissingAttr: %MissingAttr%");
90         std::string str1, str2;
91         osstream strm1(str1), strm2(str2);
92         f(rec, strm1);
93         strm2 << "MyAttr: " << attr1.get() << ", MissingAttr: ";
94         BOOST_CHECK_EQUAL(strm1.str(), strm2.str());
95     }
96 }
97 
98 namespace {
99 
100 class test_formatter_factory :
101     public logging::formatter_factory< char >
102 {
103 private:
104     typedef logging::formatter_factory< char > base_type;
105 
106 public:
107     typedef base_type::string_type string_type;
108     typedef base_type::args_map args_map;
109     typedef base_type::formatter_type formatter_type;
110 
111 public:
test_formatter_factory(logging::attribute_name const & name)112     explicit test_formatter_factory(logging::attribute_name const& name) : m_name(name), m_called(false)
113     {
114     }
115 
expect_args(args_map const & args)116     void expect_args(args_map const& args)
117     {
118         m_args = args;
119     }
120 
check_called()121     void check_called()
122     {
123         BOOST_CHECK(m_called);
124         m_called = false;
125     }
126 
create_formatter(logging::attribute_name const & name,args_map const & args)127     formatter_type create_formatter(logging::attribute_name const& name, args_map const& args)
128     {
129         BOOST_CHECK_EQUAL(m_name, name);
130         BOOST_CHECK_EQUAL(m_args.size(), args.size());
131 
132         for (args_map::const_iterator it = m_args.begin(), end = m_args.end(); it != end; ++it)
133         {
134             args_map::const_iterator parsed_it = args.find(it->first);
135             if (parsed_it != args.end())
136             {
137                 BOOST_TEST_CHECKPOINT(("Arg: " + it->first));
138                 BOOST_CHECK_EQUAL(it->second, parsed_it->second);
139             }
140             else
141             {
142                 BOOST_ERROR(("Arg not found: " + it->first));
143             }
144         }
145 
146         m_called = true;
147         return formatter_type();
148     }
149 
150 private:
151     logging::attribute_name m_name;
152     args_map m_args;
153     bool m_called;
154 };
155 
156 } // namespace
157 
158 // Tests for formatter factory
BOOST_AUTO_TEST_CASE(formatter_factory)159 BOOST_AUTO_TEST_CASE(formatter_factory)
160 {
161     logging::attribute_name attr_name("MyCustomAttr");
162     boost::shared_ptr< test_formatter_factory > factory(new test_formatter_factory(attr_name));
163     logging::register_formatter_factory(attr_name, factory);
164 
165     {
166         BOOST_TEST_CHECKPOINT("formatter 1");
167         test_formatter_factory::args_map args;
168         factory->expect_args(args);
169         logging::parse_formatter("Hello: %MyCustomAttr%");
170         factory->check_called();
171     }
172     {
173         BOOST_TEST_CHECKPOINT("formatter 2");
174         test_formatter_factory::args_map args;
175         factory->expect_args(args);
176         logging::parse_formatter("Hello: %MyCustomAttr()%");
177         factory->check_called();
178     }
179     {
180         BOOST_TEST_CHECKPOINT("formatter 3");
181         test_formatter_factory::args_map args;
182         factory->expect_args(args);
183         logging::parse_formatter("Hello: %MyCustomAttr ( ) %");
184         factory->check_called();
185     }
186     {
187         BOOST_TEST_CHECKPOINT("formatter 4");
188         test_formatter_factory::args_map args;
189         args["param1"] = "10";
190         factory->expect_args(args);
191         logging::parse_formatter("Hello: %MyCustomAttr(param1=10)%");
192         factory->check_called();
193     }
194     {
195         BOOST_TEST_CHECKPOINT("formatter 5");
196         test_formatter_factory::args_map args;
197         args["param1"] = "10";
198         factory->expect_args(args);
199         logging::parse_formatter("Hello: % MyCustomAttr ( param1 = 10 ) % ");
200         factory->check_called();
201     }
202     {
203         BOOST_TEST_CHECKPOINT("formatter 6");
204         test_formatter_factory::args_map args;
205         args["param1"] = " 10 ";
206         factory->expect_args(args);
207         logging::parse_formatter("Hello: %MyCustomAttr(param1=\" 10 \")%");
208         factory->check_called();
209     }
210     {
211         BOOST_TEST_CHECKPOINT("formatter 7");
212         test_formatter_factory::args_map args;
213         args["param1"] = "10";
214         args["param2"] = "abcd";
215         factory->expect_args(args);
216         logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = abcd)%");
217         factory->check_called();
218     }
219     {
220         BOOST_TEST_CHECKPOINT("formatter 8");
221         test_formatter_factory::args_map args;
222         args["param1"] = "10";
223         args["param2"] = "abcd";
224         factory->expect_args(args);
225         logging::parse_formatter("Hello: %MyCustomAttr(param1=10,param2=abcd)%");
226         factory->check_called();
227     }
228     {
229         BOOST_TEST_CHECKPOINT("formatter 9");
230         test_formatter_factory::args_map args;
231         args["param1"] = "10";
232         args["param2"] = "abcd";
233         args["param_last"] = "-2.2";
234         factory->expect_args(args);
235         logging::parse_formatter("Hello: %MyCustomAttr(param1 = 10, param2 = \"abcd\", param_last = -2.2)%");
236         factory->check_called();
237     }
238 }
239 
240 // Tests for invalid formatters
BOOST_AUTO_TEST_CASE(invalid)241 BOOST_AUTO_TEST_CASE(invalid)
242 {
243     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr"), logging::parse_error);
244     BOOST_CHECK_THROW(logging::parse_formatter("MyStr%"), logging::parse_error);
245     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(%"), logging::parse_error);
246     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr)%"), logging::parse_error);
247     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param%"), logging::parse_error);
248     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=%"), logging::parse_error);
249     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param)%"), logging::parse_error);
250     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=)%"), logging::parse_error);
251     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(=value)%"), logging::parse_error);
252     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param,param2)%"), logging::parse_error);
253     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,)%"), logging::parse_error);
254     BOOST_CHECK_THROW(logging::parse_formatter("%MyStr(param=value,param2)%"), logging::parse_error);
255 }
256 
257 #endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS) && !defined(BOOST_LOG_WITHOUT_DEFAULT_FACTORIES)
258