| // ---------------------------------------------------------------------------- |
| // Copyright (C) 2002-2006 Marcin Kalicinski |
| // |
| // 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) |
| // |
| // For more information, see www.boost.org |
| // ---------------------------------------------------------------------------- |
| |
| // Intentionally no include guards (to be included more than once) |
| |
| #if !defined(CHTYPE) || !defined(T) || !defined(PTREE) || !defined(NOCASE) || !defined(WIDECHAR) |
| # error No character type specified |
| #endif |
| |
| void test_debug(PTREE *) |
| { |
| #if 0 |
| // Check count |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 0); |
| |
| { |
| |
| // Create ptrees |
| PTREE pt1, pt2; |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 2); |
| |
| // Create PTREE |
| PTREE *pt3 = new PTREE; |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 3); |
| |
| // Insert |
| pt1.push_back(std::make_pair(T("key"), *pt3)); |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 4); |
| |
| // Insert |
| pt2.push_back(std::make_pair(T("key"), *pt3)); |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| |
| // Clear |
| pt1.clear(); |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 4); |
| |
| // Clear |
| pt2.clear(); |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 3); |
| |
| // Delete |
| delete pt3; |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 2); |
| |
| } |
| |
| // Check count |
| BOOST_CHECK(PTREE::debug_get_instances_count() == 0); |
| #endif |
| } |
| |
| void test_constructor_destructor_assignment(PTREE *) |
| { |
| |
| { |
| |
| // Test constructor from string |
| PTREE pt1(T("data")); |
| BOOST_CHECK(pt1.data() == T("data")); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 1); |
| |
| // Do insertions |
| PTREE &tmp1 = pt1.put(T("key1"), T("data1")); |
| PTREE &tmp2 = pt1.put(T("key2"), T("data2")); |
| tmp1.put(T("key3"), T("data3")); |
| tmp2.put(T("key4"), T("data4")); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| |
| // Make a copy using copy constructor |
| PTREE *pt2 = new PTREE(pt1); |
| BOOST_CHECK(*pt2 == pt1); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 10); |
| |
| // Make a copy using = operator |
| PTREE *pt3 = new PTREE; |
| *pt3 = *pt2; |
| BOOST_CHECK(*pt3 == *pt2); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 15); |
| |
| // Test self assignment |
| pt1 = pt1; |
| BOOST_CHECK(pt1 == *pt2); |
| BOOST_CHECK(pt1 == *pt3); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 15); |
| |
| // Destroy |
| delete pt2; |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 10); |
| |
| // Destroy |
| delete pt3; |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| |
| } |
| |
| // Check count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 0); |
| |
| } |
| |
| void test_insertion(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| PTREE tmp1(T("data1")); |
| PTREE tmp2(T("data2")); |
| PTREE tmp3(T("data3")); |
| PTREE tmp4(T("data4")); |
| PTREE::iterator it1 = pt.insert(pt.end(), std::make_pair(T("key1"), tmp1)); |
| PTREE::iterator it2 = pt.insert(it1, std::make_pair(T("key2"), tmp2)); |
| PTREE::iterator it3 = it1->second.push_back(std::make_pair(T("key3"), tmp3)); |
| PTREE::iterator it4 = it1->second.push_front(std::make_pair(T("key4"), tmp4)); |
| it2->second.insert(it2->second.end(), it1->second.begin(), it1->second.end()); |
| |
| // Check instance count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 11); |
| |
| // Check contents |
| BOOST_CHECK(pt.get(T("key1"), T("")) == T("data1")); |
| BOOST_CHECK(pt.get(T("key2"), T("")) == T("data2")); |
| BOOST_CHECK(pt.get(T("key1.key3"), T("")) == T("data3")); |
| BOOST_CHECK(pt.get(T("key1.key4"), T("")) == T("data4")); |
| BOOST_CHECK(pt.get(T("key2.key3"), T("")) == T("data3")); |
| BOOST_CHECK(pt.get(T("key2.key4"), T("")) == T("data4")); |
| |
| // Check sequence |
| PTREE::iterator it = it2; |
| ++it; BOOST_CHECK(it == it1); |
| ++it; BOOST_CHECK(it == pt.end()); |
| it = it4; |
| ++it; BOOST_CHECK(it == it3); |
| ++it; BOOST_CHECK(it == it1->second.end()); |
| |
| } |
| |
| void test_erasing(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| PTREE tmp1(T("data1")); |
| PTREE tmp2(T("data2")); |
| PTREE tmp3(T("data3")); |
| PTREE tmp4(T("data4")); |
| PTREE::iterator it1 = pt.insert(pt.end(), std::make_pair(T("key1"), tmp1)); |
| PTREE::iterator it2 = pt.insert(it1, std::make_pair(T("key2"), tmp2)); |
| it1->second.push_back(std::make_pair(T("key"), tmp3)); |
| it1->second.push_front(std::make_pair(T("key"), tmp4)); |
| it2->second.insert(it2->second.end(), it1->second.begin(), it1->second.end()); |
| |
| // Check instance count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 11); |
| |
| // Test range erase |
| PTREE::iterator it = it1->second.erase(it1->second.begin(), it1->second.end()); |
| BOOST_CHECK(it == it1->second.end()); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 9); |
| |
| // Test single erase |
| PTREE::size_type n = pt.erase(T("key1")); |
| BOOST_CHECK(n == 1); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 8); |
| |
| // Test multiple erase |
| n = it2->second.erase(T("key")); |
| BOOST_CHECK(n == 2); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| |
| // Test one more erase |
| n = pt.erase(T("key2")); |
| BOOST_CHECK(n == 1); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| |
| } |
| |
| void test_clear(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt(T("data")); |
| pt.push_back(std::make_pair(T("key"), PTREE(T("data")))); |
| |
| // Check instance count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 2); |
| |
| // Test clear |
| pt.clear(); |
| BOOST_CHECK(pt.empty()); |
| BOOST_CHECK(pt.data().empty()); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 1); |
| |
| } |
| |
| void test_pushpop(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| PTREE tmp1(T("data1")); |
| PTREE tmp2(T("data2")); |
| PTREE tmp3(T("data3")); |
| PTREE tmp4(T("data4")); |
| pt.push_back(std::make_pair(T("key3"), tmp3)); |
| pt.push_front(std::make_pair(T("key2"), tmp2)); |
| pt.push_back(std::make_pair(T("key4"), tmp4)); |
| pt.push_front(std::make_pair(T("key1"), tmp1)); |
| |
| // Check instance count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 9); |
| |
| // Check sequence |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| |
| // Test pops |
| pt.pop_back(); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 8); |
| BOOST_CHECK(pt.front().second.data() == T("data1")); |
| BOOST_CHECK(pt.back().second.data() == T("data3")); |
| pt.pop_front(); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 7); |
| BOOST_CHECK(pt.front().second.data() == T("data2")); |
| BOOST_CHECK(pt.back().second.data() == T("data3")); |
| pt.pop_back(); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| BOOST_CHECK(pt.front().second.data() == T("data2")); |
| BOOST_CHECK(pt.back().second.data() == T("data2")); |
| pt.pop_front(); |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| BOOST_CHECK(pt.empty()); |
| |
| } |
| |
| void test_container_iteration(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| pt.put(T("key3"), T("")); |
| pt.put(T("key1"), T("")); |
| pt.put(T("key4"), T("")); |
| pt.put(T("key2"), T("")); |
| |
| // iterator |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| |
| // const_iterator |
| { |
| PTREE::const_iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| |
| // reverse_iterator |
| { |
| PTREE::reverse_iterator it = pt.rbegin(); |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it == pt.rend()); |
| } |
| |
| // const_reverse_iterator |
| { |
| PTREE::const_reverse_iterator it = pt.rbegin(); |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it == PTREE::const_reverse_iterator(pt.rend())); |
| } |
| |
| } |
| |
| void test_swap(PTREE *) |
| { |
| |
| PTREE pt1, pt2; |
| |
| // Do insertions |
| pt1.put(T("key1"), T("")); |
| pt1.put(T("key2"), T("")); |
| pt1.put(T("key1.key3"), T("")); |
| pt1.put(T("key1.key4"), T("")); |
| |
| // Check counts |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| BOOST_CHECK(pt1.size() == 2); |
| BOOST_CHECK(pt1.get_child(T("key1")).size() == 2); |
| BOOST_CHECK(pt2.size() == 0); |
| |
| // Swap using member function |
| pt1.swap(pt2); |
| |
| // Check counts |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| BOOST_CHECK(pt2.size() == 2); |
| BOOST_CHECK(pt2.get_child(T("key1")).size() == 2); |
| BOOST_CHECK(pt1.size() == 0); |
| |
| // Swap using free function |
| swap(pt1, pt2); |
| |
| // Check counts |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| BOOST_CHECK(pt1.size() == 2); |
| BOOST_CHECK(pt1.get_child(T("key1")).size() == 2); |
| BOOST_CHECK(pt2.size() == 0); |
| |
| // Swap using std algorithm |
| std::swap(pt1, pt2); |
| |
| // Check counts |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 6); |
| BOOST_CHECK(pt2.size() == 2); |
| BOOST_CHECK(pt2.get_child(T("key1")).size() == 2); |
| BOOST_CHECK(pt1.size() == 0); |
| |
| } |
| |
| void test_sort_reverse(PTREE *) |
| { |
| |
| PTREE pt; |
| |
| // Do insertions |
| pt.put(T("key2"), T("data2")); |
| pt.put(T("key1"), T("data1")); |
| pt.put(T("key4"), T("data4")); |
| pt.put(T("key3"), T("data3")); |
| pt.put(T("key3.key1"), T("")); |
| pt.put(T("key4.key2"), T("")); |
| |
| // Reverse |
| pt.reverse(); |
| |
| // Check sequence |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| // Check sequence using find to check if index is ok |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key3")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key4")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key1")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key2")))); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| |
| // Sort |
| pt.sort(SortPred<PTREE>()); |
| |
| // Check sequence |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| // Check sequence (using find to check if index is ok) |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key1")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key2")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key3")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key4")))); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| |
| // Sort reverse |
| pt.sort(SortPredRev<PTREE>()); |
| |
| // Check sequence |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it->first == T("key4")); ++it; |
| BOOST_CHECK(it->first == T("key3")); ++it; |
| BOOST_CHECK(it->first == T("key2")); ++it; |
| BOOST_CHECK(it->first == T("key1")); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| // Check sequence (using find to check if index is ok) |
| { |
| PTREE::iterator it = pt.begin(); |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key4")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key3")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key2")))); ++it; |
| BOOST_CHECK(it == pt.to_iterator(pt.find(T("key1")))); ++it; |
| BOOST_CHECK(it == pt.end()); |
| } |
| |
| } |
| |
| void test_case(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| pt.put(T("key1"), T("data1")); |
| pt.put(T("KEY2"), T("data2")); |
| pt.put(T("kEy1.keY3"), T("data3")); |
| pt.put(T("KEY1.key4"), T("data4")); |
| |
| // Check findings depending on traits type |
| #if (NOCASE == 0) |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 7); |
| BOOST_CHECK(pt.get(T("key1"), T("")) == T("data1")); |
| BOOST_CHECK(pt.get(T("key2"), T("")) == T("")); |
| BOOST_CHECK(pt.get(T("key1.key3"), T("")) == T("")); |
| BOOST_CHECK(pt.get(T("KEY1.key4"), T("")) == T("data4")); |
| #else |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); |
| BOOST_CHECK(pt.get(T("key1"), T("1")) == pt.get(T("KEY1"), T("2"))); |
| BOOST_CHECK(pt.get(T("key2"), T("1")) == pt.get(T("KEY2"), T("2"))); |
| BOOST_CHECK(pt.get(T("key1.key3"), T("1")) == pt.get(T("KEY1.KEY3"), T("2"))); |
| BOOST_CHECK(pt.get(T("key1.key4"), T("1")) == pt.get(T("KEY1.KEY4"), T("2"))); |
| #endif |
| |
| // Do more insertions |
| pt.push_back(PTREE::value_type(T("key1"), PTREE())); |
| pt.push_back(PTREE::value_type(T("key1"), PTREE())); |
| |
| // Test counts |
| #if (NOCASE == 0) |
| BOOST_CHECK(pt.count(T("key1")) == 3); |
| BOOST_CHECK(pt.count(T("KEY1")) == 1); |
| BOOST_CHECK(pt.count(T("key2")) == 0); |
| BOOST_CHECK(pt.count(T("KEY2")) == 1); |
| BOOST_CHECK(pt.count(T("key3")) == 0); |
| BOOST_CHECK(pt.count(T("KEY3")) == 0); |
| #else |
| BOOST_CHECK(pt.count(T("key1")) == 3); |
| BOOST_CHECK(pt.count(T("KEY1")) == 3); |
| BOOST_CHECK(pt.count(T("key2")) == 1); |
| BOOST_CHECK(pt.count(T("KEY2")) == 1); |
| BOOST_CHECK(pt.count(T("key3")) == 0); |
| BOOST_CHECK(pt.count(T("KEY3")) == 0); |
| #endif |
| |
| } |
| |
| void test_comparison(PTREE *) |
| { |
| |
| // Prepare original |
| PTREE pt_orig(T("data")); |
| pt_orig.put(T("key1"), T("data1")); |
| pt_orig.put(T("key1.key3"), T("data2")); |
| pt_orig.put(T("key1.key4"), T("data3")); |
| pt_orig.put(T("key2"), T("data4")); |
| |
| // Test originals |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| BOOST_CHECK(pt1 == pt2); |
| BOOST_CHECK(pt2 == pt1); |
| BOOST_CHECK(!(pt1 != pt2)); |
| BOOST_CHECK(!(pt2 != pt1)); |
| } |
| |
| // Test originals with modified case |
| #if (NOCASE != 0) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.pop_back(); |
| pt1.put(T("KEY2"), T("data4")); |
| BOOST_CHECK(pt1 == pt2); |
| BOOST_CHECK(pt2 == pt1); |
| BOOST_CHECK(!(pt1 != pt2)); |
| BOOST_CHECK(!(pt2 != pt1)); |
| } |
| #endif |
| |
| // Test modified copies (both modified the same way) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.put(T("key1.key5"), T(".")); |
| pt2.put(T("key1.key5"), T(".")); |
| BOOST_CHECK(pt1 == pt2); |
| BOOST_CHECK(pt2 == pt1); |
| BOOST_CHECK(!(pt1 != pt2)); |
| BOOST_CHECK(!(pt2 != pt1)); |
| } |
| |
| // Test modified copies (modified root data) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.data() = T("a"); |
| pt2.data() = T("b"); |
| BOOST_CHECK(!(pt1 == pt2)); |
| BOOST_CHECK(!(pt2 == pt1)); |
| BOOST_CHECK(pt1 != pt2); |
| BOOST_CHECK(pt2 != pt1); |
| } |
| |
| // Test modified copies (added subkeys with different data) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.put(T("key1.key5"), T("a")); |
| pt2.put(T("key1.key5"), T("b")); |
| BOOST_CHECK(!(pt1 == pt2)); |
| BOOST_CHECK(!(pt2 == pt1)); |
| BOOST_CHECK(pt1 != pt2); |
| BOOST_CHECK(pt2 != pt1); |
| } |
| |
| // Test modified copies (added subkeys with different keys) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.put(T("key1.key5"), T("")); |
| pt2.put(T("key1.key6"), T("")); |
| BOOST_CHECK(!(pt1 == pt2)); |
| BOOST_CHECK(!(pt2 == pt1)); |
| BOOST_CHECK(pt1 != pt2); |
| BOOST_CHECK(pt2 != pt1); |
| } |
| |
| // Test modified copies (added subkey to only one copy) |
| { |
| PTREE pt1(pt_orig); |
| PTREE pt2(pt_orig); |
| pt1.put(T("key1.key5"), T("")); |
| BOOST_CHECK(!(pt1 == pt2)); |
| BOOST_CHECK(!(pt2 == pt1)); |
| BOOST_CHECK(pt1 != pt2); |
| BOOST_CHECK(pt2 != pt1); |
| } |
| |
| } |
| |
| void test_front_back(PTREE *) |
| { |
| |
| // Do insertions |
| PTREE pt; |
| pt.put(T("key1"), T("")); |
| pt.put(T("key2"), T("")); |
| |
| // Check front and back |
| BOOST_CHECK(pt.front().first == T("key1")); |
| BOOST_CHECK(pt.back().first == T("key2")); |
| |
| } |
| |
| void test_get_put(PTREE *) |
| { |
| |
| typedef std::basic_string<CHTYPE> str_t; |
| |
| // Temporary storage |
| str_t tmp_string; |
| boost::optional<int> opt_int; |
| boost::optional<long> opt_long; |
| boost::optional<double> opt_double; |
| boost::optional<float> opt_float; |
| boost::optional<str_t> opt_string; |
| boost::optional<CHTYPE> opt_char; |
| boost::optional<bool> opt_bool; |
| |
| // Do insertions via put |
| PTREE pt; |
| PTREE &pt1 = pt.put(T("k1"), 1); |
| PTREE &pt2 = pt.put(T("k2.k"), 2.5); |
| PTREE &pt3 = pt.put(T("k3.k.k"), T("ala ma kota")); |
| PTREE &pt4 = pt.put(T("k4.k.k.k"), CHTYPE('c')); |
| PTREE &pt5 = pt.put(T("k5.k.k.k.f"), false); |
| PTREE &pt6 = pt.put(T("k5.k.k.k.t"), true); |
| |
| // Check instances count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 17); |
| |
| // Check if const char * version returns std::string |
| BOOST_CHECK(typeid(pt.get_value(T(""))) == typeid(str_t)); |
| |
| // Do extractions via get (throwing version) |
| BOOST_CHECK(pt.get<int>(T("k1")) == 1); |
| BOOST_CHECK(pt.get<long>(T("k1")) == 1); |
| BOOST_CHECK(pt.get<double>(T("k2.k")) == 2.5); |
| BOOST_CHECK(pt.get<float>(T("k2.k")) == 2.5f); |
| BOOST_CHECK(pt.get<str_t>(T("k3.k.k")) == str_t(T("ala ma kota"))); |
| BOOST_CHECK(pt.get<CHTYPE>(T("k4.k.k.k")) == CHTYPE('c')); |
| BOOST_CHECK(pt.get<bool>(T("k5.k.k.k.f")) == false); |
| BOOST_CHECK(pt.get<bool>(T("k5.k.k.k.t")) == true); |
| |
| // Do extractions via get (default value version) |
| BOOST_CHECK(pt.get(T("k1"), 0) == 1); |
| BOOST_CHECK(pt.get(T("k1"), 0L) == 1); |
| BOOST_CHECK(pt.get(T("k2.k"), 0.0) == 2.5); |
| BOOST_CHECK(pt.get(T("k2.k"), 0.0f) == 2.5f); |
| BOOST_CHECK(pt.get(T("k3.k.k"), str_t()) == str_t(T("ala ma kota"))); |
| BOOST_CHECK(pt.get(T("k3.k.k"), T("")) == T("ala ma kota")); |
| BOOST_CHECK(pt.get(T("k4.k.k.k"), CHTYPE('\0')) == CHTYPE('c')); |
| BOOST_CHECK(pt.get(T("k5.k.k.k.f"), true) == false); |
| BOOST_CHECK(pt.get(T("k5.k.k.k.t"), false) == true); |
| |
| // Do extractions via get (optional version) |
| opt_int = pt.get_optional<int>(T("k1")); |
| BOOST_CHECK(opt_int && *opt_int == 1); |
| opt_long = pt.get_optional<long>(T("k1")); |
| BOOST_CHECK(opt_long && *opt_long == 1); |
| opt_double = pt.get_optional<double>(T("k2.k")); |
| BOOST_CHECK(opt_double && *opt_double == 2.5); |
| opt_float = pt.get_optional<float>(T("k2.k")); |
| BOOST_CHECK(opt_float && *opt_float == 2.5f); |
| opt_string = pt.get_optional<str_t>(T("k3.k.k")); |
| BOOST_CHECK(opt_string && *opt_string == str_t(T("ala ma kota"))); |
| opt_char = pt.get_optional<CHTYPE>(T("k4.k.k.k")); |
| BOOST_CHECK(opt_char && *opt_char == CHTYPE('c')); |
| opt_bool = pt.get_optional<bool>(T("k5.k.k.k.f")); |
| BOOST_CHECK(opt_bool && *opt_bool == false); |
| opt_bool = pt.get_optional<bool>(T("k5.k.k.k.t")); |
| BOOST_CHECK(opt_bool && *opt_bool == true); |
| |
| // Do insertions via put_value |
| pt1.put_value(short(1)); |
| pt2.put_value(2.5f); |
| pt3.put_value(str_t(T("ala ma kota"))); |
| pt4.put_value(CHTYPE('c')); |
| pt5.put_value(false); |
| pt6.put_value(true); |
| |
| // Do extractions via get_value (throwing version) |
| BOOST_CHECK(pt1.get_value<int>() == 1); |
| BOOST_CHECK(pt1.get_value<long>() == 1); |
| BOOST_CHECK(pt2.get_value<double>() == 2.5); |
| BOOST_CHECK(pt2.get_value<float>() == 2.5f); |
| BOOST_CHECK(pt3.get_value<str_t>() == str_t(T("ala ma kota"))); |
| BOOST_CHECK(pt4.get_value<CHTYPE>() == CHTYPE('c')); |
| BOOST_CHECK(pt5.get_value<bool>() == false); |
| BOOST_CHECK(pt6.get_value<bool>() == true); |
| |
| // Do extractions via get_value (default value version) |
| BOOST_CHECK(pt1.get_value(0) == 1); |
| BOOST_CHECK(pt1.get_value(0L) == 1); |
| BOOST_CHECK(pt2.get_value(0.0) == 2.5); |
| BOOST_CHECK(pt2.get_value(0.0f) == 2.5f); |
| BOOST_CHECK(pt3.get_value(str_t()) == str_t(T("ala ma kota"))); |
| BOOST_CHECK(pt3.get_value(T("")) == T("ala ma kota")); |
| BOOST_CHECK(pt4.get_value(CHTYPE('\0')) == CHTYPE('c')); |
| BOOST_CHECK(pt5.get_value(true) == false); |
| BOOST_CHECK(pt6.get_value(false) == true); |
| |
| // Do extractions via get_value (optional version) |
| opt_int = pt1.get_value_optional<int>(); |
| BOOST_CHECK(opt_int && *opt_int == 1); |
| opt_long = pt1.get_value_optional<long>(); |
| BOOST_CHECK(opt_long && *opt_long == 1); |
| opt_double = pt2.get_value_optional<double>(); |
| BOOST_CHECK(opt_double && *opt_double == 2.5); |
| opt_float = pt2.get_value_optional<float>(); |
| BOOST_CHECK(opt_float && *opt_float == 2.5f); |
| opt_string = pt3.get_value_optional<str_t>(); |
| BOOST_CHECK(opt_string && *opt_string == str_t(T("ala ma kota"))); |
| opt_char = pt4.get_value_optional<CHTYPE>(); |
| BOOST_CHECK(opt_char && *opt_char == CHTYPE('c')); |
| opt_bool = pt5.get_value_optional<bool>(); |
| BOOST_CHECK(opt_bool && *opt_bool == false); |
| opt_bool = pt6.get_value_optional<bool>(); |
| BOOST_CHECK(opt_bool && *opt_bool == true); |
| |
| // Do incorrect extractions (throwing version) |
| try |
| { |
| pt.get<int>(T("k2.k.bogus.path")); |
| BOOST_ERROR("No required exception thrown"); |
| } |
| catch (boost::property_tree::ptree_bad_path &) { } |
| catch (...) |
| { |
| BOOST_ERROR("Wrong exception type thrown"); |
| } |
| try |
| { |
| pt.get<int>(T("k2.k")); |
| BOOST_ERROR("No required exception thrown"); |
| } |
| catch (boost::property_tree::ptree_bad_data &) { } |
| catch (...) |
| { |
| BOOST_ERROR("Wrong exception type thrown"); |
| } |
| |
| // Do incorrect extractions (default value version) |
| BOOST_CHECK(pt.get(T("k2.k"), -7) == -7); |
| BOOST_CHECK(pt.get(T("k3.k.k"), -7) == -7); |
| BOOST_CHECK(pt.get(T("k4.k.k.k"), -7) == -7); |
| |
| // Do incorrect extractions (optional version) |
| BOOST_CHECK(!pt.get_optional<int>(T("k2.k"))); |
| BOOST_CHECK(!pt.get_optional<int>(T("k3.k.k"))); |
| BOOST_CHECK(!pt.get_optional<int>(T("k4.k.k.k"))); |
| |
| // Test multiple puts with the same key |
| { |
| PTREE pt; |
| pt.put(T("key"), 1); |
| BOOST_CHECK(pt.get<int>(T("key")) == 1); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put(T("key"), 2); |
| BOOST_CHECK(pt.get<int>(T("key")) == 2); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put(T("key.key.key"), 1); |
| PTREE &child = pt.get_child(T("key.key")); |
| BOOST_CHECK(pt.get<int>(T("key.key.key")) == 1); |
| BOOST_CHECK(child.size() == 1); |
| BOOST_CHECK(child.count(T("key")) == 1); |
| pt.put(T("key.key.key"), 2); |
| BOOST_CHECK(pt.get<int>(T("key.key.key")) == 2); |
| BOOST_CHECK(child.size() == 1); |
| BOOST_CHECK(child.count(T("key")) == 1); |
| } |
| |
| // Test multiple puts with the same key |
| { |
| PTREE pt; |
| pt.put(T("key"), 1); |
| BOOST_CHECK(pt.get<int>(T("key")) == 1); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put(T("key"), 2); |
| BOOST_CHECK(pt.get<int>(T("key")) == 2); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put(T("key.key.key"), 1); |
| PTREE &child = pt.get_child(T("key.key")); |
| BOOST_CHECK(child.size() == 1); |
| BOOST_CHECK(child.count(T("key")) == 1); |
| pt.add(T("key.key.key"), 2); |
| BOOST_CHECK(child.size() == 2); |
| BOOST_CHECK(child.count(T("key")) == 2); |
| } |
| |
| // Test that put does not destroy children |
| { |
| PTREE pt; |
| pt.put(T("key1"), 1); |
| pt.put(T("key1.key2"), 2); |
| BOOST_CHECK(pt.get<int>(T("key1"), 0) == 1); |
| BOOST_CHECK(pt.get<int>(T("key1.key2"), 0) == 2); |
| pt.put(T("key1"), 2); |
| BOOST_CHECK(pt.get<int>(T("key1"), 0) == 2); |
| BOOST_CHECK(pt.get<int>(T("key1.key2"), 0) == 2); |
| } |
| |
| // Test that get of single character that is whitespace works |
| { |
| PTREE pt; |
| pt.put_value(T(' ')); |
| CHTYPE ch = pt.get_value<CHTYPE>(); |
| BOOST_CHECK(ch == T(' ')); |
| } |
| |
| // Test that get of non-char value with trailing and leading whitespace works |
| { |
| PTREE pt; |
| pt.put_value(T(" \t\n99 \t\n")); |
| BOOST_CHECK(pt.get_value<int>(0) == 99); |
| } |
| |
| } |
| |
| void test_get_child_put_child(PTREE *) |
| { |
| |
| typedef std::basic_string<CHTYPE> str_t; |
| |
| PTREE pt(T("ala ma kota")); |
| |
| // Do insertions via put_child |
| PTREE pt1, pt2, pt3; |
| pt1.put_child(T("k1"), PTREE()); |
| pt1.put_child(T("k2.k"), PTREE()); |
| pt2.put_child(T("k1"), pt); |
| pt2.put_child(T("k2.k"), pt); |
| |
| // Const references to test const versions of methods |
| const PTREE &cpt1 = pt1, &cpt2 = pt2; |
| |
| // Do correct extractions via get_child (throwing version) |
| BOOST_CHECK(pt1.get_child(T("k1")).empty()); |
| BOOST_CHECK(pt1.get_child(T("k2.k")).empty()); |
| BOOST_CHECK(pt2.get_child(T("k1")) == pt); |
| BOOST_CHECK(pt2.get_child(T("k2.k")) == pt); |
| BOOST_CHECK(cpt1.get_child(T("k1")).empty()); |
| BOOST_CHECK(cpt1.get_child(T("k2.k")).empty()); |
| BOOST_CHECK(cpt2.get_child(T("k1")) == pt); |
| BOOST_CHECK(cpt2.get_child(T("k2.k")) == pt); |
| |
| // Do correct extractions via get_child (default value version) |
| BOOST_CHECK(pt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def"))); |
| BOOST_CHECK(pt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def"))); |
| BOOST_CHECK(pt2.get_child(T("k1"), PTREE(T("def"))) == pt); |
| BOOST_CHECK(pt2.get_child(T("k2.k"), PTREE(T("def"))) == pt); |
| BOOST_CHECK(cpt1.get_child(T("k1"), PTREE(T("def"))) != PTREE(T("def"))); |
| BOOST_CHECK(cpt1.get_child(T("k2.k"), PTREE(T("def"))) != PTREE(T("def"))); |
| BOOST_CHECK(cpt2.get_child(T("k1"), PTREE(T("def"))) == pt); |
| BOOST_CHECK(cpt2.get_child(T("k2.k"), PTREE(T("def"))) == pt); |
| |
| // Do correct extractions via get_child (optional version) |
| boost::optional<PTREE &> opt; |
| boost::optional<const PTREE &> copt; |
| opt = pt1.get_child_optional(T("k1")); |
| BOOST_CHECK(opt); |
| opt = pt1.get_child_optional(T("k2.k")); |
| BOOST_CHECK(opt); |
| opt = pt2.get_child_optional(T("k1")); |
| BOOST_CHECK(opt && *opt == pt); |
| opt = pt2.get_child_optional(T("k2.k")); |
| BOOST_CHECK(opt && *opt == pt); |
| copt = cpt1.get_child_optional(T("k1")); |
| BOOST_CHECK(copt); |
| copt = cpt1.get_child_optional(T("k2.k")); |
| BOOST_CHECK(copt); |
| copt = cpt2.get_child_optional(T("k1")); |
| BOOST_CHECK(copt && *copt == pt); |
| copt = cpt2.get_child_optional(T("k2.k")); |
| BOOST_CHECK(copt && *copt == pt); |
| |
| // Do incorrect extractions via get_child (throwing version) |
| try |
| { |
| pt.get_child(T("k2.k.bogus.path")); |
| BOOST_ERROR("No required exception thrown"); |
| } |
| catch (boost::property_tree::ptree_bad_path &) { } |
| catch (...) |
| { |
| BOOST_ERROR("Wrong exception type thrown"); |
| } |
| |
| // Do incorrect extractions via get_child (default value version) |
| BOOST_CHECK(&pt.get_child(T("k2.k.bogus.path"), pt3) == &pt3); |
| |
| // Do incorrect extractions via get_child (optional version) |
| BOOST_CHECK(!pt.get_child_optional(T("k2.k.bogus.path"))); |
| |
| // Test multiple puts with the same key |
| { |
| PTREE pt, tmp1(T("data1")), tmp2(T("data2")); |
| pt.put_child(T("key"), tmp1); |
| BOOST_CHECK(pt.get_child(T("key")) == tmp1); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put_child(T("key"), tmp2); |
| BOOST_CHECK(pt.get_child(T("key")) == tmp2); |
| BOOST_CHECK(pt.size() == 1); |
| pt.put_child(T("key.key.key"), tmp1); |
| PTREE &child = pt.get_child(T("key.key")); |
| BOOST_CHECK(child.size() == 1); |
| pt.put_child(T("key.key.key"), tmp2); |
| BOOST_CHECK(child.size() == 1); |
| } |
| |
| // Test multiple adds with the same key |
| { |
| PTREE pt, tmp1(T("data1")), tmp2(T("data2")); |
| pt.add_child(T("key"), tmp1); |
| BOOST_CHECK(pt.size() == 1); |
| pt.add_child(T("key"), tmp2); |
| BOOST_CHECK(pt.size() == 2); |
| BOOST_CHECK(pt.count(T("key")) == 2); |
| pt.add_child(T("key.key.key"), tmp1); |
| PTREE &child = pt.get_child(T("key.key")); |
| BOOST_CHECK(child.size() == 1); |
| BOOST_CHECK(child.count(T("key")) == 1); |
| pt.add_child(T("key.key.key"), tmp2); |
| BOOST_CHECK(child.size() == 2); |
| BOOST_CHECK(child.count(T("key")) == 2); |
| } |
| |
| // Test assigning child to tree |
| { |
| PTREE pt; |
| pt.put(T("foo.bar"), T("baz")); |
| pt = pt.get_child(T("foo")); |
| BOOST_CHECK(pt.size() == 1); |
| BOOST_CHECK(pt.get< std::basic_string<CHTYPE> >(T("bar")) == T("baz")); |
| } |
| |
| } |
| |
| void test_equal_range(PTREE *) |
| { |
| PTREE pt; |
| pt.add_child(T("k1"), PTREE()); |
| pt.add_child(T("k2"), PTREE()); |
| pt.add_child(T("k1"), PTREE()); |
| pt.add_child(T("k3"), PTREE()); |
| pt.add_child(T("k1"), PTREE()); |
| pt.add_child(T("k2"), PTREE()); |
| |
| BOOST_CHECK(boost::distance(pt.equal_range(T("k1"))) == 3); |
| BOOST_CHECK(boost::distance(pt.equal_range(T("k2"))) == 2); |
| BOOST_CHECK(boost::distance(pt.equal_range(T("k3"))) == 1); |
| } |
| |
| void test_path_separator(PTREE *) |
| { |
| |
| typedef PTREE::path_type path; |
| |
| // Check instances count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 0); |
| |
| // Do insertions |
| PTREE pt; |
| pt.put(T("key1"), T("1")); |
| pt.put(T("key2.key"), T("2")); |
| pt.put(T("key3.key.key"), T("3")); |
| pt.put(path(T("key4"), CHTYPE('/')), T("4")); |
| pt.put(path(T("key5/key"), CHTYPE('/')), T("5")); |
| pt.put(path(T("key6/key/key"), CHTYPE('/')), T("6")); |
| |
| // Check instances count |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 13); |
| |
| // Do correct extractions |
| BOOST_CHECK(pt.get(T("key1"), 0) == 1); |
| BOOST_CHECK(pt.get(T("key2.key"), 0) == 2); |
| BOOST_CHECK(pt.get(T("key3.key.key"), 0) == 3); |
| BOOST_CHECK(pt.get(path(T("key4"), CHTYPE('/')), 0) == 4); |
| BOOST_CHECK(pt.get(path(T("key5/key"), CHTYPE('/')), 0) == 5); |
| BOOST_CHECK(pt.get(path(T("key6/key/key"), CHTYPE('/')), 0) == 6); |
| |
| // Do incorrect extractions |
| BOOST_CHECK(pt.get(T("key2/key"), 0) == 0); |
| BOOST_CHECK(pt.get(T("key3/key/key"), 0) == 0); |
| BOOST_CHECK(pt.get(path(T("key5.key"), CHTYPE('/')), 0) == 0); |
| BOOST_CHECK(pt.get(path(T("key6.key.key"), CHTYPE('/')), 0) == 0); |
| |
| } |
| |
| void test_path(PTREE *) |
| { |
| |
| typedef PTREE::path_type path; |
| |
| // Insert |
| PTREE pt; |
| pt.put(T("key1.key2.key3"), 1); |
| |
| // Test operator /= |
| { |
| path p; |
| p /= T("key1"); p /= T("key2"); p /= T("key3"); |
| BOOST_CHECK(pt.get<int>(p, 0) == 1); |
| } |
| |
| // Test operator /= |
| { |
| path p(T("key1")); |
| p /= T("key2.key3"); |
| BOOST_CHECK(pt.get<int>(p, 0) == 1); |
| } |
| |
| // Test operator /= |
| { |
| path p; |
| path p1(T("key1.key2")); |
| path p2(T("key3")); |
| p /= p1; |
| p /= p2; |
| BOOST_CHECK(pt.get<int>(p, 0) == 1); |
| } |
| |
| // Test operator / |
| { |
| path p = path(T("key1")) / T("key2.key3"); |
| BOOST_CHECK(pt.get<int>(p, 0) == 1); |
| } |
| |
| // Test operator / |
| { |
| path p = T("key1.key2") / path(T("key3")); |
| BOOST_CHECK(pt.get<int>(p, 0) == 1); |
| } |
| |
| } |
| |
| void test_precision(PTREE *) |
| { |
| |
| typedef double real; |
| |
| // Quite precise PI value |
| real pi = real(3.1415926535897932384626433832795028841971); |
| |
| // Put and get |
| PTREE pt; |
| pt.put_value(pi); |
| real pi2 = pt.get_value<real>(); |
| |
| // Test if precision is "good enough", i.e. if stream precision increase worked |
| using namespace std; |
| real error = abs(pi - pi2) * |
| pow(real(numeric_limits<real>::radix), |
| real(numeric_limits<real>::digits)); |
| BOOST_CHECK(error < 100); |
| |
| } |
| |
| void test_locale(PTREE *) |
| { |
| typedef boost::property_tree::translator_between< |
| std::basic_string<CHTYPE>, double>::type translator; |
| try |
| { |
| |
| // Write strings in english and french locales |
| PTREE pt; |
| #ifdef BOOST_WINDOWS |
| std::locale loc_english("english"); |
| std::locale loc_french("french"); |
| #else |
| std::locale loc_english("en_GB"); |
| std::locale loc_french("fr_FR"); |
| #endif |
| pt.put(T("english"), 1.234, translator(loc_english)); |
| pt.put(T("french"), 1.234, translator(loc_french)); |
| |
| // Test contents |
| BOOST_CHECK(pt.get<PTREE::data_type>(T("english")) == T("1.234")); |
| BOOST_CHECK(pt.get<PTREE::data_type>(T("french")) == T("1,234")); |
| |
| } |
| catch (boost::property_tree::ptree_error &) |
| { |
| throw; |
| } |
| catch (std::runtime_error &e) |
| { |
| std::cerr << "Required locale not supported by the platform. " |
| "Skipping locale tests (caught std::runtime_error with message " << |
| e.what() << ").\n"; |
| } |
| |
| } |
| |
| void test_custom_data_type(PTREE *) |
| { |
| |
| typedef std::basic_string<CHTYPE> Str; |
| typedef PTREE::key_compare Comp; |
| typedef PTREE::path_type Path; |
| |
| // Property_tree with boost::any as data type |
| typedef boost::property_tree::basic_ptree<Str, boost::any, Comp> my_ptree; |
| my_ptree pt; |
| |
| // Put/get int value |
| pt.put(T("int value"), 3); |
| int int_value = pt.get<int>(T("int value")); |
| BOOST_CHECK(int_value == 3); |
| |
| // Put/get string value |
| pt.put<std::basic_string<CHTYPE> >(T("string value"), T("foo bar")); |
| std::basic_string<CHTYPE> string_value = pt.get<std::basic_string<CHTYPE> >(T("string value")); |
| BOOST_CHECK(string_value == T("foo bar")); |
| |
| // Put/get list<int> value |
| int list_data[] = { 1, 2, 3, 4, 5 }; |
| pt.put<std::list<int> >(T("list value"), std::list<int>(list_data, list_data + sizeof(list_data) / sizeof(*list_data))); |
| std::list<int> list_value = pt.get<std::list<int> >(T("list value")); |
| BOOST_CHECK(list_value.size() == 5); |
| BOOST_CHECK(list_value.front() == 1); |
| BOOST_CHECK(list_value.back() == 5); |
| |
| } |
| |
| void test_empty_size_max_size(PTREE *) |
| { |
| |
| PTREE pt; |
| BOOST_CHECK(pt.max_size()); |
| BOOST_CHECK(pt.empty()); |
| BOOST_CHECK(pt.size() == 0); |
| |
| pt.put(T("test1"), 1); |
| BOOST_CHECK(pt.max_size()); |
| BOOST_CHECK(!pt.empty()); |
| BOOST_CHECK(pt.size() == 1); |
| |
| pt.put(T("test2"), 2); |
| BOOST_CHECK(pt.max_size()); |
| BOOST_CHECK(!pt.empty()); |
| BOOST_CHECK(pt.size() == 2); |
| |
| } |
| |
| void test_ptree_bad_path(PTREE *) |
| { |
| |
| PTREE pt; |
| |
| try |
| { |
| pt.get<int>(T("non.existent.path")); |
| } |
| catch (boost::property_tree::ptree_bad_path &e) |
| { |
| PTREE::path_type path = e.path<PTREE::path_type>(); |
| std::string what = e.what(); |
| BOOST_CHECK(what.find("non.existent.path") != std::string::npos); |
| return; |
| } |
| |
| BOOST_ERROR("No required exception thrown"); |
| |
| } |
| |
| void test_ptree_bad_data(PTREE *) |
| { |
| |
| PTREE pt; |
| pt.put_value("non convertible to int"); |
| |
| try |
| { |
| pt.get_value<int>(); |
| } |
| catch (boost::property_tree::ptree_bad_data &e) |
| { |
| PTREE::data_type data = e.data<PTREE::data_type>(); |
| std::string what = e.what(); |
| // FIXME: Bring back what translation or make it more clear that it |
| // doesn't work. |
| //BOOST_CHECK(what.find("non convertible to int") != std::string::npos); |
| return; |
| } |
| |
| BOOST_ERROR("No required exception thrown"); |
| } |
| |
| void test_serialization(PTREE *) |
| { |
| |
| // Prepare test tree |
| PTREE pt; |
| pt.put_value(1); |
| pt.put(T("key1"), 3); |
| pt.put(T("key1.key11)"), 3.3); |
| pt.put(T("key1.key12"), T("foo")); |
| pt.put(T("key2"), true); |
| pt.put(T("key2.key21.key211.key2111.key21111"), T("super deep!")); |
| pt.put_child(T("empty"), PTREE()); |
| pt.put(T("loooooong"), PTREE::data_type(10000, CHTYPE('a'))); |
| |
| // Endforce const for input |
| const PTREE &pt1 = pt; |
| |
| // Test text archives |
| { |
| std::stringstream stream; |
| boost::archive::text_oarchive oa(stream); |
| oa & pt1; |
| boost::archive::text_iarchive ia(stream); |
| PTREE pt2; |
| ia & pt2; |
| BOOST_CHECK(pt1 == pt2); |
| } |
| |
| // Test binary archives |
| { |
| std::stringstream stream; |
| boost::archive::binary_oarchive oa(stream); |
| oa & pt1; |
| boost::archive::binary_iarchive ia(stream); |
| PTREE pt2; |
| ia & pt2; |
| BOOST_CHECK(pt1 == pt2); |
| } |
| |
| // Test XML archives |
| { |
| std::stringstream stream; |
| boost::archive::xml_oarchive oa(stream); |
| oa & boost::serialization::make_nvp("pt", pt1); |
| boost::archive::xml_iarchive ia(stream); |
| PTREE pt2; |
| ia & boost::serialization::make_nvp("pt", pt2); |
| BOOST_CHECK(pt1 == pt2); |
| } |
| |
| } |
| |
| void test_bool(PTREE *) |
| { |
| |
| // Prepare test tree |
| PTREE pt; |
| pt.put(T("bool.false.1"), false); |
| pt.put(T("bool.false.2"), T("0")); |
| pt.put(T("bool.true.1"), true); |
| pt.put(T("bool.true.2"), 1); |
| pt.put(T("bool.invalid.1"), T("")); |
| pt.put(T("bool.invalid.2"), T("tt")); |
| pt.put(T("bool.invalid.3"), T("ff")); |
| pt.put(T("bool.invalid.4"), T("2")); |
| pt.put(T("bool.invalid.5"), T("-1")); |
| |
| // Test false |
| for (PTREE::iterator it = pt.get_child(T("bool.false")).begin(); it != pt.get_child(T("bool.false")).end(); ++it) |
| BOOST_CHECK(it->second.get_value<bool>() == false); |
| |
| // Test true |
| for (PTREE::iterator it = pt.get_child(T("bool.true")).begin(); it != pt.get_child(T("bool.true")).end(); ++it) |
| BOOST_CHECK(it->second.get_value<bool>() == true); |
| |
| // Test invalid |
| for (PTREE::iterator it = pt.get_child(T("bool.invalid")).begin(); it != pt.get_child(T("bool.invalid")).end(); ++it) |
| { |
| BOOST_CHECK(it->second.get_value<bool>(false) == false); |
| BOOST_CHECK(it->second.get_value<bool>(true) == true); |
| } |
| |
| } |
| |
| void test_char(PTREE *) |
| { |
| |
| // Prepare test tree |
| PTREE pt; |
| #if WIDECHAR == 0 |
| pt.put(T("char"), char('A')); |
| #endif |
| pt.put(T("signed char"), static_cast<signed char>('A')); |
| pt.put(T("unsigned char"), static_cast<unsigned char>('A')); |
| pt.put(T("signed char min"), (std::numeric_limits<signed char>::min)()); |
| pt.put(T("signed char max"), (std::numeric_limits<signed char>::max)()); |
| pt.put(T("unsigned char min"), (std::numeric_limits<unsigned char>::min)()); |
| pt.put(T("unsigned char max"), (std::numeric_limits<unsigned char>::max)()); |
| |
| // Verify normal conversions |
| #if WIDECHAR == 0 |
| BOOST_CHECK(pt.get<char>(T("char")) == 'A'); |
| #endif |
| BOOST_CHECK(pt.get<signed char>(T("signed char")) == |
| static_cast<signed char>('A')); |
| BOOST_CHECK(pt.get<unsigned char>(T("unsigned char")) == |
| static_cast<unsigned char>('A')); |
| |
| // Verify that numbers are saved for signed and unsigned char |
| BOOST_CHECK(pt.get<int>(T("signed char")) == int('A')); |
| BOOST_CHECK(pt.get<int>(T("unsigned char")) == int('A')); |
| |
| // Verify ranges |
| BOOST_CHECK(pt.get<signed char>(T("signed char min")) == |
| (std::numeric_limits<signed char>::min)()); |
| BOOST_CHECK(pt.get<signed char>(T("signed char max")) == |
| (std::numeric_limits<signed char>::max)()); |
| BOOST_CHECK(pt.get<unsigned char>(T("unsigned char min")) == |
| (std::numeric_limits<unsigned char>::min)()); |
| BOOST_CHECK(pt.get<unsigned char>(T("unsigned char max")) == |
| (std::numeric_limits<unsigned char>::max)()); |
| |
| } |
| |
| void test_leaks(PTREE *) |
| { |
| //BOOST_CHECK(PTREE::debug_get_instances_count() == 0); |
| } |