test_conversion.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "library/cpp/json/converter/converter.h"
  2. #include <library/cpp/json/json_reader.h>
  3. #include <library/cpp/json/json_writer.h>
  4. #include "library/cpp/json/writer/json_value.h"
  5. #include <library/cpp/testing/unittest/registar.h>
  6. #include <util/generic/array_ref.h>
  7. #include <util/generic/deque.h>
  8. #include <util/generic/hash.h>
  9. #include <util/generic/list.h>
  10. #include <util/generic/map.h>
  11. #include <util/generic/maybe.h>
  12. namespace NJson {
  13. void AssertJsonsEqual(const TJsonValue& actualJson, const TJsonValue& expectedJson) {
  14. const auto actualString = WriteJson(actualJson, /*formatOutput*/ true, /*sortkeys*/ true, /*validateUtf8*/ true);
  15. const auto expectedString = WriteJson(expectedJson, /*formatOutput*/ true, /*sortkeys*/ true, /*validateUtf8*/ true);
  16. UNIT_ASSERT_NO_DIFF(actualString, expectedString);
  17. }
  18. void AssertJsonsEqual(const TJsonValue& actualJson, TStringBuf expectedString) {
  19. const auto expectedJson = ReadJsonFastTree(expectedString);
  20. AssertJsonsEqual(actualJson, expectedJson);
  21. }
  22. template<typename T>
  23. struct TConverterTester {
  24. using TValues = THashMap<TStringBuf, T>;
  25. static void TestEncoding(const TValues& values) {
  26. for (const auto& [serializedValue, value] : values) {
  27. {
  28. const auto encodedValue = TConverter<T>::Encode(value);
  29. AssertJsonsEqual(encodedValue, serializedValue);
  30. }
  31. }
  32. }
  33. static void TestDecoding(const TValues& values) {
  34. for (const auto& [serializedValue, value] : values) {
  35. {
  36. const auto decodedValue = TConverter<T>::Decode(ReadJsonFastTree(serializedValue));
  37. UNIT_ASSERT_EQUAL(decodedValue, value);
  38. }
  39. }
  40. }
  41. static void TestDecodingException(TStringBuf serializedValue) {
  42. try {
  43. TConverter<T>::Decode(ReadJsonFastTree(serializedValue));
  44. UNIT_ASSERT(false);
  45. } catch (...) {
  46. }
  47. }
  48. static void Test(const TValues& values) {
  49. TestEncoding(values);
  50. TestDecoding(values);
  51. for (const auto& [serializedValue, value] : values) {
  52. {
  53. const auto encodedValue = TConverter<T>::Encode(value);
  54. const auto decodedValue = TConverter<T>::Decode(encodedValue);
  55. UNIT_ASSERT_EQUAL(value, decodedValue);
  56. }
  57. }
  58. }
  59. };
  60. template<typename T>
  61. requires std::is_floating_point_v<T>
  62. struct TConverterTester<T> {
  63. using TValues = THashMap<TStringBuf, T>;
  64. static void TestDecoding(const TValues& values) {
  65. for (const auto& [serializedValue, value] : values) {
  66. {
  67. const auto decodedValue = TConverter<T>::Decode(ReadJsonFastTree(serializedValue));
  68. UNIT_ASSERT_DOUBLES_EQUAL(decodedValue, value, 0.000001);
  69. }
  70. }
  71. }
  72. static void Test(const TValues& values) {
  73. TestDecoding(values);
  74. for (const auto& [serializedValue, value] : values) {
  75. {
  76. const auto encodedValue = TConverter<T>::Encode(value);
  77. const auto decodedValue = TConverter<T>::Decode(encodedValue);
  78. UNIT_ASSERT_DOUBLES_EQUAL(decodedValue, value, 0.000001);
  79. }
  80. }
  81. }
  82. };
  83. Y_UNIT_TEST_SUITE(ConversionTests) {
  84. Y_UNIT_TEST(PrimitivesTest) {
  85. TConverterTester<bool>::Test({{"true", true}, {"false", false}});
  86. TConverterTester<ui8>::Test({{"0", 0}, {"255", 255}});
  87. TConverterTester<i8>::Test({{"-128", -128}, {"127", 127}});
  88. TConverterTester<ui16>::Test({{"0", 0}, {"65535", 65535}});
  89. TConverterTester<i16>::Test({{"-32768", -32768}, {"32767", 32767}});
  90. TConverterTester<ui32>::Test({{"0", 0}, {"4294967295", 4294967295}});
  91. TConverterTester<i32>::Test({{"-2147483648", -2147483648}, {"2147483647", 2147483647}});
  92. TConverterTester<ui64>::Test({{"0", 0}, {"18446744073709551615", 18446744073709551615u}});
  93. TConverterTester<i64>::Test({
  94. {"-9223372036854775808", -9223372036854775808u},
  95. {"9223372036854775807", 9223372036854775807},
  96. });
  97. TConverterTester<i8>::TestDecodingException("128");
  98. TConverterTester<i8>::TestDecodingException("-129");
  99. TConverterTester<ui8>::TestDecodingException("256");
  100. TConverterTester<i16>::TestDecodingException("32768");
  101. TConverterTester<i16>::TestDecodingException("-32769");
  102. TConverterTester<ui16>::TestDecodingException("65536");
  103. TConverterTester<i32>::TestDecodingException("-2147483649");
  104. TConverterTester<i32>::TestDecodingException("2147483649");
  105. TConverterTester<ui32>::TestDecodingException("4294967296");
  106. TConverterTester<unsigned char>::Test({{"0", 0}, {"255", 255}});
  107. TConverterTester<signed char>::Test({{"-128", -128}, {"127", 127}});
  108. TConverterTester<unsigned short int>::Test({{"0", 0}, {"65535", 65535}});
  109. TConverterTester<signed short int>::Test({{"-32768", -32768}, {"32767", 32767}});
  110. TConverterTester<unsigned int>::Test({{"0", 0}, {"65535", 65535}});
  111. TConverterTester<signed int>::Test({{"-32768", -32768}, {"32767", 32767}});
  112. TConverterTester<unsigned long int>::Test({{"0", 0}, {"4294967295", 4294967295}});
  113. TConverterTester<signed long int>::Test({{"-2147483648", -2147483648}, {"2147483647", 2147483647}});
  114. TConverterTester<unsigned long long int>::Test({{"0", 0}, {"18446744073709551615", 18446744073709551615u}});
  115. TConverterTester<signed long long int>::Test({
  116. {"-9223372036854775808", -9223372036854775808u},
  117. {"9223372036854775807", 9223372036854775807},
  118. });
  119. TConverterTester<size_t>::Test({{"0", 0}, {"65535", 65535}});
  120. TConverterTester<float>::Test({{"-1.12312", -1.12312}, {"3434.25674", 3434.25674}});
  121. TConverterTester<double>::Test({{"-1.12312E+42", -1.12312E+42}, {"3.25E+120", 3.25E+120}});
  122. }
  123. Y_UNIT_TEST(StringsTest) {
  124. TConverterTester<TStringBuf>::TestEncoding({
  125. {R"("Let's permit using of Rust in Arcadia")", "Let's permit using of Rust in Arcadia"},
  126. });
  127. TConverterTester<TString>::Test({
  128. {
  129. R"("Всякое непрерывное отображение замкнутого n-мерного шара в себя обладает неподвижной точкой")",
  130. "Всякое непрерывное отображение замкнутого n-мерного шара в себя обладает неподвижной точкой",
  131. },
  132. });
  133. }
  134. Y_UNIT_TEST(MaybeTest) {
  135. TConverterTester<TMaybe<bool>>::Test({
  136. {"true", TMaybe<bool>(true)},
  137. {"null", Nothing()},
  138. {"false", TMaybe<bool>(false)},
  139. });
  140. }
  141. Y_UNIT_TEST(ArraysTest) {
  142. TConverterTester<TVector<bool>>::Test({{"[true, true, false]", {true, true, false}}});
  143. TConverterTester<TList<TString>>::Test({{R"(["a", "b"])", {"a", "b"}}});
  144. TConverterTester<TDeque<bool>>::Test({{"[false, true, false]", {false, true, false}}});
  145. }
  146. Y_UNIT_TEST(MapsTest) {
  147. TConverterTester<THashMap<TStringBuf, bool>>::TestEncoding({
  148. {R"({"a": true, "b": false})", {{"a", true}, {"b", false}}},
  149. });
  150. TConverterTester<THashMap<TString, bool>>::Test({
  151. {R"({"a": true, "b": false})", {{"a", true}, {"b", false}}},
  152. });
  153. TConverterTester<TMap<TStringBuf, TStringBuf>>::TestEncoding({
  154. {R"({"a": "A", "b": "B"})", {{"a", "A"}, {"b", "B"}}},
  155. });
  156. TConverterTester<TMap<TString, TString>>::Test({
  157. {R"({"a": "A", "b": "B"})", {{"a", "A"}, {"b", "B"}}},
  158. });
  159. }
  160. Y_UNIT_TEST(NestedTest) {
  161. TConverterTester<TVector<THashMap<TString, TVector<ui64>>>>::Test({
  162. {
  163. R"([
  164. {
  165. "Three": [0, 1, 2],
  166. "Five": [0, 1, 2, 3, 4]
  167. },
  168. {
  169. "Four": [0, 1, 2, 3],
  170. "Six": [0, 1, 2, 3, 4, 5]
  171. },
  172. ])",
  173. {
  174. {
  175. {"Three", {0, 1, 2}},
  176. {"Five", {0, 1, 2, 3, 4}},
  177. },
  178. {
  179. {"Four", {0, 1, 2, 3}},
  180. {"Six", {0, 1, 2, 3, 4, 5}},
  181. },
  182. },
  183. },
  184. });
  185. }
  186. }
  187. }