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