property_tree/test/test_ini_parser.cpp

227 lines
5.3 KiB
C++

// ----------------------------------------------------------------------------
// 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
// ----------------------------------------------------------------------------
#include "test_utils.hpp"
#include <boost/property_tree/ini_parser.hpp>
#include <sstream>
using namespace boost::property_tree;
///////////////////////////////////////////////////////////////////////////////
// Test data
// Correct data
const char *ok_data_1 =
"\n"
"; Comment\n"
"[Section1]\n"
"\t \t; Comment\n"
" Key1=Data1\n"
" \n"
" Key2 = Data2\n"
"Key 3 = Data 3 \n"
"Key4=Data4\n"
"[Section2] ;Comment\n"
"\t \tKey1=Data4\n";
// Correct data
const char *ok_data_2 =
"[Section1]\n"
"Key1=Data1"; // No eol
// Correct data
const char *ok_data_3 =
"";
// Correct data
const char *ok_data_4 =
";Comment";
// Correct data
const char *ok_data_5 =
"Key1=Data1\n" // No section
"Key2=Data2\n";
// Treat # as comment.
const char *ok_data_6 =
"# Comment\n"
"[Section1]\n"
"Key1=Data1\n";
// Erroneous data
const char *error_data_1 =
"[Section1]\n"
"Key1\n" // No equals sign
"Key2=Data2";
// Erroneous data
const char *error_data_2 =
"[Section1]\n"
"Key1=Data1\n"
"=Data2\n"; // No key
struct ReadFunc
{
template<class Ptree>
void operator()(const std::string &filename, Ptree &pt) const
{
read_ini(filename, pt);
}
};
struct WriteFunc
{
template<class Ptree>
void operator()(const std::string &filename, const Ptree &pt) const
{
write_ini(filename, pt);
}
};
void test_erroneous_write(const boost::property_tree::ptree &pt)
{
std::stringstream stream;
try
{
write_ini(stream, pt);
BOOST_ERROR("No required exception thrown");
}
catch (ini_parser_error &e)
{
(void)e;
}
catch (...)
{
BOOST_ERROR("Wrong exception type thrown");
}
}
template<class Ptree>
void test_ini_parser()
{
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_1, NULL,
"testok1.ini", NULL, "testok1out.ini", 8, 26, 37
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_2, NULL,
"testok2.ini", NULL, "testok2out.ini", 3, 5, 12
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_3, NULL,
"testok3.ini", NULL, "testok3out.ini", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_4, NULL,
"testok4.ini", NULL, "testok4out.ini", 1, 0, 0
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_5, NULL,
"testok5.ini", NULL, "testok5out.ini", 3, 10, 8
);
generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
(
ReadFunc(), WriteFunc(), ok_data_6, NULL,
"testok6.ini", NULL, "testok6out.ini", 3, 5, 12
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
(
ReadFunc(), WriteFunc(), error_data_1, NULL,
"testerr1.ini", NULL, "testerr1out.ini", 2
);
generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
(
ReadFunc(), WriteFunc(), error_data_2, NULL,
"testerr2.ini", NULL, "testerr2out.ini", 3
);
}
void test_unmappable_trees()
{
// Test too deep ptrees
{
ptree pt;
pt.put_child("section.key.bogus", ptree());
test_erroneous_write(pt);
}
// Test duplicate sections
{
ptree pt;
pt.push_back(std::make_pair("section", ptree()));
pt.push_back(std::make_pair("section", ptree()));
test_erroneous_write(pt);
}
// Test duplicate keys
{
ptree pt;
ptree &child = pt.put_child("section", ptree());
child.push_back(std::make_pair("key", ptree()));
child.push_back(std::make_pair("key", ptree()));
test_erroneous_write(pt);
}
// Test mixed data and children.
{
ptree pt;
ptree &child = pt.put_child("section", ptree("value"));
child.push_back(std::make_pair("key", ptree()));
child.push_back(std::make_pair("key", ptree()));
test_erroneous_write(pt);
}
}
void test_other_trees()
{
// Top-level keys must be written before any section.
{
ptree pt;
pt.put("section.innerkey", "v1");
pt.put("nosection", "v2");
std::stringstream s;
write_ini(s, pt);
s.clear();
s.seekg(0, std::ios_base::beg);
ptree result;
read_ini(s, result);
BOOST_CHECK(result.get("section.innerkey", "bad") == "v1");
BOOST_CHECK(result.get("nosection", "bad") == "v2");
}
}
int test_main(int argc, char *argv[])
{
test_ini_parser<ptree>();
test_ini_parser<iptree>();
#ifndef BOOST_NO_CWCHAR
test_ini_parser<wptree>();
test_ini_parser<wiptree>();
#endif
test_unmappable_trees();
test_other_trees();
return 0;
}