unit-convenience.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++ (supporting code)
  3. // | | |__ | | | | | | version 3.11.2
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #include "doctest_compatibility.h"
  9. #define JSON_TESTS_PRIVATE
  10. #include <nlohmann/json.hpp>
  11. using nlohmann::json;
  12. #include <sstream>
  13. namespace
  14. {
  15. struct alt_string_iter
  16. {
  17. alt_string_iter() = default;
  18. alt_string_iter(const char* cstr)
  19. : impl(cstr)
  20. {}
  21. void reserve(std::size_t s)
  22. {
  23. impl.reserve(s);
  24. }
  25. template<typename Iter>
  26. void append(Iter first, Iter last)
  27. {
  28. impl.append(first, last);
  29. }
  30. std::string::const_iterator begin() const
  31. {
  32. return impl.begin();
  33. }
  34. std::string::const_iterator end() const
  35. {
  36. return impl.end();
  37. }
  38. std::size_t size() const
  39. {
  40. return impl.size();
  41. }
  42. alt_string_iter& operator+=(const char c)
  43. {
  44. impl += c;
  45. return *this;
  46. }
  47. std::string impl{};
  48. };
  49. struct alt_string_data
  50. {
  51. alt_string_data() = default;
  52. alt_string_data(const char* cstr)
  53. : impl(cstr)
  54. {}
  55. void reserve(std::size_t s)
  56. {
  57. impl.reserve(s);
  58. }
  59. void append(const char* p, std::size_t s)
  60. {
  61. impl.append(p, s);
  62. }
  63. const char* data() const
  64. {
  65. return impl.data();
  66. }
  67. std::size_t size() const
  68. {
  69. return impl.size();
  70. }
  71. alt_string_data& operator+=(const char c)
  72. {
  73. impl += c;
  74. return *this;
  75. }
  76. std::string impl{};
  77. };
  78. void check_escaped(const char* original, const char* escaped = "", bool ensure_ascii = false);
  79. void check_escaped(const char* original, const char* escaped, const bool ensure_ascii)
  80. {
  81. std::stringstream ss;
  82. json::serializer s(nlohmann::detail::output_adapter<char>(ss), ' ');
  83. s.dump_escaped(original, ensure_ascii);
  84. CHECK(ss.str() == escaped);
  85. }
  86. } // namespace
  87. TEST_CASE("convenience functions")
  88. {
  89. SECTION("type name as string")
  90. {
  91. CHECK(std::string(json(json::value_t::null).type_name()) == "null");
  92. CHECK(std::string(json(json::value_t::object).type_name()) == "object");
  93. CHECK(std::string(json(json::value_t::array).type_name()) == "array");
  94. CHECK(std::string(json(json::value_t::number_integer).type_name()) == "number");
  95. CHECK(std::string(json(json::value_t::number_unsigned).type_name()) == "number");
  96. CHECK(std::string(json(json::value_t::number_float).type_name()) == "number");
  97. CHECK(std::string(json(json::value_t::binary).type_name()) == "binary");
  98. CHECK(std::string(json(json::value_t::boolean).type_name()) == "boolean");
  99. CHECK(std::string(json(json::value_t::string).type_name()) == "string");
  100. CHECK(std::string(json(json::value_t::discarded).type_name()) == "discarded");
  101. }
  102. SECTION("string escape")
  103. {
  104. check_escaped("\"", "\\\"");
  105. check_escaped("\\", "\\\\");
  106. check_escaped("\b", "\\b");
  107. check_escaped("\f", "\\f");
  108. check_escaped("\n", "\\n");
  109. check_escaped("\r", "\\r");
  110. check_escaped("\t", "\\t");
  111. check_escaped("\x01", "\\u0001");
  112. check_escaped("\x02", "\\u0002");
  113. check_escaped("\x03", "\\u0003");
  114. check_escaped("\x04", "\\u0004");
  115. check_escaped("\x05", "\\u0005");
  116. check_escaped("\x06", "\\u0006");
  117. check_escaped("\x07", "\\u0007");
  118. check_escaped("\x08", "\\b");
  119. check_escaped("\x09", "\\t");
  120. check_escaped("\x0a", "\\n");
  121. check_escaped("\x0b", "\\u000b");
  122. check_escaped("\x0c", "\\f");
  123. check_escaped("\x0d", "\\r");
  124. check_escaped("\x0e", "\\u000e");
  125. check_escaped("\x0f", "\\u000f");
  126. check_escaped("\x10", "\\u0010");
  127. check_escaped("\x11", "\\u0011");
  128. check_escaped("\x12", "\\u0012");
  129. check_escaped("\x13", "\\u0013");
  130. check_escaped("\x14", "\\u0014");
  131. check_escaped("\x15", "\\u0015");
  132. check_escaped("\x16", "\\u0016");
  133. check_escaped("\x17", "\\u0017");
  134. check_escaped("\x18", "\\u0018");
  135. check_escaped("\x19", "\\u0019");
  136. check_escaped("\x1a", "\\u001a");
  137. check_escaped("\x1b", "\\u001b");
  138. check_escaped("\x1c", "\\u001c");
  139. check_escaped("\x1d", "\\u001d");
  140. check_escaped("\x1e", "\\u001e");
  141. check_escaped("\x1f", "\\u001f");
  142. // invalid UTF-8 characters
  143. CHECK_THROWS_WITH_AS(check_escaped("ä\xA9ü"), "[json.exception.type_error.316] invalid UTF-8 byte at index 2: 0xA9", json::type_error&);
  144. CHECK_THROWS_WITH_AS(check_escaped("\xC2"), "[json.exception.type_error.316] incomplete UTF-8 string; last byte: 0xC2", json::type_error&);
  145. }
  146. SECTION("string concat")
  147. {
  148. using nlohmann::detail::concat;
  149. const char* expected = "Hello, world!";
  150. alt_string_iter const hello_iter{"Hello, "};
  151. alt_string_data const hello_data{"Hello, "};
  152. std::string const world = "world";
  153. SECTION("std::string")
  154. {
  155. std::string str1 = concat(hello_iter, world, '!');
  156. std::string str2 = concat(hello_data, world, '!');
  157. std::string str3 = concat("Hello, ", world, '!');
  158. CHECK(str1 == expected);
  159. CHECK(str2 == expected);
  160. CHECK(str3 == expected);
  161. }
  162. SECTION("alt_string_iter")
  163. {
  164. alt_string_iter str = concat<alt_string_iter>(hello_iter, world, '!');
  165. CHECK(str.impl == expected);
  166. }
  167. SECTION("alt_string_data")
  168. {
  169. alt_string_data str = concat<alt_string_data>(hello_data, world, '!');
  170. CHECK(str.impl == expected);
  171. }
  172. }
  173. }