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.
5 #include "base/json/json_value_converter.h"
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"
20 // Very simple messages.
21 struct SimpleMessage
{
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
) {}
34 static bool ParseSimpleEnum(const StringPiece
& value
, SimpleEnum
* field
) {
38 } else if (value
== "bar") {
45 static bool HasFieldPresent(const base::Value
* value
, bool* result
) {
46 *result
= value
!= NULL
;
50 static bool GetValueString(const base::Value
* value
, std::string
* result
) {
51 const base::DictionaryValue
* dict
= NULL
;
52 if (!value
->GetAsDictionary(&dict
))
55 if (!dict
->GetString("val", result
))
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
,
72 converter
->RegisterRepeatedCustomValue
<std::string
>(
74 &SimpleMessage::string_values
,
79 // For nested messages.
80 struct NestedMessage
{
83 ScopedVector
<SimpleMessage
> children
;
85 NestedMessage() : foo(0) {}
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
);
97 TEST(JSONValueConverterTest
, ParseSimpleMessage
) {
98 const char normal_data
[] =
101 " \"bar\": \"bar\",\n"
103 " \"bstruct\": {},\n"
104 " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
105 " \"simple_enum\": \"foo\","
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
));
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]));
126 TEST(JSONValueConverterTest
, ParseNestedMessage
) {
127 const char normal_data
[] =
132 " \"bar\": \"bar\",\n"
133 " \"bstruct\": {},\n"
134 " \"string_values\": [{\"val\": \"value_1\"}, {\"val\": \"value_2\"}],"
137 " \"children\": [{\n"
139 " \"bar\": \"foobar\",\n"
140 " \"bstruct\": \"\",\n"
141 " \"string_values\": [{\"val\": \"value_1\"}],"
146 " \"bar\": \"barbaz\",\n"
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
));
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]);
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]);
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());
184 TEST(JSONValueConverterTest
, ParseFailures
) {
185 const char normal_data
[] =
188 " \"bar\": 2,\n" // "bar" is an integer here.
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.
201 TEST(JSONValueConverterTest
, ParseWithMissingFields
) {
202 const char normal_data
[] =
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
));
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]));
222 TEST(JSONValueConverterTest
, EnumParserFails
) {
223 const char normal_data
[] =
226 " \"bar\": \"bar\",\n"
228 " \"simple_enum\": \"baz\","
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.
239 TEST(JSONValueConverterTest
, RepeatedValueErrorInTheMiddle
) {
240 const char normal_data
[] =
243 " \"bar\": \"bar\",\n"
245 " \"simple_enum\": \"baz\","
246 " \"ints\": [1, false]"
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.