Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: base/json/json_value_converter_unittest.cc

Issue 10440101: ABANDONED: Update base::JSONValueConverter to support custom actions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 11 matching lines...) Expand all
22 enum SimpleEnum { 22 enum SimpleEnum {
23 FOO, BAR, 23 FOO, BAR,
24 }; 24 };
25 int foo; 25 int foo;
26 std::string bar; 26 std::string bar;
27 bool baz; 27 bool baz;
28 bool bstruct; 28 bool bstruct;
29 SimpleEnum simple_enum; 29 SimpleEnum simple_enum;
30 ScopedVector<int> ints; 30 ScopedVector<int> ints;
31 ScopedVector<std::string> string_values; 31 ScopedVector<std::string> string_values;
32 std::string conditional;
33 std::string email_href;
34 std::string home_href;
32 SimpleMessage() : foo(0), baz(false), bstruct(false) {} 35 SimpleMessage() : foo(0), baz(false), bstruct(false) {}
33 36
34 static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) { 37 static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) {
35 if (value == "foo") { 38 if (value == "foo") {
36 *field = FOO; 39 *field = FOO;
37 return true; 40 return true;
38 } else if (value == "bar") { 41 } else if (value == "bar") {
39 *field = BAR; 42 *field = BAR;
40 return true; 43 return true;
41 } 44 }
42 return false; 45 return false;
43 } 46 }
44 47
45 static bool HasFieldPresent(const base::Value* value, bool* result) { 48 static bool HasFieldPresent(const base::Value* value, bool* result) {
46 *result = value != NULL; 49 *result = value != NULL;
47 return true; 50 return true;
48 } 51 }
49 52
50 static bool GetValueString(const base::Value* value, std::string* result) { 53 static bool GetValueString(const base::Value* value, std::string* result) {
51 const base::DictionaryValue* dict = NULL; 54 const base::DictionaryValue* dict = NULL;
52 if (!value->GetAsDictionary(&dict)) 55 if (!value->GetAsDictionary(&dict))
53 return false; 56 return false;
54 57
55 if (!dict->GetString("val", result)) 58 if (!dict->GetString("val", result))
56 return false; 59 return false;
57 60
58 return true; 61 return true;
59 } 62 }
60 63
64 // Inspects the passed-in DictionaryValue's "use" field. If true, copies the
65 // "value" field to the message's |conditional| member.
66 static bool HandleConditionalField(const base::Value* value,
67 SimpleMessage* object) {
68 const base::DictionaryValue* dict = NULL;
69 if (!value->GetAsDictionary(&dict))
70 return false;
71
72 bool use = false;
73 std::string string_value;
74 if (!dict->GetBoolean("use", &use) ||
75 !dict->GetString("value", &string_value)) {
76 return false;
77 }
78 if (use)
79 object->conditional = string_value;
80 return true;
81 }
82
83 // Inspects the passed-in DictionaryValue's "type" field and uses it to
84 // determine which of the message's members should store the "href" field.
85 static bool HandleUrl(const base::Value* value, SimpleMessage* object) {
86 const base::DictionaryValue* dict = NULL;
87 if (!value->GetAsDictionary(&dict))
88 return false;
89
90 std::string type, href;
91 if (!dict->GetString("type", &type) || !dict->GetString("href", &href))
92 return false;
93
94 if (type == "email")
95 object->email_href = href;
96 else if (type == "home")
97 object->home_href = href;
98
99 return true;
100 }
101
61 static void RegisterJSONConverter( 102 static void RegisterJSONConverter(
62 base::JSONValueConverter<SimpleMessage>* converter) { 103 base::JSONValueConverter<SimpleMessage>* converter) {
63 converter->RegisterIntField("foo", &SimpleMessage::foo); 104 converter->RegisterIntField("foo", &SimpleMessage::foo);
64 converter->RegisterStringField("bar", &SimpleMessage::bar); 105 converter->RegisterStringField("bar", &SimpleMessage::bar);
65 converter->RegisterBoolField("baz", &SimpleMessage::baz); 106 converter->RegisterBoolField("baz", &SimpleMessage::baz);
66 converter->RegisterCustomField<SimpleEnum>( 107 converter->RegisterCustomField<SimpleEnum>(
67 "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum); 108 "simple_enum", &SimpleMessage::simple_enum, &ParseSimpleEnum);
68 converter->RegisterRepeatedInt("ints", &SimpleMessage::ints); 109 converter->RegisterRepeatedInt("ints", &SimpleMessage::ints);
69 converter->RegisterCustomValueField<bool>("bstruct", 110 converter->RegisterCustomValueField<bool>("bstruct",
70 &SimpleMessage::bstruct, 111 &SimpleMessage::bstruct,
71 &HasFieldPresent); 112 &HasFieldPresent);
72 converter->RegisterRepeatedCustomValue<std::string>( 113 converter->RegisterRepeatedCustomValue<std::string>(
73 "string_values", 114 "string_values",
74 &SimpleMessage::string_values, 115 &SimpleMessage::string_values,
75 &GetValueString); 116 &GetValueString);
117 converter->RegisterCustomAction("conditional", &HandleConditionalField);
118 converter->RegisterRepeatedCustomAction("url", &HandleUrl);
76 } 119 }
77 }; 120 };
78 121
79 // For nested messages. 122 // For nested messages.
80 struct NestedMessage { 123 struct NestedMessage {
81 double foo; 124 double foo;
82 SimpleMessage child; 125 SimpleMessage child;
83 ScopedVector<SimpleMessage> children; 126 ScopedVector<SimpleMessage> children;
84 127
85 NestedMessage() : foo(0) {} 128 NestedMessage() : foo(0) {}
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 " \"ints\": [1, false]" 289 " \"ints\": [1, false]"
247 "}\n"; 290 "}\n";
248 291
249 scoped_ptr<Value> value(base::JSONReader::Read(normal_data)); 292 scoped_ptr<Value> value(base::JSONReader::Read(normal_data));
250 SimpleMessage message; 293 SimpleMessage message;
251 base::JSONValueConverter<SimpleMessage> converter; 294 base::JSONValueConverter<SimpleMessage> converter;
252 EXPECT_FALSE(converter.Convert(*value.get(), &message)); 295 EXPECT_FALSE(converter.Convert(*value.get(), &message));
253 // No check the values as mentioned above. 296 // No check the values as mentioned above.
254 } 297 }
255 298
299 TEST(JSONValueConverterTest, CustomAction) {
300 // The handler for the "conditional" field checks if the nested dictionary's
301 // "use" field is true and copies its "value" parameter if so.
302 const char usable_data[] =
303 "{\n"
304 " \"conditional\": {\n"
305 " \"use\": true,\n"
306 " \"value\": \"foo\"\n"
307 " }\n"
308 "}\n";
309 scoped_ptr<Value> value(base::JSONReader::Read(usable_data));
310 SimpleMessage usable_message;
311 base::JSONValueConverter<SimpleMessage> converter;
312 EXPECT_TRUE(converter.Convert(*value.get(), &usable_message));
313 EXPECT_EQ("foo", usable_message.conditional);
314
315 const char non_usable_data[] =
316 "{\n"
317 " \"conditional\": {\n"
318 " \"use\": false,\n"
319 " \"value\": \"foo\"\n"
320 " }\n"
321 "}\n";
322 value.reset(base::JSONReader::Read(non_usable_data));
323 SimpleMessage non_usable_message;
324 EXPECT_TRUE(converter.Convert(*value.get(), &non_usable_message));
325 EXPECT_EQ("", non_usable_message.conditional);
326
327 // If we pass data that makes the custom handler return false (a missing "use"
328 // field, in this case), conversion should fail.
329 const char broken_data[] =
330 "{\n"
331 " \"conditional\": {\n"
332 " \"value\": \"foo\"\n"
333 " }\n"
334 "}\n";
335 value.reset(base::JSONReader::Read(broken_data));
336 SimpleMessage broken_message;
337 EXPECT_FALSE(converter.Convert(*value.get(), &broken_message));
338 }
339
340 TEST(JSONValueConverterTest, RepeatedCustomAction) {
341 const char data[] =
342 "{\n"
343 " \"url\": [\n"
344 " {\"type\": \"search\",\n"
345 " \"href\": \"http://www.google.com/\"},\n"
346 " {\"type\": \"home\",\n"
347 " \"href\": \"http://www.example.org/\"},\n"
348 " {\"type\": \"email\",\n"
349 " \"href\": \"mailto:me@example.org\"}\n"
350 " ]\n"
351 "}\n";
352 scoped_ptr<Value> value(base::JSONReader::Read(data));
353 SimpleMessage message;
354 base::JSONValueConverter<SimpleMessage> converter;
355 EXPECT_TRUE(converter.Convert(*value.get(), &message));
356 EXPECT_EQ("mailto:me@example.org", message.email_href);
357 EXPECT_EQ("http://www.example.org/", message.home_href);
358
359 // If we pass data that makes the custom handler return false (a missing
360 // "type" field for one of the entries, in this case), conversion should fail.
361 const char broken_data[] =
362 "{\n"
363 " \"url\": [\n"
364 " {\"type\": \"search\",\n"
365 " \"href\": \"http://www.google.com/\"},\n"
366 " {\"href\": \"http://www.example.org/\"},\n"
367 " {\"type\": \"email\",\n"
368 " \"href\": \"mailto:me@example.org\"}\n"
369 " ]\n"
370 "}\n";
371 value.reset(base::JSONReader::Read(broken_data));
372 EXPECT_FALSE(converter.Convert(*value.get(), &message));
373 }
374
256 } // namespace base 375 } // namespace base
OLDNEW
« base/json/json_value_converter.h ('K') | « base/json/json_value_converter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698