util_stp_settings_parser.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. /*!
  8. * \file setup_settings_parser.cpp
  9. * \author Andrey Semashev
  10. * \date 25.08.2013
  11. *
  12. * \brief This header contains tests for the settings parser.
  13. */
  14. #define BOOST_TEST_MODULE setup_settings_parser
  15. #include <string>
  16. #include <sstream>
  17. #include <boost/test/unit_test.hpp>
  18. #include <boost/log/utility/setup/settings_parser.hpp>
  19. #if !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)
  20. #include <boost/log/exceptions.hpp>
  21. namespace logging = boost::log;
  22. typedef logging::basic_settings< char > settings;
  23. // Tests for single-level settings
  24. BOOST_AUTO_TEST_CASE(single_level)
  25. {
  26. {
  27. std::istringstream strm
  28. (
  29. "[Section1]\n"
  30. "\n"
  31. "Param1 = Value1\n"
  32. "Param2 = \"hello, \\\"world\\\"\"\n"
  33. "\n"
  34. "[Section2]\n"
  35. "\n"
  36. "Param1 = 10\n"
  37. "Param2 = -2.2\n"
  38. );
  39. settings s = logging::parse_settings(strm);
  40. BOOST_CHECK(s.has_section("Section1"));
  41. BOOST_CHECK(s.has_section("Section2"));
  42. BOOST_CHECK(!s.has_section("Section3"));
  43. BOOST_CHECK(s.has_parameter("Section1", "Param1"));
  44. BOOST_CHECK(s.has_parameter("Section1", "Param2"));
  45. BOOST_CHECK(s.has_parameter("Section2", "Param1"));
  46. BOOST_CHECK(s.has_parameter("Section2", "Param2"));
  47. BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
  48. BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
  49. BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
  50. BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
  51. }
  52. }
  53. // Tests for multi-level settings
  54. BOOST_AUTO_TEST_CASE(multi_level)
  55. {
  56. {
  57. std::istringstream strm
  58. (
  59. " [Section1]\n"
  60. "\n"
  61. "Param1 = Value1 \n"
  62. "Param2=\"hello, \\\"world\\\"\" \n"
  63. "\n"
  64. "[Section1.Subsection2] \n"
  65. "\n"
  66. "Param1=10\n"
  67. "Param2=-2.2\n"
  68. );
  69. settings s = logging::parse_settings(strm);
  70. BOOST_CHECK(s.has_section("Section1"));
  71. BOOST_CHECK(s.has_section("Section1.Subsection2"));
  72. BOOST_CHECK(!s.has_section("Subsection2"));
  73. BOOST_CHECK(s.has_parameter("Section1", "Param1"));
  74. BOOST_CHECK(s.has_parameter("Section1", "Param2"));
  75. BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param1"));
  76. BOOST_CHECK(s.has_parameter("Section1.Subsection2", "Param2"));
  77. BOOST_CHECK(!s.has_parameter("Subsection2", "Param1"));
  78. BOOST_CHECK(!s.has_parameter("Subsection2", "Param2"));
  79. BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
  80. BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
  81. BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param1"].or_default(std::string()), "10");
  82. BOOST_CHECK_EQUAL(s["Section1.Subsection2"]["Param2"].or_default(std::string()), "-2.2");
  83. }
  84. }
  85. // Tests for comments
  86. BOOST_AUTO_TEST_CASE(comments)
  87. {
  88. {
  89. std::istringstream strm
  90. (
  91. "# Some comment\n"
  92. "[ Section1 ] # another comment\n"
  93. "\n"
  94. "Param1 = Value1 ### yet another comment \n"
  95. "Param2=\"hello, \\\"world\\\"\" # comment after a quoted string\n"
  96. "\n"
  97. "[ Section2 ]\n"
  98. "\n"
  99. "Param1=10#comment after a number\n"
  100. "Param2=-2.2#comment without a terminating newline"
  101. "\n"
  102. "#[Section3]\n"
  103. "#\n"
  104. "#Param1=10#comment after a number\n"
  105. "#Param2=-2.2#comment without a terminating newline"
  106. );
  107. settings s = logging::parse_settings(strm);
  108. BOOST_CHECK(s.has_section("Section1"));
  109. BOOST_CHECK(s.has_section("Section2"));
  110. BOOST_CHECK(!s.has_section("Section3"));
  111. BOOST_CHECK(s.has_parameter("Section1", "Param1"));
  112. BOOST_CHECK(s.has_parameter("Section1", "Param2"));
  113. BOOST_CHECK(s.has_parameter("Section2", "Param1"));
  114. BOOST_CHECK(s.has_parameter("Section2", "Param2"));
  115. BOOST_CHECK_EQUAL(s["Section1"]["Param1"].or_default(std::string()), "Value1");
  116. BOOST_CHECK_EQUAL(s["Section1"]["Param2"].or_default(std::string()), "hello, \"world\"");
  117. BOOST_CHECK_EQUAL(s["Section2"]["Param1"].or_default(std::string()), "10");
  118. BOOST_CHECK_EQUAL(s["Section2"]["Param2"].or_default(std::string()), "-2.2");
  119. }
  120. }
  121. // Tests for invalid settings
  122. BOOST_AUTO_TEST_CASE(invalid)
  123. {
  124. {
  125. std::istringstream strm
  126. (
  127. "Param1 = Value1\n" // parameters outside sections
  128. "Param2 = \"hello, \\\"world\\\"\"\n"
  129. );
  130. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  131. }
  132. {
  133. std::istringstream strm
  134. (
  135. "[Section1\n" // missing closing brace
  136. "\n"
  137. "Param1 = Value1\n"
  138. "Param2 = \"hello, \\\"world\\\"\"\n"
  139. "\n"
  140. "[Section2]\n"
  141. "\n"
  142. "Param1 = 10\n"
  143. "Param2 = -2.2\n"
  144. );
  145. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  146. }
  147. {
  148. std::istringstream strm
  149. (
  150. "Section1]\n" // missing opening brace
  151. "\n"
  152. "Param1 = Value1\n"
  153. "Param2 = \"hello, \\\"world\\\"\"\n"
  154. "\n"
  155. "[Section2]\n"
  156. "\n"
  157. "Param1 = 10\n"
  158. "Param2 = -2.2\n"
  159. );
  160. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  161. }
  162. {
  163. std::istringstream strm
  164. (
  165. "[Section1=xyz]\n" // invalid characters in the section name
  166. "\n"
  167. "Param1 = Value1\n"
  168. "Param2 = \"hello, \\\"world\\\"\"\n"
  169. "\n"
  170. "[Section2]\n"
  171. "\n"
  172. "Param1 = 10\n"
  173. "Param2 = -2.2\n"
  174. );
  175. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  176. }
  177. {
  178. std::istringstream strm
  179. (
  180. "[Section1# hello?]\n" // invalid characters in the section name
  181. "\n"
  182. "Param1 = Value1\n"
  183. "Param2 = \"hello, \\\"world\\\"\"\n"
  184. "\n"
  185. "[Section2]\n"
  186. "\n"
  187. "Param1 = 10\n"
  188. "Param2 = -2.2\n"
  189. );
  190. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  191. }
  192. {
  193. std::istringstream strm
  194. (
  195. "(Section1)\n" // invalid braces
  196. "\n"
  197. "Param1 = Value1\n"
  198. "Param2 = \"hello, \\\"world\\\"\"\n"
  199. "\n"
  200. "[Section2]\n"
  201. "\n"
  202. "Param1 = 10\n"
  203. "Param2 = -2.2\n"
  204. );
  205. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  206. }
  207. {
  208. std::istringstream strm
  209. (
  210. "[Section1]\n"
  211. "\n"
  212. "Param1 =\n" // no parameter value
  213. "Param2 = \"hello, \\\"world\\\"\"\n"
  214. "\n"
  215. "[Section2]\n"
  216. "\n"
  217. "Param1 = 10\n"
  218. "Param2 = -2.2\n"
  219. );
  220. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  221. }
  222. {
  223. std::istringstream strm
  224. (
  225. "[Section1]\n"
  226. "\n"
  227. "Param1\n" // no parameter value
  228. "Param2 = \"hello, \\\"world\\\"\"\n"
  229. "\n"
  230. "[Section2]\n"
  231. "\n"
  232. "Param1 = 10\n"
  233. "Param2 = -2.2\n"
  234. );
  235. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  236. }
  237. {
  238. std::istringstream strm
  239. (
  240. "[Section1]\n"
  241. "\n"
  242. "Param1 = Value1\n"
  243. "Param2 = \"hello, \\\"world\\\"\n" // unterminated quote
  244. "\n"
  245. "[Section2]\n"
  246. "\n"
  247. "Param1 = 10\n"
  248. "Param2 = -2.2\n"
  249. );
  250. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  251. }
  252. {
  253. std::istringstream strm
  254. (
  255. "[Section1]\n"
  256. "\n"
  257. "Param1 = Value1 Value2\n" // multi-word value
  258. "Param2 = \"hello, \\\"world\\\"\"\n"
  259. "\n"
  260. "[Section2]\n"
  261. "\n"
  262. "Param1 = 10\n"
  263. "Param2 = -2.2\n"
  264. );
  265. BOOST_CHECK_THROW(logging::parse_settings(strm), logging::parse_error);
  266. }
  267. }
  268. #endif // !defined(BOOST_LOG_WITHOUT_SETTINGS_PARSERS)