| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/json/json_file_value_serializer.h" | 9 #include "base/json/json_file_value_serializer.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/json/json_string_value_serializer.h" | 11 #include "base/json/json_string_value_serializer.h" |
| 12 #include "base/json/json_writer.h" | 12 #include "base/json/json_writer.h" |
| 13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
| 14 #include "base/path_service.h" | 14 #include "base/path_service.h" |
| 15 #include "base/strings/string_piece.h" |
| 15 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 17 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/values.h" | 18 #include "base/values.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 20 |
| 20 namespace base { | 21 namespace base { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 // Some proper JSON to test with: | 25 // Some proper JSON to test with: |
| (...skipping 10 matching lines...) Expand all Loading... |
| 35 | 36 |
| 36 // Some proper JSON with trailing commas: | 37 // Some proper JSON with trailing commas: |
| 37 const char kProperJSONWithCommas[] = | 38 const char kProperJSONWithCommas[] = |
| 38 "{\n" | 39 "{\n" |
| 39 "\t\"some_int\": 42,\n" | 40 "\t\"some_int\": 42,\n" |
| 40 "\t\"some_String\": \"1337\",\n" | 41 "\t\"some_String\": \"1337\",\n" |
| 41 "\t\"the_list\": [\"val1\", \"val2\", ],\n" | 42 "\t\"the_list\": [\"val1\", \"val2\", ],\n" |
| 42 "\t\"compound\": { \"a\": 1, \"b\": 2, },\n" | 43 "\t\"compound\": { \"a\": 1, \"b\": 2, },\n" |
| 43 "}\n"; | 44 "}\n"; |
| 44 | 45 |
| 46 // kProperJSON with a few misc characters at the begin and end. |
| 47 const char kProperJSONPadded[] = |
| 48 ")]}'\n" |
| 49 "{\n" |
| 50 " \"compound\": {\n" |
| 51 " \"a\": 1,\n" |
| 52 " \"b\": 2\n" |
| 53 " },\n" |
| 54 " \"some_String\": \"1337\",\n" |
| 55 " \"some_int\": 42,\n" |
| 56 " \"the_list\": [ \"val1\", \"val2\" ]\n" |
| 57 "}\n" |
| 58 "?!ab\n"; |
| 59 |
| 45 const char kWinLineEnds[] = "\r\n"; | 60 const char kWinLineEnds[] = "\r\n"; |
| 46 const char kLinuxLineEnds[] = "\n"; | 61 const char kLinuxLineEnds[] = "\n"; |
| 47 | 62 |
| 48 // Verifies the generated JSON against the expected output. | 63 // Verifies the generated JSON against the expected output. |
| 49 void CheckJSONIsStillTheSame(Value& value) { | 64 void CheckJSONIsStillTheSame(Value& value) { |
| 50 // Serialize back the output. | 65 // Serialize back the output. |
| 51 std::string serialized_json; | 66 std::string serialized_json; |
| 52 JSONStringValueSerializer str_serializer(&serialized_json); | 67 JSONStringValueSerializer str_serializer(&serialized_json); |
| 53 str_serializer.set_pretty_print(true); | 68 str_serializer.set_pretty_print(true); |
| 54 ASSERT_TRUE(str_serializer.Serialize(value)); | 69 ASSERT_TRUE(str_serializer.Serialize(value)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 67 Value* elt = NULL; | 82 Value* elt = NULL; |
| 68 ASSERT_TRUE(list->Get(0, &elt)); | 83 ASSERT_TRUE(list->Get(0, &elt)); |
| 69 int value = 0; | 84 int value = 0; |
| 70 ASSERT_TRUE(elt && elt->GetAsInteger(&value)); | 85 ASSERT_TRUE(elt && elt->GetAsInteger(&value)); |
| 71 ASSERT_EQ(1, value); | 86 ASSERT_EQ(1, value); |
| 72 } | 87 } |
| 73 | 88 |
| 74 // Test proper JSON [de]serialization from string is working. | 89 // Test proper JSON [de]serialization from string is working. |
| 75 TEST(JSONValueSerializerTest, ReadProperJSONFromString) { | 90 TEST(JSONValueSerializerTest, ReadProperJSONFromString) { |
| 76 // Try to deserialize it through the serializer. | 91 // Try to deserialize it through the serializer. |
| 92 JSONStringValueSerializer str_deserializer(kProperJSON); |
| 93 |
| 94 int error_code = 0; |
| 95 std::string error_message; |
| 96 scoped_ptr<Value> value( |
| 97 str_deserializer.Deserialize(&error_code, &error_message)); |
| 98 ASSERT_TRUE(value.get()); |
| 99 ASSERT_EQ(0, error_code); |
| 100 ASSERT_TRUE(error_message.empty()); |
| 101 // Verify if the same JSON is still there. |
| 102 CheckJSONIsStillTheSame(*value); |
| 103 } |
| 104 |
| 105 // Test proper JSON deserialization from a string pointer is working. |
| 106 TEST(JSONValueSerializerTest, ReadProperJSONFromStringPointer) { |
| 107 // Try to deserialize a string pointer through the serializer. (This exercises |
| 108 // a separate code path to passing a StringPiece.) |
| 77 std::string proper_json(kProperJSON); | 109 std::string proper_json(kProperJSON); |
| 110 JSONStringValueSerializer str_deserializer(&proper_json); |
| 111 |
| 112 int error_code = 0; |
| 113 std::string error_message; |
| 114 scoped_ptr<Value> value( |
| 115 str_deserializer.Deserialize(&error_code, &error_message)); |
| 116 ASSERT_TRUE(value.get()); |
| 117 ASSERT_EQ(0, error_code); |
| 118 ASSERT_TRUE(error_message.empty()); |
| 119 // Verify if the same JSON is still there. |
| 120 CheckJSONIsStillTheSame(*value); |
| 121 } |
| 122 |
| 123 // Test proper JSON deserialization from a StringPiece substring. |
| 124 TEST(JSONValueSerializerTest, ReadProperJSONFromStringPiece) { |
| 125 // Create a StringPiece for the substring of kProperJSONPadded that matches |
| 126 // kProperJSON. |
| 127 base::StringPiece proper_json(kProperJSONPadded); |
| 128 proper_json = proper_json.substr(5, proper_json.length() - 10); |
| 78 JSONStringValueSerializer str_deserializer(proper_json); | 129 JSONStringValueSerializer str_deserializer(proper_json); |
| 79 | 130 |
| 80 int error_code = 0; | 131 int error_code = 0; |
| 81 std::string error_message; | 132 std::string error_message; |
| 82 scoped_ptr<Value> value( | 133 scoped_ptr<Value> value( |
| 83 str_deserializer.Deserialize(&error_code, &error_message)); | 134 str_deserializer.Deserialize(&error_code, &error_message)); |
| 84 ASSERT_TRUE(value.get()); | 135 ASSERT_TRUE(value.get()); |
| 85 ASSERT_EQ(0, error_code); | 136 ASSERT_EQ(0, error_code); |
| 86 ASSERT_TRUE(error_message.empty()); | 137 ASSERT_TRUE(error_message.empty()); |
| 87 // Verify if the same JSON is still there. | 138 // Verify if the same JSON is still there. |
| 88 CheckJSONIsStillTheSame(*value); | 139 CheckJSONIsStillTheSame(*value); |
| 89 } | 140 } |
| 90 | 141 |
| 91 // Test that trialing commas are only properly deserialized from string when | 142 // Test that trialing commas are only properly deserialized from string when |
| 92 // the proper flag for that is set. | 143 // the proper flag for that is set. |
| 93 TEST(JSONValueSerializerTest, ReadJSONWithTrailingCommasFromString) { | 144 TEST(JSONValueSerializerTest, ReadJSONWithTrailingCommasFromString) { |
| 94 // Try to deserialize it through the serializer. | 145 // Try to deserialize it through the serializer. |
| 95 std::string proper_json(kProperJSONWithCommas); | 146 JSONStringValueSerializer str_deserializer(kProperJSONWithCommas); |
| 96 JSONStringValueSerializer str_deserializer(proper_json); | |
| 97 | 147 |
| 98 int error_code = 0; | 148 int error_code = 0; |
| 99 std::string error_message; | 149 std::string error_message; |
| 100 scoped_ptr<Value> value( | 150 scoped_ptr<Value> value( |
| 101 str_deserializer.Deserialize(&error_code, &error_message)); | 151 str_deserializer.Deserialize(&error_code, &error_message)); |
| 102 ASSERT_FALSE(value.get()); | 152 ASSERT_FALSE(value.get()); |
| 103 ASSERT_NE(0, error_code); | 153 ASSERT_NE(0, error_code); |
| 104 ASSERT_FALSE(error_message.empty()); | 154 ASSERT_FALSE(error_message.empty()); |
| 105 // Now the flag is set and it must pass. | 155 // Now the flag is set and it must pass. |
| 106 str_deserializer.set_allow_trailing_comma(true); | 156 str_deserializer.set_allow_trailing_comma(true); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 // Now the flag is set and it must pass. | 208 // Now the flag is set and it must pass. |
| 159 file_deserializer.set_allow_trailing_comma(true); | 209 file_deserializer.set_allow_trailing_comma(true); |
| 160 value.reset(file_deserializer.Deserialize(&error_code, &error_message)); | 210 value.reset(file_deserializer.Deserialize(&error_code, &error_message)); |
| 161 ASSERT_TRUE(value.get()); | 211 ASSERT_TRUE(value.get()); |
| 162 ASSERT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code); | 212 ASSERT_EQ(JSONReader::JSON_TRAILING_COMMA, error_code); |
| 163 // Verify if the same JSON is still there. | 213 // Verify if the same JSON is still there. |
| 164 CheckJSONIsStillTheSame(*value); | 214 CheckJSONIsStillTheSame(*value); |
| 165 } | 215 } |
| 166 | 216 |
| 167 TEST(JSONValueSerializerTest, Roundtrip) { | 217 TEST(JSONValueSerializerTest, Roundtrip) { |
| 168 const std::string original_serialization = | 218 static const char kOriginalSerialization[] = |
| 169 "{\"bool\":true,\"double\":3.14,\"int\":42,\"list\":[1,2],\"null\":null}"; | 219 "{\"bool\":true,\"double\":3.14,\"int\":42,\"list\":[1,2],\"null\":null}"; |
| 170 JSONStringValueSerializer serializer(original_serialization); | 220 JSONStringValueSerializer serializer(kOriginalSerialization); |
| 171 scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); | 221 scoped_ptr<Value> root(serializer.Deserialize(NULL, NULL)); |
| 172 ASSERT_TRUE(root.get()); | 222 ASSERT_TRUE(root.get()); |
| 173 ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); | 223 ASSERT_TRUE(root->IsType(Value::TYPE_DICTIONARY)); |
| 174 | 224 |
| 175 DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get()); | 225 DictionaryValue* root_dict = static_cast<DictionaryValue*>(root.get()); |
| 176 | 226 |
| 177 Value* null_value = NULL; | 227 Value* null_value = NULL; |
| 178 ASSERT_TRUE(root_dict->Get("null", &null_value)); | 228 ASSERT_TRUE(root_dict->Get("null", &null_value)); |
| 179 ASSERT_TRUE(null_value); | 229 ASSERT_TRUE(null_value); |
| 180 ASSERT_TRUE(null_value->IsType(Value::TYPE_NULL)); | 230 ASSERT_TRUE(null_value->IsType(Value::TYPE_NULL)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 191 ASSERT_TRUE(root_dict->GetDouble("double", &double_value)); | 241 ASSERT_TRUE(root_dict->GetDouble("double", &double_value)); |
| 192 ASSERT_DOUBLE_EQ(3.14, double_value); | 242 ASSERT_DOUBLE_EQ(3.14, double_value); |
| 193 | 243 |
| 194 // We shouldn't be able to write using this serializer, since it was | 244 // We shouldn't be able to write using this serializer, since it was |
| 195 // initialized with a const string. | 245 // initialized with a const string. |
| 196 ASSERT_FALSE(serializer.Serialize(*root_dict)); | 246 ASSERT_FALSE(serializer.Serialize(*root_dict)); |
| 197 | 247 |
| 198 std::string test_serialization; | 248 std::string test_serialization; |
| 199 JSONStringValueSerializer mutable_serializer(&test_serialization); | 249 JSONStringValueSerializer mutable_serializer(&test_serialization); |
| 200 ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); | 250 ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); |
| 201 ASSERT_EQ(original_serialization, test_serialization); | 251 ASSERT_EQ(kOriginalSerialization, test_serialization); |
| 202 | 252 |
| 203 mutable_serializer.set_pretty_print(true); | 253 mutable_serializer.set_pretty_print(true); |
| 204 ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); | 254 ASSERT_TRUE(mutable_serializer.Serialize(*root_dict)); |
| 205 // JSON output uses a different newline style on Windows than on other | 255 // JSON output uses a different newline style on Windows than on other |
| 206 // platforms. | 256 // platforms. |
| 207 #if defined(OS_WIN) | 257 #if defined(OS_WIN) |
| 208 #define JSON_NEWLINE "\r\n" | 258 #define JSON_NEWLINE "\r\n" |
| 209 #else | 259 #else |
| 210 #define JSON_NEWLINE "\n" | 260 #define JSON_NEWLINE "\n" |
| 211 #endif | 261 #endif |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 ASSERT_TRUE(serializer.Serialize(valueRoot)); | 316 ASSERT_TRUE(serializer.Serialize(valueRoot)); |
| 267 ASSERT_EQ(expected_output, output_js); | 317 ASSERT_EQ(expected_output, output_js); |
| 268 } | 318 } |
| 269 | 319 |
| 270 TEST(JSONValueSerializerTest, UnicodeStrings) { | 320 TEST(JSONValueSerializerTest, UnicodeStrings) { |
| 271 // unicode string json -> escaped ascii text | 321 // unicode string json -> escaped ascii text |
| 272 DictionaryValue root; | 322 DictionaryValue root; |
| 273 string16 test(WideToUTF16(L"\x7F51\x9875")); | 323 string16 test(WideToUTF16(L"\x7F51\x9875")); |
| 274 root.SetString("web", test); | 324 root.SetString("web", test); |
| 275 | 325 |
| 276 std::string expected = "{\"web\":\"\xE7\xBD\x91\xE9\xA1\xB5\"}"; | 326 static const char kExpected[] = "{\"web\":\"\xE7\xBD\x91\xE9\xA1\xB5\"}"; |
| 277 | 327 |
| 278 std::string actual; | 328 std::string actual; |
| 279 JSONStringValueSerializer serializer(&actual); | 329 JSONStringValueSerializer serializer(&actual); |
| 280 ASSERT_TRUE(serializer.Serialize(root)); | 330 ASSERT_TRUE(serializer.Serialize(root)); |
| 281 ASSERT_EQ(expected, actual); | 331 ASSERT_EQ(kExpected, actual); |
| 282 | 332 |
| 283 // escaped ascii text -> json | 333 // escaped ascii text -> json |
| 284 JSONStringValueSerializer deserializer(expected); | 334 JSONStringValueSerializer deserializer(kExpected); |
| 285 scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); | 335 scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); |
| 286 ASSERT_TRUE(deserial_root.get()); | 336 ASSERT_TRUE(deserial_root.get()); |
| 287 DictionaryValue* dict_root = | 337 DictionaryValue* dict_root = |
| 288 static_cast<DictionaryValue*>(deserial_root.get()); | 338 static_cast<DictionaryValue*>(deserial_root.get()); |
| 289 string16 web_value; | 339 string16 web_value; |
| 290 ASSERT_TRUE(dict_root->GetString("web", &web_value)); | 340 ASSERT_TRUE(dict_root->GetString("web", &web_value)); |
| 291 ASSERT_EQ(test, web_value); | 341 ASSERT_EQ(test, web_value); |
| 292 } | 342 } |
| 293 | 343 |
| 294 TEST(JSONValueSerializerTest, HexStrings) { | 344 TEST(JSONValueSerializerTest, HexStrings) { |
| 295 // hex string json -> escaped ascii text | 345 // hex string json -> escaped ascii text |
| 296 DictionaryValue root; | 346 DictionaryValue root; |
| 297 string16 test(WideToUTF16(L"\x01\x02")); | 347 string16 test(WideToUTF16(L"\x01\x02")); |
| 298 root.SetString("test", test); | 348 root.SetString("test", test); |
| 299 | 349 |
| 300 std::string expected = "{\"test\":\"\\u0001\\u0002\"}"; | 350 static const char kExpected[] = "{\"test\":\"\\u0001\\u0002\"}"; |
| 301 | 351 |
| 302 std::string actual; | 352 std::string actual; |
| 303 JSONStringValueSerializer serializer(&actual); | 353 JSONStringValueSerializer serializer(&actual); |
| 304 ASSERT_TRUE(serializer.Serialize(root)); | 354 ASSERT_TRUE(serializer.Serialize(root)); |
| 305 ASSERT_EQ(expected, actual); | 355 ASSERT_EQ(kExpected, actual); |
| 306 | 356 |
| 307 // escaped ascii text -> json | 357 // escaped ascii text -> json |
| 308 JSONStringValueSerializer deserializer(expected); | 358 JSONStringValueSerializer deserializer(kExpected); |
| 309 scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); | 359 scoped_ptr<Value> deserial_root(deserializer.Deserialize(NULL, NULL)); |
| 310 ASSERT_TRUE(deserial_root.get()); | 360 ASSERT_TRUE(deserial_root.get()); |
| 311 DictionaryValue* dict_root = | 361 DictionaryValue* dict_root = |
| 312 static_cast<DictionaryValue*>(deserial_root.get()); | 362 static_cast<DictionaryValue*>(deserial_root.get()); |
| 313 string16 test_value; | 363 string16 test_value; |
| 314 ASSERT_TRUE(dict_root->GetString("test", &test_value)); | 364 ASSERT_TRUE(dict_root->GetString("test", &test_value)); |
| 315 ASSERT_EQ(test, test_value); | 365 ASSERT_EQ(test, test_value); |
| 316 | 366 |
| 317 // Test converting escaped regular chars | 367 // Test converting escaped regular chars |
| 318 std::string escaped_chars = "{\"test\":\"\\u0067\\u006f\"}"; | 368 static const char kEscapedChars[] = "{\"test\":\"\\u0067\\u006f\"}"; |
| 319 JSONStringValueSerializer deserializer2(escaped_chars); | 369 JSONStringValueSerializer deserializer2(kEscapedChars); |
| 320 deserial_root.reset(deserializer2.Deserialize(NULL, NULL)); | 370 deserial_root.reset(deserializer2.Deserialize(NULL, NULL)); |
| 321 ASSERT_TRUE(deserial_root.get()); | 371 ASSERT_TRUE(deserial_root.get()); |
| 322 dict_root = static_cast<DictionaryValue*>(deserial_root.get()); | 372 dict_root = static_cast<DictionaryValue*>(deserial_root.get()); |
| 323 ASSERT_TRUE(dict_root->GetString("test", &test_value)); | 373 ASSERT_TRUE(dict_root->GetString("test", &test_value)); |
| 324 ASSERT_EQ(ASCIIToUTF16("go"), test_value); | 374 ASSERT_EQ(ASCIIToUTF16("go"), test_value); |
| 325 } | 375 } |
| 326 | 376 |
| 327 TEST(JSONValueSerializerTest, AllowTrailingComma) { | 377 TEST(JSONValueSerializerTest, AllowTrailingComma) { |
| 328 scoped_ptr<Value> root; | 378 scoped_ptr<Value> root; |
| 329 scoped_ptr<Value> root_expected; | 379 scoped_ptr<Value> root_expected; |
| 330 std::string test_with_commas("{\"key\": [true,],}"); | 380 static const char kTestWithCommas[] = "{\"key\": [true,],}"; |
| 331 std::string test_no_commas("{\"key\": [true]}"); | 381 static const char kTestNoCommas[] = "{\"key\": [true]}"; |
| 332 | 382 |
| 333 JSONStringValueSerializer serializer(test_with_commas); | 383 JSONStringValueSerializer serializer(kTestWithCommas); |
| 334 serializer.set_allow_trailing_comma(true); | 384 serializer.set_allow_trailing_comma(true); |
| 335 JSONStringValueSerializer serializer_expected(test_no_commas); | 385 JSONStringValueSerializer serializer_expected(kTestNoCommas); |
| 336 root.reset(serializer.Deserialize(NULL, NULL)); | 386 root.reset(serializer.Deserialize(NULL, NULL)); |
| 337 ASSERT_TRUE(root.get()); | 387 ASSERT_TRUE(root.get()); |
| 338 root_expected.reset(serializer_expected.Deserialize(NULL, NULL)); | 388 root_expected.reset(serializer_expected.Deserialize(NULL, NULL)); |
| 339 ASSERT_TRUE(root_expected.get()); | 389 ASSERT_TRUE(root_expected.get()); |
| 340 ASSERT_TRUE(root->Equals(root_expected.get())); | 390 ASSERT_TRUE(root->Equals(root_expected.get())); |
| 341 } | 391 } |
| 342 | 392 |
| 343 TEST(JSONValueSerializerTest, JSONReaderComments) { | 393 TEST(JSONValueSerializerTest, JSONReaderComments) { |
| 344 ValidateJsonList("[ // 2, 3, ignore me ] \n1 ]"); | 394 ValidateJsonList("[ // 2, 3, ignore me ] \n1 ]"); |
| 345 ValidateJsonList("[ /* 2, \n3, ignore me ]*/ \n1 ]"); | 395 ValidateJsonList("[ /* 2, \n3, ignore me ]*/ \n1 ]"); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 ASSERT_TRUE(PathExists(source_file_path)); | 510 ASSERT_TRUE(PathExists(source_file_path)); |
| 461 JSONFileValueSerializer serializer(source_file_path); | 511 JSONFileValueSerializer serializer(source_file_path); |
| 462 scoped_ptr<Value> root; | 512 scoped_ptr<Value> root; |
| 463 root.reset(serializer.Deserialize(NULL, NULL)); | 513 root.reset(serializer.Deserialize(NULL, NULL)); |
| 464 ASSERT_TRUE(root.get()); | 514 ASSERT_TRUE(root.get()); |
| 465 } | 515 } |
| 466 | 516 |
| 467 } // namespace | 517 } // namespace |
| 468 | 518 |
| 469 } // namespace base | 519 } // namespace base |
| OLD | NEW |