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