/* * Copyright Andrey Semashev 2007 - 2015. * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) */ /*! * \file attr_value_visitation.cpp * \author Andrey Semashev * \date 21.01.2009 * * \brief This header contains tests for the attribute value extraction helpers. */ #define BOOST_TEST_MODULE attr_value_visitation #include #include #include #include #include #include #include #include #include "char_definitions.hpp" namespace mpl = boost::mpl; namespace logging = boost::log; namespace attrs = logging::attributes; namespace { // The receiver functional object that verifies the extracted attribute values struct my_receiver { typedef void result_type; enum type_expected { none_expected, int_expected, double_expected, string_expected }; my_receiver() : m_Expected(none_expected), m_Int(0), m_Double(0.0) {} void set_expected() { m_Expected = none_expected; } void set_expected(int value) { m_Expected = int_expected; m_Int = value; } void set_expected(double value) { m_Expected = double_expected; m_Double = value; } void set_expected(std::string const& value) { m_Expected = string_expected; m_String = value; } // Implement visitation logic for all supported types void operator() (int const& value) { BOOST_CHECK_EQUAL(m_Expected, int_expected); BOOST_CHECK_EQUAL(m_Int, value); } void operator() (double const& value) { BOOST_CHECK_EQUAL(m_Expected, double_expected); BOOST_CHECK_CLOSE(m_Double, value, 0.001); } void operator() (std::string const& value) { BOOST_CHECK_EQUAL(m_Expected, string_expected); BOOST_CHECK_EQUAL(m_String, value); } void operator() (char value) { // This one should not be called BOOST_ERROR("The unexpected operator() has been called"); } private: type_expected m_Expected; int m_Int; double m_Double; std::string m_String; }; } // namespace // The test checks invokers specialized on a single attribute value type BOOST_AUTO_TEST_CASE(single_type) { typedef logging::attribute_set attr_set; typedef logging::attribute_value_set attr_values; typedef test_data< char > data; attrs::constant< int > attr1(10); attrs::constant< double > attr2(5.5); attrs::constant< std::string > attr3("Hello, world!"); attr_set set1, set2, set3; set1[data::attr1()] = attr1; set1[data::attr2()] = attr2; attr_values values1(set1, set2, set3); values1.freeze(); my_receiver recv; logging::value_visitor_invoker< int > invoker1; logging::value_visitor_invoker< double > invoker2; logging::value_visitor_invoker< std::string > invoker3; logging::value_visitor_invoker< char > invoker4; // These two extractors will find their values in the set recv.set_expected(10); BOOST_CHECK(invoker1(data::attr1(), values1, recv)); recv.set_expected(5.5); BOOST_CHECK(invoker2(data::attr2(), values1, recv)); // This one will not recv.set_expected(); BOOST_CHECK(!invoker3(data::attr3(), values1, recv)); // But it will find it in this set set1[data::attr3()] = attr3; attr_values values2(set1, set2, set3); values2.freeze(); recv.set_expected("Hello, world!"); BOOST_CHECK(invoker3(data::attr3(), values2, recv)); // This one will find the sought attribute value, but it will have an incorrect type recv.set_expected(); BOOST_CHECK(!invoker4(data::attr1(), values1, recv)); // This one is the same, but there is a value of the requested type in the set BOOST_CHECK(!invoker1(data::attr2(), values1, recv)); } // The test checks invokers specialized with type lists BOOST_AUTO_TEST_CASE(multiple_types) { typedef logging::attribute_set attr_set; typedef logging::attribute_value_set attr_values; typedef test_data< char > data; typedef mpl::vector< int, double, std::string, char >::type types; attrs::constant< int > attr1(10); attrs::constant< double > attr2(5.5); attrs::constant< std::string > attr3("Hello, world!"); attr_set set1, set2, set3; set1[data::attr1()] = attr1; set1[data::attr2()] = attr2; attr_values values1(set1, set2, set3); values1.freeze(); my_receiver recv; logging::value_visitor_invoker< types > invoker; // These two extractors will find their values in the set recv.set_expected(10); BOOST_CHECK(invoker(data::attr1(), values1, recv)); recv.set_expected(5.5); BOOST_CHECK(invoker(data::attr2(), values1, recv)); // This one will not recv.set_expected(); BOOST_CHECK(!invoker(data::attr3(), values1, recv)); // But it will find it in this set set1[data::attr3()] = attr3; attr_values values2(set1, set2, set3); values2.freeze(); recv.set_expected("Hello, world!"); BOOST_CHECK(invoker(data::attr3(), values2, recv)); } // The test verifies the visit function BOOST_AUTO_TEST_CASE(visit_function) { typedef logging::attribute_set attr_set; typedef logging::attribute_value_set attr_values; typedef test_data< char > data; typedef mpl::vector< int, double, std::string, char >::type types; attrs::constant< int > attr1(10); attrs::constant< double > attr2(5.5); attrs::constant< std::string > attr3("Hello, world!"); attr_set set1, set2, set3; set1[data::attr1()] = attr1; set1[data::attr2()] = attr2; attr_values values1(set1, set2, set3); values1.freeze(); my_receiver recv; // These two extractors will find their values in the set recv.set_expected(10); BOOST_CHECK(logging::visit< types >(data::attr1(), values1, recv)); recv.set_expected(5.5); BOOST_CHECK(logging::visit< double >(data::attr2(), values1, recv)); // These will not recv.set_expected(); BOOST_CHECK(!logging::visit< types >(data::attr3(), values1, recv)); BOOST_CHECK(!logging::visit< char >(data::attr1(), values1, recv)); // But it will find it in this set set1[data::attr3()] = attr3; attr_values values2(set1, set2, set3); values2.freeze(); recv.set_expected("Hello, world!"); BOOST_CHECK(logging::visit< std::string >(data::attr3(), values2, recv)); }