| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/json/json_value_converter.h" | 5 #include "base/json/json_value_converter.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "base/json/json_reader.h" | 11 #include "base/json/json_reader.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/memory/scoped_vector.h" |
| 13 #include "base/string_piece.h" | 14 #include "base/string_piece.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 16 |
| 16 namespace base { | 17 namespace base { |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 // Very simple messages. | 20 // Very simple messages. |
| 20 struct SimpleMessage { | 21 struct SimpleMessage { |
| 21 enum SimpleEnum { | 22 enum SimpleEnum { |
| 22 FOO, BAR, | 23 FOO, BAR, |
| 23 }; | 24 }; |
| 24 int foo; | 25 int foo; |
| 25 std::string bar; | 26 std::string bar; |
| 26 bool baz; | 27 bool baz; |
| 27 SimpleEnum simple_enum; | 28 SimpleEnum simple_enum; |
| 28 std::vector<int> ints; | 29 ScopedVector<int> ints; |
| 29 SimpleMessage() : foo(0), baz(false) {} | 30 SimpleMessage() : foo(0), baz(false) {} |
| 30 | 31 |
| 31 static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) { | 32 static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) { |
| 32 if (value == "foo") { | 33 if (value == "foo") { |
| 33 *field = FOO; | 34 *field = FOO; |
| 34 return true; | 35 return true; |
| 35 } else if (value == "bar") { | 36 } else if (value == "bar") { |
| 36 *field = BAR; | 37 *field = BAR; |
| 37 return true; | 38 return true; |
| 38 } | 39 } |
| 39 return false; | 40 return false; |
| 40 } | 41 } |
| 41 | 42 |
| 42 static void RegisterJSONConverter( | 43 static void RegisterJSONConverter( |
| 43 base::JSONValueConverter<SimpleMessage>* converter) { | 44 base::JSONValueConverter<SimpleMessage>* converter) { |
| 44 converter->RegisterIntField("foo", &SimpleMessage::foo); | 45 converter->RegisterIntField("foo", &SimpleMessage::foo); |
| 45 converter->RegisterStringField("bar", &SimpleMessage::bar); | 46 converter->RegisterStringField("bar", &SimpleMessage::bar); |
| 46 converter->RegisterBoolField("baz", &SimpleMessage::baz); | 47 converter->RegisterBoolField("baz", &SimpleMessage::baz); |
| 47 converter->RegisterCustomField<SimpleEnum>( | 48 converter->RegisterCustomField<SimpleEnum>( |
| 48 "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum); | 49 "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum); |
| 49 converter->RegisterRepeatedInt("ints", &SimpleMessage::ints); | 50 converter->RegisterRepeatedInt("ints", &SimpleMessage::ints); |
| 50 } | 51 } |
| 51 }; | 52 }; |
| 52 | 53 |
| 53 // For nested messages. | 54 // For nested messages. |
| 54 struct NestedMessage { | 55 struct NestedMessage { |
| 55 double foo; | 56 double foo; |
| 56 SimpleMessage child; | 57 SimpleMessage child; |
| 57 std::vector<SimpleMessage> children; | 58 ScopedVector<SimpleMessage> children; |
| 58 | 59 |
| 59 NestedMessage() : foo(0) {} | 60 NestedMessage() : foo(0) {} |
| 60 | 61 |
| 61 static void RegisterJSONConverter( | 62 static void RegisterJSONConverter( |
| 62 base::JSONValueConverter<NestedMessage>* converter) { | 63 base::JSONValueConverter<NestedMessage>* converter) { |
| 63 converter->RegisterDoubleField("foo", &NestedMessage::foo); | 64 converter->RegisterDoubleField("foo", &NestedMessage::foo); |
| 64 converter->RegisterNestedField("child", &NestedMessage::child); | 65 converter->RegisterNestedField("child", &NestedMessage::child); |
| 65 converter->RegisterRepeatedMessage("children", &NestedMessage::children); | 66 converter->RegisterRepeatedMessage("children", &NestedMessage::children); |
| 66 } | 67 } |
| 67 }; | 68 }; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 81 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); | 82 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); |
| 82 SimpleMessage message; | 83 SimpleMessage message; |
| 83 base::JSONValueConverter<SimpleMessage> converter; | 84 base::JSONValueConverter<SimpleMessage> converter; |
| 84 EXPECT_TRUE(converter.Convert(*value.get(), &message)); | 85 EXPECT_TRUE(converter.Convert(*value.get(), &message)); |
| 85 | 86 |
| 86 EXPECT_EQ(1, message.foo); | 87 EXPECT_EQ(1, message.foo); |
| 87 EXPECT_EQ("bar", message.bar); | 88 EXPECT_EQ("bar", message.bar); |
| 88 EXPECT_TRUE(message.baz); | 89 EXPECT_TRUE(message.baz); |
| 89 EXPECT_EQ(SimpleMessage::FOO, message.simple_enum); | 90 EXPECT_EQ(SimpleMessage::FOO, message.simple_enum); |
| 90 EXPECT_EQ(2, static_cast<int>(message.ints.size())); | 91 EXPECT_EQ(2, static_cast<int>(message.ints.size())); |
| 91 EXPECT_EQ(1, message.ints[0]); | 92 EXPECT_EQ(1, *(message.ints[0])); |
| 92 EXPECT_EQ(2, message.ints[1]); | 93 EXPECT_EQ(2, *(message.ints[1])); |
| 93 } | 94 } |
| 94 | 95 |
| 95 TEST(JSONValueConverterTest, ParseNestedMessage) { | 96 TEST(JSONValueConverterTest, ParseNestedMessage) { |
| 96 const char normal_data[] = | 97 const char normal_data[] = |
| 97 "{\n" | 98 "{\n" |
| 98 " \"foo\": 1.0,\n" | 99 " \"foo\": 1.0,\n" |
| 99 " \"child\": {\n" | 100 " \"child\": {\n" |
| 100 " \"foo\": 1,\n" | 101 " \"foo\": 1,\n" |
| 101 " \"bar\": \"bar\",\n" | 102 " \"bar\": \"bar\",\n" |
| 102 " \"baz\": true\n" | 103 " \"baz\": true\n" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 117 NestedMessage message; | 118 NestedMessage message; |
| 118 base::JSONValueConverter<NestedMessage> converter; | 119 base::JSONValueConverter<NestedMessage> converter; |
| 119 EXPECT_TRUE(converter.Convert(*value.get(), &message)); | 120 EXPECT_TRUE(converter.Convert(*value.get(), &message)); |
| 120 | 121 |
| 121 EXPECT_EQ(1.0, message.foo); | 122 EXPECT_EQ(1.0, message.foo); |
| 122 EXPECT_EQ(1, message.child.foo); | 123 EXPECT_EQ(1, message.child.foo); |
| 123 EXPECT_EQ("bar", message.child.bar); | 124 EXPECT_EQ("bar", message.child.bar); |
| 124 EXPECT_TRUE(message.child.baz); | 125 EXPECT_TRUE(message.child.baz); |
| 125 | 126 |
| 126 EXPECT_EQ(2, static_cast<int>(message.children.size())); | 127 EXPECT_EQ(2, static_cast<int>(message.children.size())); |
| 127 const SimpleMessage& first_child = message.children[0]; | 128 const SimpleMessage* first_child = message.children[0]; |
| 128 EXPECT_EQ(2, first_child.foo); | 129 ASSERT_TRUE(first_child); |
| 129 EXPECT_EQ("foobar", first_child.bar); | 130 EXPECT_EQ(2, first_child->foo); |
| 130 EXPECT_TRUE(first_child.baz); | 131 EXPECT_EQ("foobar", first_child->bar); |
| 132 EXPECT_TRUE(first_child->baz); |
| 131 | 133 |
| 132 const SimpleMessage& second_child = message.children[1]; | 134 const SimpleMessage* second_child = message.children[1]; |
| 133 EXPECT_EQ(3, second_child.foo); | 135 ASSERT_TRUE(second_child); |
| 134 EXPECT_EQ("barbaz", second_child.bar); | 136 EXPECT_EQ(3, second_child->foo); |
| 135 EXPECT_FALSE(second_child.baz); | 137 EXPECT_EQ("barbaz", second_child->bar); |
| 138 EXPECT_FALSE(second_child->baz); |
| 136 } | 139 } |
| 137 | 140 |
| 138 TEST(JSONValueConverterTest, ParseFailures) { | 141 TEST(JSONValueConverterTest, ParseFailures) { |
| 139 const char normal_data[] = | 142 const char normal_data[] = |
| 140 "{\n" | 143 "{\n" |
| 141 " \"foo\": 1,\n" | 144 " \"foo\": 1,\n" |
| 142 " \"bar\": 2,\n" // "bar" is an integer here. | 145 " \"bar\": 2,\n" // "bar" is an integer here. |
| 143 " \"baz\": true,\n" | 146 " \"baz\": true,\n" |
| 144 " \"ints\": [1, 2]" | 147 " \"ints\": [1, 2]" |
| 145 "}\n"; | 148 "}\n"; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 162 | 165 |
| 163 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); | 166 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); |
| 164 SimpleMessage message; | 167 SimpleMessage message; |
| 165 base::JSONValueConverter<SimpleMessage> converter; | 168 base::JSONValueConverter<SimpleMessage> converter; |
| 166 // Convert() still succeeds even if the input doesn't have "bar" field. | 169 // Convert() still succeeds even if the input doesn't have "bar" field. |
| 167 EXPECT_TRUE(converter.Convert(*value.get(), &message)); | 170 EXPECT_TRUE(converter.Convert(*value.get(), &message)); |
| 168 | 171 |
| 169 EXPECT_EQ(1, message.foo); | 172 EXPECT_EQ(1, message.foo); |
| 170 EXPECT_TRUE(message.baz); | 173 EXPECT_TRUE(message.baz); |
| 171 EXPECT_EQ(2, static_cast<int>(message.ints.size())); | 174 EXPECT_EQ(2, static_cast<int>(message.ints.size())); |
| 172 EXPECT_EQ(1, message.ints[0]); | 175 EXPECT_EQ(1, *(message.ints[0])); |
| 173 EXPECT_EQ(2, message.ints[1]); | 176 EXPECT_EQ(2, *(message.ints[1])); |
| 174 } | 177 } |
| 175 | 178 |
| 176 TEST(JSONValueConverterTest, EnumParserFails) { | 179 TEST(JSONValueConverterTest, EnumParserFails) { |
| 177 const char normal_data[] = | 180 const char normal_data[] = |
| 178 "{\n" | 181 "{\n" |
| 179 " \"foo\": 1,\n" | 182 " \"foo\": 1,\n" |
| 180 " \"bar\": \"bar\",\n" | 183 " \"bar\": \"bar\",\n" |
| 181 " \"baz\": true,\n" | 184 " \"baz\": true,\n" |
| 182 " \"simple_enum\": \"baz\"," | 185 " \"simple_enum\": \"baz\"," |
| 183 " \"ints\": [1, 2]" | 186 " \"ints\": [1, 2]" |
| 184 "}\n"; | 187 "}\n"; |
| 185 | 188 |
| 186 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); | 189 scoped_ptr<Value> value(base::JSONReader::Read(normal_data, false)); |
| 187 SimpleMessage message; | 190 SimpleMessage message; |
| 188 base::JSONValueConverter<SimpleMessage> converter; | 191 base::JSONValueConverter<SimpleMessage> converter; |
| 189 EXPECT_FALSE(converter.Convert(*value.get(), &message)); | 192 EXPECT_FALSE(converter.Convert(*value.get(), &message)); |
| 190 // No check the values as mentioned above. | 193 // No check the values as mentioned above. |
| 191 } | 194 } |
| 192 | 195 |
| 193 } // namespace base | 196 } // namespace base |
| OLD | NEW |