Chromium Code Reviews| Index: base/json/json_value_converter_unittest.cc |
| diff --git a/base/json/json_value_converter_unittest.cc b/base/json/json_value_converter_unittest.cc |
| index 925fd5cdda3b3b4a8bdf83fd6585acb1b9e1883e..722ef3952bd6d4ceadcc52ac38db0c82bcb0b5fb 100644 |
| --- a/base/json/json_value_converter_unittest.cc |
| +++ b/base/json/json_value_converter_unittest.cc |
| @@ -29,6 +29,9 @@ struct SimpleMessage { |
| SimpleEnum simple_enum; |
| ScopedVector<int> ints; |
| ScopedVector<std::string> string_values; |
| + std::string conditional; |
| + std::string email_href; |
| + std::string home_href; |
|
Jun Mukai
2012/05/30 23:51:10
Can you define another struct for custom actions?
|
| SimpleMessage() : foo(0), baz(false), bstruct(false) {} |
| static bool ParseSimpleEnum(const StringPiece& value, SimpleEnum* field) { |
| @@ -58,6 +61,44 @@ struct SimpleMessage { |
| return true; |
| } |
| + // Inspects the passed-in DictionaryValue's "use" field. If true, copies the |
| + // "value" field to the message's |conditional| member. |
| + static bool HandleConditionalField(const base::Value* value, |
| + SimpleMessage* object) { |
| + const base::DictionaryValue* dict = NULL; |
| + if (!value->GetAsDictionary(&dict)) |
| + return false; |
| + |
| + bool use = false; |
| + std::string string_value; |
| + if (!dict->GetBoolean("use", &use) || |
| + !dict->GetString("value", &string_value)) { |
| + return false; |
| + } |
| + if (use) |
| + object->conditional = string_value; |
| + return true; |
| + } |
| + |
| + // Inspects the passed-in DictionaryValue's "type" field and uses it to |
| + // determine which of the message's members should store the "href" field. |
| + static bool HandleUrl(const base::Value* value, SimpleMessage* object) { |
| + const base::DictionaryValue* dict = NULL; |
| + if (!value->GetAsDictionary(&dict)) |
| + return false; |
| + |
| + std::string type, href; |
| + if (!dict->GetString("type", &type) || !dict->GetString("href", &href)) |
| + return false; |
| + |
| + if (type == "email") |
| + object->email_href = href; |
| + else if (type == "home") |
| + object->home_href = href; |
| + |
| + return true; |
| + } |
| + |
| static void RegisterJSONConverter( |
| base::JSONValueConverter<SimpleMessage>* converter) { |
| converter->RegisterIntField("foo", &SimpleMessage::foo); |
| @@ -73,6 +114,8 @@ struct SimpleMessage { |
| "string_values", |
| &SimpleMessage::string_values, |
| &GetValueString); |
| + converter->RegisterCustomAction("conditional", &HandleConditionalField); |
| + converter->RegisterRepeatedCustomAction("url", &HandleUrl); |
| } |
| }; |
| @@ -253,4 +296,80 @@ TEST(JSONValueConverterTest, RepeatedValueErrorInTheMiddle) { |
| // No check the values as mentioned above. |
| } |
| +TEST(JSONValueConverterTest, CustomAction) { |
| + // The handler for the "conditional" field checks if the nested dictionary's |
| + // "use" field is true and copies its "value" parameter if so. |
| + const char kUsableData[] = |
| + "{\n" |
| + " \"conditional\": {\n" |
| + " \"use\": true,\n" |
| + " \"value\": \"foo\"\n" |
| + " }\n" |
| + "}\n"; |
| + scoped_ptr<Value> value(base::JSONReader::Read(kUsableData)); |
| + SimpleMessage usable_message; |
| + base::JSONValueConverter<SimpleMessage> converter; |
| + EXPECT_TRUE(converter.Convert(*value.get(), &usable_message)); |
| + EXPECT_EQ("foo", usable_message.conditional); |
| + |
| + const char kUnusableData[] = |
| + "{\n" |
| + " \"conditional\": {\n" |
| + " \"use\": false,\n" |
| + " \"value\": \"foo\"\n" |
| + " }\n" |
| + "}\n"; |
| + value.reset(base::JSONReader::Read(kUnusableData)); |
| + SimpleMessage non_usable_message; |
| + EXPECT_TRUE(converter.Convert(*value.get(), &non_usable_message)); |
| + EXPECT_EQ("", non_usable_message.conditional); |
| + |
| + // If we pass data that makes the custom handler return false (a missing "use" |
| + // field, in this case), conversion should fail. |
| + const char kBrokenData[] = |
| + "{\n" |
| + " \"conditional\": {\n" |
| + " \"value\": \"foo\"\n" |
| + " }\n" |
| + "}\n"; |
| + value.reset(base::JSONReader::Read(kBrokenData)); |
| + SimpleMessage broken_message; |
| + EXPECT_FALSE(converter.Convert(*value.get(), &broken_message)); |
| +} |
| + |
| +TEST(JSONValueConverterTest, RepeatedCustomAction) { |
| + const char kData[] = |
| + "{\n" |
| + " \"url\": [\n" |
| + " {\"type\": \"search\",\n" |
| + " \"href\": \"http://www.google.com/\"},\n" |
| + " {\"type\": \"home\",\n" |
| + " \"href\": \"http://www.example.org/\"},\n" |
| + " {\"type\": \"email\",\n" |
| + " \"href\": \"mailto:me@example.org\"}\n" |
| + " ]\n" |
| + "}\n"; |
| + scoped_ptr<Value> value(base::JSONReader::Read(kData)); |
| + SimpleMessage message; |
| + base::JSONValueConverter<SimpleMessage> converter; |
| + EXPECT_TRUE(converter.Convert(*value.get(), &message)); |
| + EXPECT_EQ("mailto:me@example.org", message.email_href); |
| + EXPECT_EQ("http://www.example.org/", message.home_href); |
| + |
| + // If we pass data that makes the custom handler return false (a missing |
| + // "type" field for one of the entries, in this case), conversion should fail. |
| + const char kBrokenData[] = |
| + "{\n" |
| + " \"url\": [\n" |
| + " {\"type\": \"search\",\n" |
| + " \"href\": \"http://www.google.com/\"},\n" |
| + " {\"href\": \"http://www.example.org/\"},\n" |
| + " {\"type\": \"email\",\n" |
| + " \"href\": \"mailto:me@example.org\"}\n" |
| + " ]\n" |
| + "}\n"; |
| + value.reset(base::JSONReader::Read(kBrokenData)); |
| + EXPECT_FALSE(converter.Convert(*value.get(), &message)); |
| +} |
| + |
| } // namespace base |