json_value_converter_unittest.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/json/json_value_converter.h"
  5. #include <memory>
  6. #include <string>
  7. #include <vector>
  8. #include "base/json/json_reader.h"
  9. #include "base/strings/string_piece.h"
  10. #include "base/values.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. namespace base {
  14. namespace {
  15. // Very simple messages.
  16. struct SimpleMessage {
  17. enum SimpleEnum {
  18. FOO,
  19. BAR,
  20. };
  21. int foo;
  22. std::string bar;
  23. bool baz;
  24. bool bstruct;
  25. SimpleEnum simple_enum;
  26. std::vector<std::unique_ptr<int>> ints;
  27. std::vector<std::unique_ptr<std::string>> string_values;
  28. SimpleMessage() : foo(0), baz(false), bstruct(false), simple_enum(FOO) {}
  29. static bool ParseSimpleEnum(StringPiece value, SimpleEnum* field) {
  30. if (value == "foo") {
  31. *field = FOO;
  32. return true;
  33. }
  34. if (value == "bar") {
  35. *field = BAR;
  36. return true;
  37. }
  38. return false;
  39. }
  40. static bool HasFieldPresent(const base::Value* value, bool* result) {
  41. *result = value != nullptr;
  42. return true;
  43. }
  44. static bool GetValueString(const base::Value* value, std::string* result) {
  45. const Value::Dict* dict = value->GetIfDict();
  46. if (!dict)
  47. return false;
  48. const std::string* str = dict->FindString("val");
  49. if (!str)
  50. return false;
  51. if (result)
  52. *result = *str;
  53. return true;
  54. }
  55. static void RegisterJSONConverter(
  56. base::JSONValueConverter<SimpleMessage>* converter) {
  57. converter->RegisterIntField("foo", &SimpleMessage::foo);
  58. converter->RegisterStringField("bar", &SimpleMessage::bar);
  59. converter->RegisterBoolField("baz", &SimpleMessage::baz);
  60. converter->RegisterCustomField<SimpleEnum>(
  61. "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum);
  62. converter->RegisterRepeatedInt("ints", &SimpleMessage::ints);
  63. converter->RegisterCustomValueField<bool>(
  64. "bstruct", &SimpleMessage::bstruct, &HasFieldPresent);
  65. converter->RegisterRepeatedCustomValue<std::string>(
  66. "string_values", &SimpleMessage::string_values, &GetValueString);
  67. }
  68. };
  69. // For nested messages.
  70. struct NestedMessage {
  71. double foo;
  72. SimpleMessage child;
  73. std::vector<std::unique_ptr<SimpleMessage>> children;
  74. NestedMessage() : foo(0) {}
  75. static void RegisterJSONConverter(
  76. base::JSONValueConverter<NestedMessage>* converter) {
  77. converter->RegisterDoubleField("foo", &NestedMessage::foo);
  78. converter->RegisterNestedField("child", &NestedMessage::child);
  79. converter->RegisterRepeatedMessage("children", &NestedMessage::children);
  80. }
  81. };
  82. } // namespace
  83. TEST(JSONValueConverterTest, ParseSimpleMessage) {
  84. const char normal_data[] =
  85. "{\n"
  86. " \"foo\": 1,\n"
  87. " \"bar\": \"bar\",\n"
  88. " \"baz\": true,\n"
  89. " \"bstruct\": {},\n"
  90. " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
  91. " \"simple_enum\": \"foo\","
  92. " \"ints\": [1, 2]"
  93. "}\n";
  94. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  95. ASSERT_TRUE(value);
  96. SimpleMessage message;
  97. base::JSONValueConverter<SimpleMessage> converter;
  98. EXPECT_TRUE(converter.Convert(*value, &message));
  99. EXPECT_EQ(1, message.foo);
  100. EXPECT_EQ("bar", message.bar);
  101. EXPECT_TRUE(message.baz);
  102. EXPECT_EQ(SimpleMessage::FOO, message.simple_enum);
  103. EXPECT_EQ(2, static_cast<int>(message.ints.size()));
  104. ASSERT_EQ(2U, message.string_values.size());
  105. EXPECT_EQ("value_1", *message.string_values[0]);
  106. EXPECT_EQ("value_2", *message.string_values[1]);
  107. EXPECT_EQ(1, *(message.ints[0]));
  108. EXPECT_EQ(2, *(message.ints[1]));
  109. }
  110. TEST(JSONValueConverterTest, ParseNestedMessage) {
  111. const char normal_data[] =
  112. "{\n"
  113. " \"foo\": 1.0,\n"
  114. " \"child\": {\n"
  115. " \"foo\": 1,\n"
  116. " \"bar\": \"bar\",\n"
  117. " \"bstruct\": {},\n"
  118. " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
  119. " \"baz\": true\n"
  120. " },\n"
  121. " \"children\": [{\n"
  122. " \"foo\": 2,\n"
  123. " \"bar\": \"foobar\",\n"
  124. " \"bstruct\": \"\",\n"
  125. " \"string_values\": [{\"val\": \"value_1\"}],"
  126. " \"baz\": true\n"
  127. " },\n"
  128. " {\n"
  129. " \"foo\": 3,\n"
  130. " \"bar\": \"barbaz\",\n"
  131. " \"baz\": false\n"
  132. " }]\n"
  133. "}\n";
  134. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  135. ASSERT_TRUE(value);
  136. NestedMessage message;
  137. base::JSONValueConverter<NestedMessage> converter;
  138. EXPECT_TRUE(converter.Convert(*value, &message));
  139. EXPECT_EQ(1.0, message.foo);
  140. EXPECT_EQ(1, message.child.foo);
  141. EXPECT_EQ("bar", message.child.bar);
  142. EXPECT_TRUE(message.child.baz);
  143. EXPECT_TRUE(message.child.bstruct);
  144. ASSERT_EQ(2U, message.child.string_values.size());
  145. EXPECT_EQ("value_1", *message.child.string_values[0]);
  146. EXPECT_EQ("value_2", *message.child.string_values[1]);
  147. EXPECT_EQ(2, static_cast<int>(message.children.size()));
  148. const SimpleMessage* first_child = message.children[0].get();
  149. ASSERT_TRUE(first_child);
  150. EXPECT_EQ(2, first_child->foo);
  151. EXPECT_EQ("foobar", first_child->bar);
  152. EXPECT_TRUE(first_child->baz);
  153. EXPECT_TRUE(first_child->bstruct);
  154. ASSERT_EQ(1U, first_child->string_values.size());
  155. EXPECT_EQ("value_1", *first_child->string_values[0]);
  156. const SimpleMessage* second_child = message.children[1].get();
  157. ASSERT_TRUE(second_child);
  158. EXPECT_EQ(3, second_child->foo);
  159. EXPECT_EQ("barbaz", second_child->bar);
  160. EXPECT_FALSE(second_child->baz);
  161. EXPECT_FALSE(second_child->bstruct);
  162. EXPECT_EQ(0U, second_child->string_values.size());
  163. }
  164. TEST(JSONValueConverterTest, ParseFailures) {
  165. const char normal_data[] =
  166. "{\n"
  167. " \"foo\": 1,\n"
  168. " \"bar\": 2,\n" // "bar" is an integer here.
  169. " \"baz\": true,\n"
  170. " \"ints\": [1, 2]"
  171. "}\n";
  172. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  173. ASSERT_TRUE(value);
  174. SimpleMessage message;
  175. base::JSONValueConverter<SimpleMessage> converter;
  176. EXPECT_FALSE(converter.Convert(*value, &message));
  177. // Do not check the values below. |message| may be modified during
  178. // Convert() even it fails.
  179. }
  180. TEST(JSONValueConverterTest, ParseWithMissingFields) {
  181. const char normal_data[] =
  182. "{\n"
  183. " \"foo\": 1,\n"
  184. " \"baz\": true,\n"
  185. " \"ints\": [1, 2]"
  186. "}\n";
  187. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  188. ASSERT_TRUE(value);
  189. SimpleMessage message;
  190. base::JSONValueConverter<SimpleMessage> converter;
  191. // Convert() still succeeds even if the input doesn't have "bar" field.
  192. EXPECT_TRUE(converter.Convert(*value, &message));
  193. EXPECT_EQ(1, message.foo);
  194. EXPECT_TRUE(message.baz);
  195. EXPECT_EQ(2, static_cast<int>(message.ints.size()));
  196. EXPECT_EQ(1, *(message.ints[0]));
  197. EXPECT_EQ(2, *(message.ints[1]));
  198. }
  199. TEST(JSONValueConverterTest, EnumParserFails) {
  200. const char normal_data[] =
  201. "{\n"
  202. " \"foo\": 1,\n"
  203. " \"bar\": \"bar\",\n"
  204. " \"baz\": true,\n"
  205. " \"simple_enum\": \"baz\","
  206. " \"ints\": [1, 2]"
  207. "}\n";
  208. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  209. ASSERT_TRUE(value);
  210. SimpleMessage message;
  211. base::JSONValueConverter<SimpleMessage> converter;
  212. EXPECT_FALSE(converter.Convert(*value, &message));
  213. // No check the values as mentioned above.
  214. }
  215. TEST(JSONValueConverterTest, RepeatedValueErrorInTheMiddle) {
  216. const char normal_data[] =
  217. "{\n"
  218. " \"foo\": 1,\n"
  219. " \"bar\": \"bar\",\n"
  220. " \"baz\": true,\n"
  221. " \"simple_enum\": \"baz\","
  222. " \"ints\": [1, false]"
  223. "}\n";
  224. absl::optional<Value> value = base::JSONReader::Read(normal_data);
  225. ASSERT_TRUE(value);
  226. SimpleMessage message;
  227. base::JSONValueConverter<SimpleMessage> converter;
  228. EXPECT_FALSE(converter.Convert(*value, &message));
  229. // No check the values as mentioned above.
  230. }
  231. } // namespace base