1// ----------------------------------------------------------------------------
2// Copyright (C) 2002-2006 Marcin Kalicinski
3//
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7//
8// For more information, see www.boost.org
9// ----------------------------------------------------------------------------
10
11#include "test_utils.hpp"
12#include <boost/property_tree/ini_parser.hpp>
13#include <sstream>
14
15using namespace boost::property_tree;
16
17///////////////////////////////////////////////////////////////////////////////
18// Test data
19
20// Correct data
21const char *ok_data_1 =
22 "\n"
23 "; Comment\n"
24 "[Section1]\n"
25 "\t \t; Comment\n"
26 " Key1=Data1\n"
27 " \n"
28 " Key2 = Data2\n"
29 "Key 3 = Data 3 \n"
30 "Key4=Data4\n"
31 "[Section2] ;Comment\n"
32 "\t \tKey1=Data4\n";
33
34// Correct data
35const char *ok_data_2 =
36 "[Section1]\n"
37 "Key1=Data1"; // No eol
38
39// Correct data
40const char *ok_data_3 =
41 "";
42
43// Correct data
44const char *ok_data_4 =
45 ";Comment";
46
47// Correct data
48const char *ok_data_5 =
49 "Key1=Data1\n" // No section
50 "Key2=Data2\n";
51
52// Treat # as comment.
53const char *ok_data_6 =
54 "# Comment\n"
55 "[Section1]\n"
56 "Key1=Data1\n";
57
58// Erroneous data
59const char *error_data_1 =
60 "[Section1]\n"
61 "Key1\n" // No equals sign
62 "Key2=Data2";
63
64// Erroneous data
65const char *error_data_2 =
66 "[Section1]\n"
67 "Key1=Data1\n"
68 "=Data2\n"; // No key
69
70struct ReadFunc
71{
72 template<class Ptree>
73 void operator()(const std::string &filename, Ptree &pt) const
74 {
75 read_ini(filename, pt);
76 }
77};
78
79struct WriteFunc
80{
81 template<class Ptree>
82 void operator()(const std::string &filename, const Ptree &pt) const
83 {
84 write_ini(filename, pt);
85 }
86};
87
88void test_erroneous_write(const boost::property_tree::ptree &pt)
89{
90 std::stringstream stream;
91 try
92 {
93 write_ini(stream, pt);
94 BOOST_ERROR("No required exception thrown");
95 }
96 catch (ini_parser_error &e)
97 {
98 (void)e;
99 }
100 catch (...)
101 {
102 BOOST_ERROR("Wrong exception type thrown");
103 }
104}
105
106template<class Ptree>
107void test_ini_parser()
108{
109 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
110 (
111 ReadFunc(), WriteFunc(), ok_data_1, NULL,
112 "testok1.ini", NULL, "testok1out.ini", 8, 26, 37
113 );
114
115 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
116 (
117 ReadFunc(), WriteFunc(), ok_data_2, NULL,
118 "testok2.ini", NULL, "testok2out.ini", 3, 5, 12
119 );
120
121 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
122 (
123 ReadFunc(), WriteFunc(), ok_data_3, NULL,
124 "testok3.ini", NULL, "testok3out.ini", 1, 0, 0
125 );
126
127 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
128 (
129 ReadFunc(), WriteFunc(), ok_data_4, NULL,
130 "testok4.ini", NULL, "testok4out.ini", 1, 0, 0
131 );
132
133 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
134 (
135 ReadFunc(), WriteFunc(), ok_data_5, NULL,
136 "testok5.ini", NULL, "testok5out.ini", 3, 10, 8
137 );
138
139 generic_parser_test_ok<Ptree, ReadFunc, WriteFunc>
140 (
141 ReadFunc(), WriteFunc(), ok_data_6, NULL,
142 "testok6.ini", NULL, "testok6out.ini", 3, 5, 12
143 );
144
145 generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
146 (
147 ReadFunc(), WriteFunc(), error_data_1, NULL,
148 "testerr1.ini", NULL, "testerr1out.ini", 2
149 );
150
151 generic_parser_test_error<Ptree, ReadFunc, WriteFunc, ini_parser_error>
152 (
153 ReadFunc(), WriteFunc(), error_data_2, NULL,
154 "testerr2.ini", NULL, "testerr2out.ini", 3
155 );
156}
157
158void test_unmappable_trees()
159{
160 // Test too deep ptrees
161 {
162 ptree pt;
163 pt.put_child(path: "section.key.bogus", value: ptree());
164 test_erroneous_write(pt);
165 }
166
167 // Test duplicate sections
168 {
169 ptree pt;
170 pt.push_back(value: std::make_pair(x: "section", y: ptree()));
171 pt.push_back(value: std::make_pair(x: "section", y: ptree()));
172 test_erroneous_write(pt);
173 }
174
175 // Test duplicate keys
176 {
177 ptree pt;
178 ptree &child = pt.put_child(path: "section", value: ptree());
179 child.push_back(value: std::make_pair(x: "key", y: ptree()));
180 child.push_back(value: std::make_pair(x: "key", y: ptree()));
181 test_erroneous_write(pt);
182 }
183
184 // Test mixed data and children.
185 {
186 ptree pt;
187 ptree &child = pt.put_child(path: "section", value: ptree("value"));
188 child.push_back(value: std::make_pair(x: "key", y: ptree()));
189 child.push_back(value: std::make_pair(x: "key", y: ptree()));
190 test_erroneous_write(pt);
191 }
192}
193
194void test_other_trees()
195{
196 // Top-level keys must be written before any section.
197 {
198 ptree pt;
199 pt.put(path: "section.innerkey", value: "v1");
200 pt.put(path: "nosection", value: "v2");
201 std::stringstream s;
202 write_ini(stream&: s, pt);
203 s.clear();
204 s.seekg(0, std::ios_base::beg);
205 ptree result;
206 read_ini(stream&: s, pt&: result);
207 BOOST_TEST(result.get("section.innerkey", "bad") == "v1");
208 BOOST_TEST(result.get("nosection", "bad") == "v2");
209 }
210}
211
212int main()
213{
214 test_ini_parser<ptree>();
215 test_ini_parser<iptree>();
216#ifndef BOOST_NO_CWCHAR
217 test_ini_parser<wptree>();
218 test_ini_parser<wiptree>();
219#endif
220
221 test_unmappable_trees();
222 test_other_trees();
223
224 return boost::report_errors();
225
226}
227

source code of boost/libs/property_tree/test/test_ini_parser.cpp