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)
9 * \author Andrey Semashev
12 * \brief This header contains tests for the \c attr filter.
15 #define BOOST_TEST_MODULE filt_attr
17 #include <boost/predef/os.h>
19 // Try including WinAPI config as soon as possible so that any other headers don't include Windows SDK headers.
20 // This is important to select the target Windows version, as windows.h will be included by other Boost libraries, e.g. Regex.
21 #if defined(BOOST_OS_WINDOWS_AVAILABLE)
22 #define BOOST_USE_WINDOWS_H
23 #include <boost/winapi/config.hpp>
29 #include <boost/regex.hpp>
30 #include <boost/mpl/vector.hpp>
31 #include <boost/phoenix/bind.hpp>
32 #include <boost/test/unit_test.hpp>
33 #include <boost/log/attributes/constant.hpp>
34 #include <boost/log/attributes/attribute_set.hpp>
35 #include <boost/log/attributes/attribute_value_set.hpp>
36 #include <boost/log/utility/type_dispatch/standard_types.hpp>
37 #include <boost/log/support/regex.hpp>
38 #include <boost/log/expressions.hpp>
39 #include "char_definitions.hpp"
41 namespace phoenix
= boost::phoenix
;
43 namespace logging
= boost::log
;
44 namespace attrs
= logging::attributes
;
45 namespace expr
= logging::expressions
;
47 // The test checks that general conditions work
48 BOOST_AUTO_TEST_CASE(general_conditions
)
50 typedef logging::attribute_set attr_set
;
51 typedef logging::attribute_value_set attr_values
;
52 typedef logging::filter filter
;
53 typedef test_data
< char > data
;
55 attrs::constant
< int > attr1(10);
56 attrs::constant
< double > attr2(5.5);
57 attrs::constant
< std::string
> attr3("Hello, world!");
59 attr_set set1
, set2
, set3
;
60 set1
[data::attr1()] = attr1
;
61 set1
[data::attr2()] = attr2
;
62 set1
[data::attr3()] = attr3
;
64 attr_values
values1(set1
, set2
, set3
);
67 filter f
= expr::attr
< int >(data::attr1()) == 10;
68 BOOST_CHECK(f(values1
));
70 f
= expr::attr
< int >(data::attr1()) < 0;
71 BOOST_CHECK(!f(values1
));
73 f
= expr::attr
< float >(data::attr1()).or_throw() > 0;
74 BOOST_CHECK_THROW(f(values1
), logging::runtime_error
);
75 f
= expr::attr
< float >(data::attr1()) > 0;
76 BOOST_CHECK(!f(values1
));
78 f
= expr::attr
< int >(data::attr4()).or_throw() >= 1;
79 BOOST_CHECK_THROW(f(values1
), logging::runtime_error
);
80 f
= expr::attr
< int >(data::attr4()) >= 1;
81 BOOST_CHECK(!f(values1
));
83 f
= expr::attr
< int >(data::attr4()) < 1;
84 BOOST_CHECK(!f(values1
));
86 f
= expr::attr
< logging::numeric_types
>(data::attr2()) > 5;
87 BOOST_CHECK(f(values1
));
89 f
= expr::attr
< std::string
>(data::attr3()) == "Hello, world!";
90 BOOST_CHECK(f(values1
));
92 f
= expr::attr
< std::string
>(data::attr3()) > "AAA";
93 BOOST_CHECK(f(values1
));
96 // The test checks that is_in_range condition works
97 BOOST_AUTO_TEST_CASE(in_range_check
)
99 typedef logging::attribute_set attr_set
;
100 typedef logging::attribute_value_set attr_values
;
101 typedef logging::filter filter
;
102 typedef test_data
< char > data
;
104 attrs::constant
< int > attr1(10);
105 attrs::constant
< double > attr2(5.5);
106 attrs::constant
< std::string
> attr3("Hello, world!");
108 attr_set set1
, set2
, set3
;
109 set1
[data::attr1()] = attr1
;
110 set1
[data::attr2()] = attr2
;
111 set1
[data::attr3()] = attr3
;
113 attr_values
values1(set1
, set2
, set3
);
116 filter f
= expr::is_in_range(expr::attr
< int >(data::attr1()), 5, 20);
117 BOOST_CHECK(f(values1
));
119 f
= expr::is_in_range(expr::attr
< int >(data::attr1()), 5, 10);
120 BOOST_CHECK(!f(values1
));
122 f
= expr::is_in_range(expr::attr
< int >(data::attr1()), 10, 20);
123 BOOST_CHECK(f(values1
));
125 f
= expr::is_in_range(expr::attr
< logging::numeric_types
>(data::attr2()), 5, 6);
126 BOOST_CHECK(f(values1
));
128 f
= expr::is_in_range(expr::attr
< std::string
>(data::attr3()), "AAA", "zzz");
129 BOOST_CHECK(f(values1
));
131 // Check that strings are saved into the filter by value
134 std::strcpy(buf1
, "AAA");
135 std::strcpy(buf2
, "zzz");
136 f
= expr::is_in_range(expr::attr
< std::string
>(data::attr3()), buf1
, buf2
);
137 std::fill_n(buf1
, sizeof(buf1
), static_cast< char >(0));
138 std::fill_n(buf2
, sizeof(buf2
), static_cast< char >(0));
139 BOOST_CHECK(f(values1
));
141 std::strcpy(buf1
, "AAA");
142 std::strcpy(buf2
, "zzz");
143 f
= expr::is_in_range(expr::attr
< std::string
>(data::attr3()),
144 static_cast< const char* >(buf1
), static_cast< const char* >(buf2
));
145 std::fill_n(buf1
, sizeof(buf1
), static_cast< char >(0));
146 std::fill_n(buf2
, sizeof(buf2
), static_cast< char >(0));
147 BOOST_CHECK(f(values1
));
154 typedef bool result_type
;
156 explicit predicate(unsigned int& present_counter
, bool& result
) :
157 m_PresentCounter(present_counter
),
162 template< typename T
, typename TagT
>
163 result_type
operator() (logging::value_ref
< T
, TagT
> const& val
) const
165 m_PresentCounter
+= !val
.empty();
170 unsigned int& m_PresentCounter
;
176 // The test checks that phoenix::bind interaction works
177 BOOST_AUTO_TEST_CASE(bind_support_check
)
179 typedef logging::attribute_set attr_set
;
180 typedef logging::attribute_value_set attr_values
;
181 typedef logging::filter filter
;
182 typedef test_data
< char > data
;
184 attrs::constant
< int > attr1(10);
185 attrs::constant
< double > attr2(5.5);
186 attrs::constant
< std::string
> attr3("Hello, world!");
188 attr_set set1
, set2
, set3
;
189 set1
[data::attr1()] = attr1
;
190 set1
[data::attr2()] = attr2
;
191 set1
[data::attr3()] = attr3
;
193 attr_values
values1(set1
, set2
, set3
);
196 unsigned int present_counter
= 0;
197 bool predicate_result
= false;
199 filter f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< int >(data::attr1()));
200 BOOST_CHECK_EQUAL(f(values1
), predicate_result
);
201 BOOST_CHECK_EQUAL(present_counter
, 1U);
203 predicate_result
= true;
204 BOOST_CHECK_EQUAL(f(values1
), predicate_result
);
205 BOOST_CHECK_EQUAL(present_counter
, 2U);
207 f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< logging::numeric_types
>(data::attr2()));
208 BOOST_CHECK_EQUAL(f(values1
), predicate_result
);
209 BOOST_CHECK_EQUAL(present_counter
, 3U);
211 f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< int >(data::attr2()).or_throw());
212 BOOST_CHECK_THROW(f(values1
), logging::runtime_error
);
213 f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< int >(data::attr2()));
214 BOOST_CHECK_EQUAL(f(values1
), true);
215 BOOST_CHECK_EQUAL(present_counter
, 3U);
217 f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< int >(data::attr4()).or_throw());
218 BOOST_CHECK_THROW(f(values1
), logging::runtime_error
);
219 f
= phoenix::bind(predicate(present_counter
, predicate_result
), expr::attr
< int >(data::attr4()));
220 BOOST_CHECK_EQUAL(f(values1
), true);
221 BOOST_CHECK_EQUAL(present_counter
, 3U);
224 // The test checks that begins_with condition works
225 BOOST_AUTO_TEST_CASE(begins_with_check
)
227 typedef logging::attribute_set attr_set
;
228 typedef logging::attribute_value_set attr_values
;
229 typedef logging::filter filter
;
230 typedef test_data
< char > data
;
232 attrs::constant
< int > attr1(10);
233 attrs::constant
< double > attr2(5.5);
234 attrs::constant
< std::string
> attr3("Hello, world!");
236 attr_set set1
, set2
, set3
;
237 set1
[data::attr1()] = attr1
;
238 set1
[data::attr2()] = attr2
;
239 set1
[data::attr3()] = attr3
;
241 attr_values
values1(set1
, set2
, set3
);
244 filter f
= expr::begins_with(expr::attr
< std::string
>(data::attr3()), "Hello");
245 BOOST_CHECK(f(values1
));
247 f
= expr::begins_with(expr::attr
< std::string
>(data::attr3()), "hello");
248 BOOST_CHECK(!f(values1
));
250 f
= expr::begins_with(expr::attr
< std::string
>(data::attr3()).or_throw(), "Bye");
251 BOOST_CHECK(!f(values1
));
253 f
= expr::begins_with(expr::attr
< std::string
>(data::attr3()).or_throw(), "world!");
254 BOOST_CHECK(!f(values1
));
256 f
= expr::begins_with(expr::attr
< std::string
>(data::attr2()), "Hello");
257 BOOST_CHECK(!f(values1
));
259 f
= expr::begins_with(expr::attr
< std::string
>(data::attr4()), "Hello");
260 BOOST_CHECK(!f(values1
));
263 // The test checks that ends_with condition works
264 BOOST_AUTO_TEST_CASE(ends_with_check
)
266 typedef logging::attribute_set attr_set
;
267 typedef logging::attribute_value_set attr_values
;
268 typedef logging::filter filter
;
269 typedef test_data
< char > data
;
271 attrs::constant
< int > attr1(10);
272 attrs::constant
< double > attr2(5.5);
273 attrs::constant
< std::string
> attr3("Hello, world!");
275 attr_set set1
, set2
, set3
;
276 set1
[data::attr1()] = attr1
;
277 set1
[data::attr2()] = attr2
;
278 set1
[data::attr3()] = attr3
;
280 attr_values
values1(set1
, set2
, set3
);
283 filter f
= expr::ends_with(expr::attr
< std::string
>(data::attr3()), "world!");
284 BOOST_CHECK(f(values1
));
286 f
= expr::ends_with(expr::attr
< std::string
>(data::attr3()), "World!");
287 BOOST_CHECK(!f(values1
));
289 f
= expr::ends_with(expr::attr
< std::string
>(data::attr3()).or_throw(), "Bye");
290 BOOST_CHECK(!f(values1
));
292 f
= expr::ends_with(expr::attr
< std::string
>(data::attr3()).or_throw(), "Hello");
293 BOOST_CHECK(!f(values1
));
295 f
= expr::ends_with(expr::attr
< std::string
>(data::attr2()), "world!");
296 BOOST_CHECK(!f(values1
));
298 f
= expr::ends_with(expr::attr
< std::string
>(data::attr4()), "world!");
299 BOOST_CHECK(!f(values1
));
302 // The test checks that contains condition works
303 BOOST_AUTO_TEST_CASE(contains_check
)
305 typedef logging::attribute_set attr_set
;
306 typedef logging::attribute_value_set attr_values
;
307 typedef logging::filter filter
;
308 typedef test_data
< char > data
;
310 attrs::constant
< int > attr1(10);
311 attrs::constant
< double > attr2(5.5);
312 attrs::constant
< std::string
> attr3("Hello, world!");
314 attr_set set1
, set2
, set3
;
315 set1
[data::attr1()] = attr1
;
316 set1
[data::attr2()] = attr2
;
317 set1
[data::attr3()] = attr3
;
319 attr_values
values1(set1
, set2
, set3
);
322 filter f
= expr::contains(expr::attr
< std::string
>(data::attr3()), "Hello");
323 BOOST_CHECK(f(values1
));
325 f
= expr::contains(expr::attr
< std::string
>(data::attr3()), "hello");
326 BOOST_CHECK(!f(values1
));
328 f
= expr::contains(expr::attr
< std::string
>(data::attr3()).or_throw(), "o, w");
329 BOOST_CHECK(f(values1
));
331 f
= expr::contains(expr::attr
< std::string
>(data::attr3()).or_throw(), "world!");
332 BOOST_CHECK(f(values1
));
334 f
= expr::contains(expr::attr
< std::string
>(data::attr2()), "Hello");
335 BOOST_CHECK(!f(values1
));
337 f
= expr::contains(expr::attr
< std::string
>(data::attr4()), "Hello");
338 BOOST_CHECK(!f(values1
));
341 // The test checks that matches condition works
342 BOOST_AUTO_TEST_CASE(matches_check
)
344 typedef logging::attribute_set attr_set
;
345 typedef logging::attribute_value_set attr_values
;
346 typedef logging::filter filter
;
347 typedef test_data
< char > data
;
349 attrs::constant
< int > attr1(10);
350 attrs::constant
< double > attr2(5.5);
351 attrs::constant
< std::string
> attr3("Hello, world!");
353 attr_set set1
, set2
, set3
;
354 set1
[data::attr1()] = attr1
;
355 set1
[data::attr2()] = attr2
;
356 set1
[data::attr3()] = attr3
;
358 attr_values
values1(set1
, set2
, set3
);
361 boost::regex
rex("hello");
362 filter f
= expr::matches(expr::attr
< std::string
>(data::attr3()), rex
);
363 BOOST_CHECK(!f(values1
));
366 f
= expr::matches(expr::attr
< std::string
>(data::attr3()).or_throw(), rex
);
367 BOOST_CHECK(f(values1
));
370 f
= expr::matches(expr::attr
< std::string
>(data::attr2()), rex
);
371 BOOST_CHECK(!f(values1
));
373 f
= expr::matches(expr::attr
< std::string
>(data::attr4()), rex
);
374 BOOST_CHECK(!f(values1
));
377 // The test checks that the filter composition works
378 BOOST_AUTO_TEST_CASE(composition_check
)
380 typedef logging::attribute_set attr_set
;
381 typedef logging::attribute_value_set attr_values
;
382 typedef logging::filter filter
;
383 typedef test_data
< char > data
;
385 attrs::constant
< int > attr1(10);
386 attrs::constant
< double > attr2(5.5);
387 attrs::constant
< std::string
> attr3("Hello, world!");
389 attr_set set1
, set2
, set3
;
390 attr_values
values1(set1
, set2
, set3
);
392 set1
[data::attr2()] = attr2
;
393 attr_values
values2(set1
, set2
, set3
);
395 set1
[data::attr3()] = attr3
;
396 set1
[data::attr1()] = attr1
;
397 attr_values
values3(set1
, set2
, set3
);
401 expr::attr
< int >(data::attr1()) <= 10 ||
402 expr::is_in_range(expr::attr
< double >(data::attr2()), 2.2, 7.7);
403 BOOST_CHECK(!f(values1
));
404 BOOST_CHECK(f(values2
));
405 BOOST_CHECK(f(values3
));
407 f
= expr::attr
< int >(data::attr1()) == 10 &&
408 expr::begins_with(expr::attr
< std::string
>(data::attr3()), "Hello");
409 BOOST_CHECK(!f(values1
));
410 BOOST_CHECK(!f(values2
));
411 BOOST_CHECK(f(values3
));