test_ini_parser.cpp 5.3 KB

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