239 lines
6.8 KiB
C++
239 lines
6.8 KiB
C++
/*
|
|
* 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 <string>
|
|
#include <boost/mpl/vector.hpp>
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <boost/test/tools/floating_point_comparison.hpp>
|
|
#include <boost/log/attributes/value_visitation.hpp>
|
|
#include <boost/log/attributes/constant.hpp>
|
|
#include <boost/log/attributes/attribute_set.hpp>
|
|
#include <boost/log/attributes/attribute_value_set.hpp>
|
|
#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));
|
|
}
|