log/test/run/attr_attribute_set.cpp
2015-01-25 17:32:33 +03:00

281 lines
8.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_attribute_set.cpp
* \author Andrey Semashev
* \date 24.01.2009
*
* \brief This header contains tests for the attribute set class.
*/
#define BOOST_TEST_MODULE attr_attribute_set
#include <list>
#include <vector>
#include <string>
#include <utility>
#include <iterator>
#include <boost/test/unit_test.hpp>
#include <boost/log/attributes/constant.hpp>
#include <boost/log/attributes/attribute_set.hpp>
#include "char_definitions.hpp"
#include "attr_comparison.hpp"
namespace logging = boost::log;
namespace attrs = logging::attributes;
// The test checks construction and assignment
BOOST_AUTO_TEST_CASE(construction)
{
typedef logging::attribute_set attr_set;
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;
BOOST_CHECK(set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 0UL);
attr_set set2 = set1;
BOOST_CHECK(set2.empty());
BOOST_CHECK_EQUAL(set2.size(), 0UL);
set2[data::attr1()] = attr1;
set2[data::attr2()] = attr2;
BOOST_CHECK(set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 0UL);
BOOST_CHECK(!set2.empty());
BOOST_CHECK_EQUAL(set2.size(), 2UL);
attr_set set3 = set2;
BOOST_CHECK(!set3.empty());
BOOST_CHECK_EQUAL(set3.size(), 2UL);
BOOST_CHECK_EQUAL(set3.count(data::attr1()), 1UL);
BOOST_CHECK_EQUAL(set3.count(data::attr2()), 1UL);
BOOST_CHECK_EQUAL(set3.count(data::attr3()), 0UL);
set1[data::attr3()] = attr3;
BOOST_CHECK(!set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 1UL);
BOOST_CHECK_EQUAL(set1.count(data::attr3()), 1UL);
set2 = set1;
BOOST_REQUIRE_EQUAL(set1.size(), set2.size());
BOOST_CHECK(std::equal(set1.begin(), set1.end(), set2.begin()));
}
// The test checks lookup methods
BOOST_AUTO_TEST_CASE(lookup)
{
typedef logging::attribute_set attr_set;
typedef test_data< char > data;
typedef std::basic_string< char > string;
attrs::constant< int > attr1(10);
attrs::constant< double > attr2(5.5);
attr_set set1;
set1[data::attr1()] = attr1;
set1[data::attr2()] = attr2;
// Traditional find methods
attr_set::iterator it = set1.find(data::attr1());
BOOST_CHECK(it != set1.end());
BOOST_CHECK_EQUAL(it->second, attr1);
string s1 = data::attr2();
it = set1.find(s1);
BOOST_CHECK(it != set1.end());
BOOST_CHECK_EQUAL(it->second, attr2);
it = set1.find(data::attr1());
BOOST_CHECK(it != set1.end());
BOOST_CHECK_EQUAL(it->second, attr1);
it = set1.find(data::attr3());
BOOST_CHECK(it == set1.end());
// Subscript operator
logging::attribute p = set1[data::attr1()];
BOOST_CHECK_EQUAL(p, attr1);
BOOST_CHECK_EQUAL(set1.size(), 2UL);
p = set1[s1];
BOOST_CHECK_EQUAL(p, attr2);
BOOST_CHECK_EQUAL(set1.size(), 2UL);
p = set1[data::attr1()];
BOOST_CHECK_EQUAL(p, attr1);
BOOST_CHECK_EQUAL(set1.size(), 2UL);
p = set1[data::attr3()];
BOOST_CHECK(!p);
BOOST_CHECK_EQUAL(set1.size(), 2UL);
// Counting elements
BOOST_CHECK_EQUAL(set1.count(data::attr1()), 1UL);
BOOST_CHECK_EQUAL(set1.count(s1), 1UL);
BOOST_CHECK_EQUAL(set1.count(data::attr1()), 1UL);
BOOST_CHECK_EQUAL(set1.count(data::attr3()), 0UL);
}
// The test checks insertion methods
BOOST_AUTO_TEST_CASE(insertion)
{
typedef logging::attribute_set attr_set;
typedef test_data< char > data;
typedef std::basic_string< char > string;
attrs::constant< int > attr1(10);
attrs::constant< double > attr2(5.5);
attrs::constant< std::string > attr3("Hello, world!");
attr_set set1;
// Traditional insert methods
std::pair< attr_set::iterator, bool > res = set1.insert(data::attr1(), attr1);
BOOST_CHECK(res.second);
BOOST_CHECK(res.first != set1.end());
BOOST_CHECK(res.first->first == data::attr1());
BOOST_CHECK_EQUAL(res.first->second, attr1);
BOOST_CHECK(!set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 1UL);
res = set1.insert(std::make_pair(attr_set::key_type(data::attr2()), attr2));
BOOST_CHECK(res.second);
BOOST_CHECK(res.first != set1.end());
BOOST_CHECK(res.first->first == data::attr2());
BOOST_CHECK_EQUAL(res.first->second, attr2);
BOOST_CHECK(!set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 2UL);
// Insertion attempt of an attribute with the name of an already existing attribute
res = set1.insert(std::make_pair(attr_set::key_type(data::attr2()), attr3));
BOOST_CHECK(!res.second);
BOOST_CHECK(res.first != set1.end());
BOOST_CHECK(res.first->first == data::attr2());
BOOST_CHECK_EQUAL(res.first->second, attr2);
BOOST_CHECK(!set1.empty());
BOOST_CHECK_EQUAL(set1.size(), 2UL);
// Mass insertion
typedef attr_set::key_type key_type;
std::list< std::pair< key_type, logging::attribute > > elems;
elems.push_back(std::make_pair(key_type(data::attr2()), attr2));
elems.push_back(std::make_pair(key_type(data::attr1()), attr1));
elems.push_back(std::make_pair(key_type(data::attr3()), attr3));
// ... with element duplication
elems.push_back(std::make_pair(key_type(data::attr1()), attr3));
attr_set set2;
set2.insert(elems.begin(), elems.end());
BOOST_CHECK(!set2.empty());
BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
typedef attr_set::mapped_type mapped_type;
BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr1()]), attr1);
BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr2()]), attr2);
BOOST_CHECK_EQUAL(static_cast< mapped_type >(set2[data::attr3()]), attr3);
// The same, but with insertion results collection
std::vector< std::pair< attr_set::iterator, bool > > results;
attr_set set3;
set3.insert(elems.begin(), elems.end(), std::back_inserter(results));
BOOST_REQUIRE_EQUAL(results.size(), elems.size());
BOOST_CHECK(!set3.empty());
BOOST_REQUIRE_EQUAL(set3.size(), 3UL);
attr_set::iterator it = set3.find(data::attr1());
BOOST_REQUIRE(it != set3.end());
BOOST_CHECK(it->first == data::attr1());
BOOST_CHECK_EQUAL(it->second, attr1);
BOOST_CHECK(it == results[1].first);
it = set3.find(data::attr2());
BOOST_REQUIRE(it != set3.end());
BOOST_CHECK(it->first == data::attr2());
BOOST_CHECK_EQUAL(it->second, attr2);
BOOST_CHECK(it == results[0].first);
it = set3.find(data::attr3());
BOOST_REQUIRE(it != set3.end());
BOOST_CHECK(it->first == data::attr3());
BOOST_CHECK_EQUAL(it->second, attr3);
BOOST_CHECK(it == results[2].first);
BOOST_CHECK(results[0].second);
BOOST_CHECK(results[1].second);
BOOST_CHECK(results[2].second);
BOOST_CHECK(!results[3].second);
// Subscript operator
attr_set set4;
logging::attribute& p1 = (set4[data::attr1()] = attr1);
BOOST_CHECK_EQUAL(set4.size(), 1UL);
BOOST_CHECK_EQUAL(p1, attr1);
logging::attribute& p2 = (set4[string(data::attr2())] = attr2);
BOOST_CHECK_EQUAL(set4.size(), 2UL);
BOOST_CHECK_EQUAL(p2, attr2);
logging::attribute& p3 = (set4[key_type(data::attr3())] = attr3);
BOOST_CHECK_EQUAL(set4.size(), 3UL);
BOOST_CHECK_EQUAL(p3, attr3);
// subscript operator can replace existing elements
logging::attribute& p4 = (set4[data::attr3()] = attr1);
BOOST_CHECK_EQUAL(set4.size(), 3UL);
BOOST_CHECK_EQUAL(p4, attr1);
}
// The test checks erasure methods
BOOST_AUTO_TEST_CASE(erasure)
{
typedef logging::attribute_set attr_set;
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;
set1[data::attr1()] = attr1;
set1[data::attr2()] = attr2;
set1[data::attr3()] = attr3;
attr_set set2 = set1;
BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
BOOST_CHECK_EQUAL(set2.erase(data::attr1()), 1UL);
BOOST_CHECK_EQUAL(set2.size(), 2UL);
BOOST_CHECK_EQUAL(set2.count(data::attr1()), 0UL);
BOOST_CHECK_EQUAL(set2.erase(data::attr1()), 0UL);
BOOST_CHECK_EQUAL(set2.size(), 2UL);
set2.erase(set2.begin());
BOOST_CHECK_EQUAL(set2.size(), 1UL);
BOOST_CHECK_EQUAL(set2.count(data::attr2()), 0UL);
set2 = set1;
BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
attr_set::iterator it = set2.begin();
set2.erase(++it, set2.end());
BOOST_CHECK_EQUAL(set2.size(), 1UL);
BOOST_CHECK_EQUAL(set2.count(data::attr1()), 1UL);
BOOST_CHECK_EQUAL(set2.count(data::attr2()), 0UL);
BOOST_CHECK_EQUAL(set2.count(data::attr3()), 0UL);
set2 = set1;
BOOST_REQUIRE_EQUAL(set2.size(), 3UL);
set2.clear();
BOOST_CHECK(set2.empty());
BOOST_CHECK_EQUAL(set2.size(), 0UL);
}