/* * 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 #include #include #include #include #include #include #include #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); }