| 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 <cmath> | 5 #include <cmath> |
| 6 | 6 |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/test/values_test_util.h" | 8 #include "base/test/values_test_util.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "content/renderer/v8_value_converter_impl.h" | 10 #include "content/renderer/v8_value_converter_impl.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 virtual void SetUp() { | 28 virtual void SetUp() { |
| 29 v8::HandleScope handle_scope; | 29 v8::HandleScope handle_scope; |
| 30 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); | 30 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); |
| 31 context_ = v8::Context::New(NULL, global); | 31 context_ = v8::Context::New(NULL, global); |
| 32 } | 32 } |
| 33 | 33 |
| 34 virtual void TearDown() { | 34 virtual void TearDown() { |
| 35 context_.Dispose(); | 35 context_.Dispose(); |
| 36 } | 36 } |
| 37 | 37 |
| 38 std::string GetString(DictionaryValue* value, const std::string& key) { | 38 std::string GetString(base::DictionaryValue* value, const std::string& key) { |
| 39 std::string temp; | 39 std::string temp; |
| 40 if (!value->GetString(key, &temp)) { | 40 if (!value->GetString(key, &temp)) { |
| 41 ADD_FAILURE(); | 41 ADD_FAILURE(); |
| 42 return ""; | 42 return ""; |
| 43 } | 43 } |
| 44 return temp; | 44 return temp; |
| 45 } | 45 } |
| 46 | 46 |
| 47 std::string GetString(v8::Handle<v8::Object> value, const std::string& key) { | 47 std::string GetString(v8::Handle<v8::Object> value, const std::string& key) { |
| 48 v8::Handle<v8::String> temp = | 48 v8::Handle<v8::String> temp = |
| 49 value->Get(v8::String::New(key.c_str())).As<v8::String>(); | 49 value->Get(v8::String::New(key.c_str())).As<v8::String>(); |
| 50 if (temp.IsEmpty()) { | 50 if (temp.IsEmpty()) { |
| 51 ADD_FAILURE(); | 51 ADD_FAILURE(); |
| 52 return ""; | 52 return ""; |
| 53 } | 53 } |
| 54 v8::String::Utf8Value utf8(temp); | 54 v8::String::Utf8Value utf8(temp); |
| 55 return std::string(*utf8, utf8.length()); | 55 return std::string(*utf8, utf8.length()); |
| 56 } | 56 } |
| 57 | 57 |
| 58 std::string GetString(ListValue* value, uint32 index) { | 58 std::string GetString(base::ListValue* value, uint32 index) { |
| 59 std::string temp; | 59 std::string temp; |
| 60 if (!value->GetString(static_cast<size_t>(index), &temp)) { | 60 if (!value->GetString(static_cast<size_t>(index), &temp)) { |
| 61 ADD_FAILURE(); | 61 ADD_FAILURE(); |
| 62 return ""; | 62 return ""; |
| 63 } | 63 } |
| 64 return temp; | 64 return temp; |
| 65 } | 65 } |
| 66 | 66 |
| 67 std::string GetString(v8::Handle<v8::Array> value, uint32 index) { | 67 std::string GetString(v8::Handle<v8::Array> value, uint32 index) { |
| 68 v8::Handle<v8::String> temp = value->Get(index).As<v8::String>(); | 68 v8::Handle<v8::String> temp = value->Get(index).As<v8::String>(); |
| 69 if (temp.IsEmpty()) { | 69 if (temp.IsEmpty()) { |
| 70 ADD_FAILURE(); | 70 ADD_FAILURE(); |
| 71 return ""; | 71 return ""; |
| 72 } | 72 } |
| 73 v8::String::Utf8Value utf8(temp); | 73 v8::String::Utf8Value utf8(temp); |
| 74 return std::string(*utf8, utf8.length()); | 74 return std::string(*utf8, utf8.length()); |
| 75 } | 75 } |
| 76 | 76 |
| 77 bool IsNull(DictionaryValue* value, const std::string& key) { | 77 bool IsNull(base::DictionaryValue* value, const std::string& key) { |
| 78 Value* child = NULL; | 78 base::Value* child = NULL; |
| 79 if (!value->Get(key, &child)) { | 79 if (!value->Get(key, &child)) { |
| 80 ADD_FAILURE(); | 80 ADD_FAILURE(); |
| 81 return false; | 81 return false; |
| 82 } | 82 } |
| 83 return child->GetType() == Value::TYPE_NULL; | 83 return child->GetType() == base::Value::TYPE_NULL; |
| 84 } | 84 } |
| 85 | 85 |
| 86 bool IsNull(v8::Handle<v8::Object> value, const std::string& key) { | 86 bool IsNull(v8::Handle<v8::Object> value, const std::string& key) { |
| 87 v8::Handle<v8::Value> child = value->Get(v8::String::New(key.c_str())); | 87 v8::Handle<v8::Value> child = value->Get(v8::String::New(key.c_str())); |
| 88 if (child.IsEmpty()) { | 88 if (child.IsEmpty()) { |
| 89 ADD_FAILURE(); | 89 ADD_FAILURE(); |
| 90 return false; | 90 return false; |
| 91 } | 91 } |
| 92 return child->IsNull(); | 92 return child->IsNull(); |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool IsNull(ListValue* value, uint32 index) { | 95 bool IsNull(base::ListValue* value, uint32 index) { |
| 96 Value* child = NULL; | 96 base::Value* child = NULL; |
| 97 if (!value->Get(static_cast<size_t>(index), &child)) { | 97 if (!value->Get(static_cast<size_t>(index), &child)) { |
| 98 ADD_FAILURE(); | 98 ADD_FAILURE(); |
| 99 return false; | 99 return false; |
| 100 } | 100 } |
| 101 return child->GetType() == Value::TYPE_NULL; | 101 return child->GetType() == base::Value::TYPE_NULL; |
| 102 } | 102 } |
| 103 | 103 |
| 104 bool IsNull(v8::Handle<v8::Array> value, uint32 index) { | 104 bool IsNull(v8::Handle<v8::Array> value, uint32 index) { |
| 105 v8::Handle<v8::Value> child = value->Get(index); | 105 v8::Handle<v8::Value> child = value->Get(index); |
| 106 if (child.IsEmpty()) { | 106 if (child.IsEmpty()) { |
| 107 ADD_FAILURE(); | 107 ADD_FAILURE(); |
| 108 return false; | 108 return false; |
| 109 } | 109 } |
| 110 return child->IsNull(); | 110 return child->IsNull(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 void TestWeirdType(const V8ValueConverterImpl& converter, | 113 void TestWeirdType(const V8ValueConverterImpl& converter, |
| 114 v8::Handle<v8::Value> val, | 114 v8::Handle<v8::Value> val, |
| 115 base::Value::Type expected_type, | 115 base::Value::Type expected_type, |
| 116 scoped_ptr<Value> expected_value) { | 116 scoped_ptr<base::Value> expected_value) { |
| 117 scoped_ptr<Value> raw(converter.FromV8Value(val, context_)); | 117 scoped_ptr<base::Value> raw(converter.FromV8Value(val, context_)); |
| 118 | 118 |
| 119 if (expected_value.get()) { | 119 if (expected_value.get()) { |
| 120 ASSERT_TRUE(raw.get()); | 120 ASSERT_TRUE(raw.get()); |
| 121 EXPECT_TRUE(expected_value->Equals(raw.get())); | 121 EXPECT_TRUE(expected_value->Equals(raw.get())); |
| 122 EXPECT_EQ(expected_type, raw->GetType()); | 122 EXPECT_EQ(expected_type, raw->GetType()); |
| 123 } else { | 123 } else { |
| 124 EXPECT_FALSE(raw.get()); | 124 EXPECT_FALSE(raw.get()); |
| 125 } | 125 } |
| 126 | 126 |
| 127 v8::Handle<v8::Object> object(v8::Object::New()); | 127 v8::Handle<v8::Object> object(v8::Object::New()); |
| 128 object->Set(v8::String::New("test"), val); | 128 object->Set(v8::String::New("test"), val); |
| 129 scoped_ptr<DictionaryValue> dictionary( | 129 scoped_ptr<base::DictionaryValue> dictionary( |
| 130 static_cast<DictionaryValue*>( | 130 static_cast<base::DictionaryValue*>( |
| 131 converter.FromV8Value(object, context_))); | 131 converter.FromV8Value(object, context_))); |
| 132 ASSERT_TRUE(dictionary.get()); | 132 ASSERT_TRUE(dictionary.get()); |
| 133 | 133 |
| 134 if (expected_value.get()) { | 134 if (expected_value.get()) { |
| 135 Value* temp = NULL; | 135 base::Value* temp = NULL; |
| 136 ASSERT_TRUE(dictionary->Get("test", &temp)); | 136 ASSERT_TRUE(dictionary->Get("test", &temp)); |
| 137 EXPECT_EQ(expected_type, temp->GetType()); | 137 EXPECT_EQ(expected_type, temp->GetType()); |
| 138 EXPECT_TRUE(expected_value->Equals(temp)); | 138 EXPECT_TRUE(expected_value->Equals(temp)); |
| 139 } else { | 139 } else { |
| 140 EXPECT_FALSE(dictionary->HasKey("test")); | 140 EXPECT_FALSE(dictionary->HasKey("test")); |
| 141 } | 141 } |
| 142 | 142 |
| 143 v8::Handle<v8::Array> array(v8::Array::New()); | 143 v8::Handle<v8::Array> array(v8::Array::New()); |
| 144 array->Set(0, val); | 144 array->Set(0, val); |
| 145 scoped_ptr<ListValue> list( | 145 scoped_ptr<base::ListValue> list( |
| 146 static_cast<ListValue*>( | 146 static_cast<base::ListValue*>(converter.FromV8Value(array, context_))); |
| 147 converter.FromV8Value(array, context_))); | |
| 148 ASSERT_TRUE(list.get()); | 147 ASSERT_TRUE(list.get()); |
| 149 if (expected_value.get()) { | 148 if (expected_value.get()) { |
| 150 Value* temp = NULL; | 149 base::Value* temp = NULL; |
| 151 ASSERT_TRUE(list->Get(0, &temp)); | 150 ASSERT_TRUE(list->Get(0, &temp)); |
| 152 EXPECT_EQ(expected_type, temp->GetType()); | 151 EXPECT_EQ(expected_type, temp->GetType()); |
| 153 EXPECT_TRUE(expected_value->Equals(temp)); | 152 EXPECT_TRUE(expected_value->Equals(temp)); |
| 154 } else { | 153 } else { |
| 155 // Arrays should preserve their length, and convert unconvertible | 154 // Arrays should preserve their length, and convert unconvertible |
| 156 // types into null. | 155 // types into null. |
| 157 Value* temp = NULL; | 156 base::Value* temp = NULL; |
| 158 ASSERT_TRUE(list->Get(0, &temp)); | 157 ASSERT_TRUE(list->Get(0, &temp)); |
| 159 EXPECT_EQ(Value::TYPE_NULL, temp->GetType()); | 158 EXPECT_EQ(base::Value::TYPE_NULL, temp->GetType()); |
| 160 } | 159 } |
| 161 } | 160 } |
| 162 | 161 |
| 163 // Context for the JavaScript in the test. | 162 // Context for the JavaScript in the test. |
| 164 v8::Persistent<v8::Context> context_; | 163 v8::Persistent<v8::Context> context_; |
| 165 }; | 164 }; |
| 166 | 165 |
| 167 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { | 166 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { |
| 168 scoped_ptr<Value> original_root = base::test::ParseJson( | 167 scoped_ptr<base::Value> original_root = base::test::ParseJson( |
| 169 "{ \n" | 168 "{ \n" |
| 170 " \"null\": null, \n" | 169 " \"null\": null, \n" |
| 171 " \"true\": true, \n" | 170 " \"true\": true, \n" |
| 172 " \"false\": false, \n" | 171 " \"false\": false, \n" |
| 173 " \"positive-int\": 42, \n" | 172 " \"positive-int\": 42, \n" |
| 174 " \"negative-int\": -42, \n" | 173 " \"negative-int\": -42, \n" |
| 175 " \"zero\": 0, \n" | 174 " \"zero\": 0, \n" |
| 176 " \"double\": 88.8, \n" | 175 " \"double\": 88.8, \n" |
| 177 " \"big-integral-double\": 9007199254740992.0, \n" // 2.0^53 | 176 " \"big-integral-double\": 9007199254740992.0, \n" // 2.0^53 |
| 178 " \"string\": \"foobar\", \n" | 177 " \"string\": \"foobar\", \n" |
| 179 " \"empty-string\": \"\", \n" | 178 " \"empty-string\": \"\", \n" |
| 180 " \"dictionary\": { \n" | 179 " \"dictionary\": { \n" |
| 181 " \"foo\": \"bar\",\n" | 180 " \"foo\": \"bar\",\n" |
| 182 " \"hot\": \"dog\",\n" | 181 " \"hot\": \"dog\",\n" |
| 183 " }, \n" | 182 " }, \n" |
| 184 " \"empty-dictionary\": {}, \n" | 183 " \"empty-dictionary\": {}, \n" |
| 185 " \"list\": [ \"monkey\", \"balls\" ], \n" | 184 " \"list\": [ \"monkey\", \"balls\" ], \n" |
| 186 " \"empty-list\": [], \n" | 185 " \"empty-list\": [], \n" |
| 187 "}"); | 186 "}"); |
| 188 | 187 |
| 189 v8::Context::Scope context_scope(context_); | 188 v8::Context::Scope context_scope(context_); |
| 190 v8::HandleScope handle_scope; | 189 v8::HandleScope handle_scope; |
| 191 | 190 |
| 192 V8ValueConverterImpl converter; | 191 V8ValueConverterImpl converter; |
| 193 v8::Handle<v8::Object> v8_object = | 192 v8::Handle<v8::Object> v8_object = |
| 194 converter.ToV8Value(original_root.get(), context_).As<v8::Object>(); | 193 converter.ToV8Value(original_root.get(), context_).As<v8::Object>(); |
| 195 ASSERT_FALSE(v8_object.IsEmpty()); | 194 ASSERT_FALSE(v8_object.IsEmpty()); |
| 196 | 195 |
| 197 EXPECT_EQ(static_cast<const DictionaryValue&>(*original_root).size(), | 196 EXPECT_EQ(static_cast<const base::DictionaryValue&>(*original_root).size(), |
| 198 v8_object->GetPropertyNames()->Length()); | 197 v8_object->GetPropertyNames()->Length()); |
| 199 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); | 198 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); |
| 200 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); | 199 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); |
| 201 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); | 200 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); |
| 202 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); | 201 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); |
| 203 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); | 202 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); |
| 204 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); | 203 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); |
| 205 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); | 204 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); |
| 206 EXPECT_TRUE( | 205 EXPECT_TRUE( |
| 207 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); | 206 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); |
| 208 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); | 207 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); |
| 209 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); | 208 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); |
| 210 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); | 209 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); |
| 211 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); | 210 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); |
| 212 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); | 211 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); |
| 213 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); | 212 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); |
| 214 | 213 |
| 215 scoped_ptr<Value> new_root(converter.FromV8Value(v8_object, context_)); | 214 scoped_ptr<base::Value> new_root(converter.FromV8Value(v8_object, context_)); |
| 216 EXPECT_NE(original_root.get(), new_root.get()); | 215 EXPECT_NE(original_root.get(), new_root.get()); |
| 217 EXPECT_TRUE(original_root->Equals(new_root.get())); | 216 EXPECT_TRUE(original_root->Equals(new_root.get())); |
| 218 } | 217 } |
| 219 | 218 |
| 220 TEST_F(V8ValueConverterImplTest, KeysWithDots) { | 219 TEST_F(V8ValueConverterImplTest, KeysWithDots) { |
| 221 scoped_ptr<Value> original = | 220 scoped_ptr<base::Value> original = |
| 222 base::test::ParseJson("{ \"foo.bar\": \"baz\" }"); | 221 base::test::ParseJson("{ \"foo.bar\": \"baz\" }"); |
| 223 | 222 |
| 224 v8::Context::Scope context_scope(context_); | 223 v8::Context::Scope context_scope(context_); |
| 225 v8::HandleScope handle_scope; | 224 v8::HandleScope handle_scope; |
| 226 | 225 |
| 227 V8ValueConverterImpl converter; | 226 V8ValueConverterImpl converter; |
| 228 scoped_ptr<Value> copy( | 227 scoped_ptr<base::Value> copy( |
| 229 converter.FromV8Value( | 228 converter.FromV8Value( |
| 230 converter.ToV8Value(original.get(), context_), context_)); | 229 converter.ToV8Value(original.get(), context_), context_)); |
| 231 | 230 |
| 232 EXPECT_TRUE(original->Equals(copy.get())); | 231 EXPECT_TRUE(original->Equals(copy.get())); |
| 233 } | 232 } |
| 234 | 233 |
| 235 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { | 234 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { |
| 236 v8::Context::Scope context_scope(context_); | 235 v8::Context::Scope context_scope(context_); |
| 237 v8::HandleScope handle_scope; | 236 v8::HandleScope handle_scope; |
| 238 | 237 |
| 239 // Set up objects to throw when reading or writing 'foo'. | 238 // Set up objects to throw when reading or writing 'foo'. |
| 240 const char* source = | 239 const char* source = |
| 241 "Object.prototype.__defineSetter__('foo', " | 240 "Object.prototype.__defineSetter__('foo', " |
| 242 " function() { throw new Error('muah!'); });" | 241 " function() { throw new Error('muah!'); });" |
| 243 "Object.prototype.__defineGetter__('foo', " | 242 "Object.prototype.__defineGetter__('foo', " |
| 244 " function() { throw new Error('muah!'); });"; | 243 " function() { throw new Error('muah!'); });"; |
| 245 | 244 |
| 246 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 245 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 247 script->Run(); | 246 script->Run(); |
| 248 | 247 |
| 249 v8::Handle<v8::Object> object(v8::Object::New()); | 248 v8::Handle<v8::Object> object(v8::Object::New()); |
| 250 object->Set(v8::String::New("bar"), v8::String::New("bar")); | 249 object->Set(v8::String::New("bar"), v8::String::New("bar")); |
| 251 | 250 |
| 252 // Converting from v8 value should replace the foo property with null. | 251 // Converting from v8 value should replace the foo property with null. |
| 253 V8ValueConverterImpl converter; | 252 V8ValueConverterImpl converter; |
| 254 scoped_ptr<DictionaryValue> converted(static_cast<DictionaryValue*>( | 253 scoped_ptr<base::DictionaryValue> converted( |
| 255 converter.FromV8Value(object, context_))); | 254 static_cast<base::DictionaryValue*>( |
| 255 converter.FromV8Value(object, context_))); |
| 256 EXPECT_TRUE(converted.get()); | 256 EXPECT_TRUE(converted.get()); |
| 257 // http://code.google.com/p/v8/issues/detail?id=1342 | 257 // http://code.google.com/p/v8/issues/detail?id=1342 |
| 258 // EXPECT_EQ(2u, converted->size()); | 258 // EXPECT_EQ(2u, converted->size()); |
| 259 // EXPECT_TRUE(IsNull(converted.get(), "foo")); | 259 // EXPECT_TRUE(IsNull(converted.get(), "foo")); |
| 260 EXPECT_EQ(1u, converted->size()); | 260 EXPECT_EQ(1u, converted->size()); |
| 261 EXPECT_EQ("bar", GetString(converted.get(), "bar")); | 261 EXPECT_EQ("bar", GetString(converted.get(), "bar")); |
| 262 | 262 |
| 263 // Converting to v8 value should drop the foo property. | 263 // Converting to v8 value should drop the foo property. |
| 264 converted->SetString("foo", "foo"); | 264 converted->SetString("foo", "foo"); |
| 265 v8::Handle<v8::Object> copy = | 265 v8::Handle<v8::Object> copy = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 282 "arr[1] = 'bar';" | 282 "arr[1] = 'bar';" |
| 283 "return arr;" | 283 "return arr;" |
| 284 "})();"; | 284 "})();"; |
| 285 | 285 |
| 286 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 286 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 287 v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); | 287 v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); |
| 288 ASSERT_FALSE(array.IsEmpty()); | 288 ASSERT_FALSE(array.IsEmpty()); |
| 289 | 289 |
| 290 // Converting from v8 value should replace the first item with null. | 290 // Converting from v8 value should replace the first item with null. |
| 291 V8ValueConverterImpl converter; | 291 V8ValueConverterImpl converter; |
| 292 scoped_ptr<ListValue> converted(static_cast<ListValue*>( | 292 scoped_ptr<base::ListValue> converted(static_cast<base::ListValue*>( |
| 293 converter.FromV8Value(array, context_))); | 293 converter.FromV8Value(array, context_))); |
| 294 ASSERT_TRUE(converted.get()); | 294 ASSERT_TRUE(converted.get()); |
| 295 // http://code.google.com/p/v8/issues/detail?id=1342 | 295 // http://code.google.com/p/v8/issues/detail?id=1342 |
| 296 EXPECT_EQ(2u, converted->GetSize()); | 296 EXPECT_EQ(2u, converted->GetSize()); |
| 297 EXPECT_TRUE(IsNull(converted.get(), 0)); | 297 EXPECT_TRUE(IsNull(converted.get(), 0)); |
| 298 | 298 |
| 299 // Converting to v8 value should drop the first item and leave a hole. | 299 // Converting to v8 value should drop the first item and leave a hole. |
| 300 converted.reset(static_cast<ListValue*>( | 300 converted.reset(static_cast<base::ListValue*>( |
| 301 base::test::ParseJson("[ \"foo\", \"bar\" ]").release())); | 301 base::test::ParseJson("[ \"foo\", \"bar\" ]").release())); |
| 302 v8::Handle<v8::Array> copy = | 302 v8::Handle<v8::Array> copy = |
| 303 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); | 303 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); |
| 304 ASSERT_FALSE(copy.IsEmpty()); | 304 ASSERT_FALSE(copy.IsEmpty()); |
| 305 EXPECT_EQ(2u, copy->Length()); | 305 EXPECT_EQ(2u, copy->Length()); |
| 306 EXPECT_EQ("bar", GetString(copy, 1)); | 306 EXPECT_EQ("bar", GetString(copy, 1)); |
| 307 } | 307 } |
| 308 | 308 |
| 309 TEST_F(V8ValueConverterImplTest, WeirdTypes) { | 309 TEST_F(V8ValueConverterImplTest, WeirdTypes) { |
| 310 v8::Context::Scope context_scope(context_); | 310 v8::Context::Scope context_scope(context_); |
| 311 v8::HandleScope handle_scope; | 311 v8::HandleScope handle_scope; |
| 312 | 312 |
| 313 v8::Handle<v8::RegExp> regex( | 313 v8::Handle<v8::RegExp> regex( |
| 314 v8::RegExp::New(v8::String::New("."), v8::RegExp::kNone)); | 314 v8::RegExp::New(v8::String::New("."), v8::RegExp::kNone)); |
| 315 | 315 |
| 316 V8ValueConverterImpl converter; | 316 V8ValueConverterImpl converter; |
| 317 TestWeirdType(converter, | 317 TestWeirdType(converter, |
| 318 v8::Undefined(), | 318 v8::Undefined(), |
| 319 Value::TYPE_NULL, // Arbitrary type, result is NULL. | 319 base::Value::TYPE_NULL, // Arbitrary type, result is NULL. |
| 320 scoped_ptr<Value>(NULL)); | 320 scoped_ptr<base::Value>(NULL)); |
| 321 TestWeirdType(converter, | 321 TestWeirdType(converter, |
| 322 v8::Date::New(1000), | 322 v8::Date::New(1000), |
| 323 Value::TYPE_DICTIONARY, | 323 base::Value::TYPE_DICTIONARY, |
| 324 scoped_ptr<Value>(new DictionaryValue())); | 324 scoped_ptr<base::Value>(new base::DictionaryValue())); |
| 325 TestWeirdType(converter, | 325 TestWeirdType(converter, |
| 326 regex, | 326 regex, |
| 327 Value::TYPE_DICTIONARY, | 327 base::Value::TYPE_DICTIONARY, |
| 328 scoped_ptr<Value>(new DictionaryValue())); | 328 scoped_ptr<base::Value>(new base::DictionaryValue())); |
| 329 | 329 |
| 330 converter.SetDateAllowed(true); | 330 converter.SetDateAllowed(true); |
| 331 TestWeirdType(converter, | 331 TestWeirdType(converter, |
| 332 v8::Date::New(1000), | 332 v8::Date::New(1000), |
| 333 Value::TYPE_DOUBLE, | 333 base::Value::TYPE_DOUBLE, |
| 334 scoped_ptr<Value>(Value::CreateDoubleValue(1))); | 334 scoped_ptr<base::Value>(new base::FundamentalValue(1.0))); |
| 335 | 335 |
| 336 converter.SetRegExpAllowed(true); | 336 converter.SetRegExpAllowed(true); |
| 337 TestWeirdType(converter, | 337 TestWeirdType(converter, |
| 338 regex, | 338 regex, |
| 339 Value::TYPE_STRING, | 339 base::Value::TYPE_STRING, |
| 340 scoped_ptr<Value>(Value::CreateStringValue("/./"))); | 340 scoped_ptr<base::Value>(new base::StringValue("/./"))); |
| 341 } | 341 } |
| 342 | 342 |
| 343 TEST_F(V8ValueConverterImplTest, Prototype) { | 343 TEST_F(V8ValueConverterImplTest, Prototype) { |
| 344 v8::Context::Scope context_scope(context_); | 344 v8::Context::Scope context_scope(context_); |
| 345 v8::HandleScope handle_scope; | 345 v8::HandleScope handle_scope; |
| 346 | 346 |
| 347 const char* source = "(function() {" | 347 const char* source = "(function() {" |
| 348 "Object.prototype.foo = 'foo';" | 348 "Object.prototype.foo = 'foo';" |
| 349 "return {};" | 349 "return {};" |
| 350 "})();"; | 350 "})();"; |
| 351 | 351 |
| 352 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 352 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 353 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 353 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
| 354 ASSERT_FALSE(object.IsEmpty()); | 354 ASSERT_FALSE(object.IsEmpty()); |
| 355 | 355 |
| 356 V8ValueConverterImpl converter; | 356 V8ValueConverterImpl converter; |
| 357 scoped_ptr<DictionaryValue> result( | 357 scoped_ptr<base::DictionaryValue> result( |
| 358 static_cast<DictionaryValue*>(converter.FromV8Value(object, context_))); | 358 static_cast<base::DictionaryValue*>( |
| 359 converter.FromV8Value(object, context_))); |
| 359 ASSERT_TRUE(result.get()); | 360 ASSERT_TRUE(result.get()); |
| 360 EXPECT_EQ(0u, result->size()); | 361 EXPECT_EQ(0u, result->size()); |
| 361 } | 362 } |
| 362 | 363 |
| 363 TEST_F(V8ValueConverterImplTest, StripNullFromObjects) { | 364 TEST_F(V8ValueConverterImplTest, StripNullFromObjects) { |
| 364 v8::Context::Scope context_scope(context_); | 365 v8::Context::Scope context_scope(context_); |
| 365 v8::HandleScope handle_scope; | 366 v8::HandleScope handle_scope; |
| 366 | 367 |
| 367 const char* source = "(function() {" | 368 const char* source = "(function() {" |
| 368 "return { foo: undefined, bar: null };" | 369 "return { foo: undefined, bar: null };" |
| 369 "})();"; | 370 "})();"; |
| 370 | 371 |
| 371 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 372 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 372 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 373 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
| 373 ASSERT_FALSE(object.IsEmpty()); | 374 ASSERT_FALSE(object.IsEmpty()); |
| 374 | 375 |
| 375 V8ValueConverterImpl converter; | 376 V8ValueConverterImpl converter; |
| 376 converter.SetStripNullFromObjects(true); | 377 converter.SetStripNullFromObjects(true); |
| 377 | 378 |
| 378 scoped_ptr<DictionaryValue> result( | 379 scoped_ptr<base::DictionaryValue> result( |
| 379 static_cast<DictionaryValue*>(converter.FromV8Value(object, context_))); | 380 static_cast<base::DictionaryValue*>( |
| 381 converter.FromV8Value(object, context_))); |
| 380 ASSERT_TRUE(result.get()); | 382 ASSERT_TRUE(result.get()); |
| 381 EXPECT_EQ(0u, result->size()); | 383 EXPECT_EQ(0u, result->size()); |
| 382 } | 384 } |
| 383 | 385 |
| 384 TEST_F(V8ValueConverterImplTest, RecursiveObjects) { | 386 TEST_F(V8ValueConverterImplTest, RecursiveObjects) { |
| 385 v8::Context::Scope context_scope(context_); | 387 v8::Context::Scope context_scope(context_); |
| 386 v8::HandleScope handle_scope; | 388 v8::HandleScope handle_scope; |
| 387 | 389 |
| 388 V8ValueConverterImpl converter; | 390 V8ValueConverterImpl converter; |
| 389 | 391 |
| 390 v8::Handle<v8::Object> object = v8::Object::New().As<v8::Object>(); | 392 v8::Handle<v8::Object> object = v8::Object::New().As<v8::Object>(); |
| 391 ASSERT_FALSE(object.IsEmpty()); | 393 ASSERT_FALSE(object.IsEmpty()); |
| 392 object->Set(v8::String::New("foo"), v8::String::New("bar")); | 394 object->Set(v8::String::New("foo"), v8::String::New("bar")); |
| 393 object->Set(v8::String::New("obj"), object); | 395 object->Set(v8::String::New("obj"), object); |
| 394 | 396 |
| 395 scoped_ptr<DictionaryValue> object_result( | 397 scoped_ptr<base::DictionaryValue> object_result( |
| 396 static_cast<DictionaryValue*>(converter.FromV8Value(object, context_))); | 398 static_cast<base::DictionaryValue*>( |
| 399 converter.FromV8Value(object, context_))); |
| 397 ASSERT_TRUE(object_result.get()); | 400 ASSERT_TRUE(object_result.get()); |
| 398 EXPECT_EQ(2u, object_result->size()); | 401 EXPECT_EQ(2u, object_result->size()); |
| 399 EXPECT_TRUE(IsNull(object_result.get(), "obj")); | 402 EXPECT_TRUE(IsNull(object_result.get(), "obj")); |
| 400 | 403 |
| 401 v8::Handle<v8::Array> array = v8::Array::New().As<v8::Array>(); | 404 v8::Handle<v8::Array> array = v8::Array::New().As<v8::Array>(); |
| 402 ASSERT_FALSE(array.IsEmpty()); | 405 ASSERT_FALSE(array.IsEmpty()); |
| 403 array->Set(0, v8::String::New("1")); | 406 array->Set(0, v8::String::New("1")); |
| 404 array->Set(1, array); | 407 array->Set(1, array); |
| 405 | 408 |
| 406 scoped_ptr<ListValue> list_result( | 409 scoped_ptr<base::ListValue> list_result( |
| 407 static_cast<ListValue*>(converter.FromV8Value(array, context_))); | 410 static_cast<base::ListValue*>(converter.FromV8Value(array, context_))); |
| 408 ASSERT_TRUE(list_result.get()); | 411 ASSERT_TRUE(list_result.get()); |
| 409 EXPECT_EQ(2u, list_result->GetSize()); | 412 EXPECT_EQ(2u, list_result->GetSize()); |
| 410 EXPECT_TRUE(IsNull(list_result.get(), 1)); | 413 EXPECT_TRUE(IsNull(list_result.get(), 1)); |
| 411 } | 414 } |
| 412 | 415 |
| 413 // Do not try and convert any named callbacks including getters. | 416 // Do not try and convert any named callbacks including getters. |
| 414 TEST_F(V8ValueConverterImplTest, ObjectGetters) { | 417 TEST_F(V8ValueConverterImplTest, ObjectGetters) { |
| 415 v8::Context::Scope context_scope(context_); | 418 v8::Context::Scope context_scope(context_); |
| 416 v8::HandleScope handle_scope; | 419 v8::HandleScope handle_scope; |
| 417 | 420 |
| 418 const char* source = "(function() {" | 421 const char* source = "(function() {" |
| 419 "var a = {};" | 422 "var a = {};" |
| 420 "a.__defineGetter__('foo', function() { return 'bar'; });" | 423 "a.__defineGetter__('foo', function() { return 'bar'; });" |
| 421 "return a;" | 424 "return a;" |
| 422 "})();"; | 425 "})();"; |
| 423 | 426 |
| 424 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 427 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 425 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 428 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
| 426 ASSERT_FALSE(object.IsEmpty()); | 429 ASSERT_FALSE(object.IsEmpty()); |
| 427 | 430 |
| 428 V8ValueConverterImpl converter; | 431 V8ValueConverterImpl converter; |
| 429 scoped_ptr<DictionaryValue> result( | 432 scoped_ptr<base::DictionaryValue> result( |
| 430 static_cast<DictionaryValue*>(converter.FromV8Value(object, context_))); | 433 static_cast<base::DictionaryValue*>( |
| 434 converter.FromV8Value(object, context_))); |
| 431 ASSERT_TRUE(result.get()); | 435 ASSERT_TRUE(result.get()); |
| 432 EXPECT_EQ(0u, result->size()); | 436 EXPECT_EQ(0u, result->size()); |
| 433 } | 437 } |
| 434 | 438 |
| 435 // Do not try and convert any named callbacks including getters. | 439 // Do not try and convert any named callbacks including getters. |
| 436 TEST_F(V8ValueConverterImplTest, ObjectWithInternalFieldsGetters) { | 440 TEST_F(V8ValueConverterImplTest, ObjectWithInternalFieldsGetters) { |
| 437 v8::Context::Scope context_scope(context_); | 441 v8::Context::Scope context_scope(context_); |
| 438 v8::HandleScope handle_scope; | 442 v8::HandleScope handle_scope; |
| 439 | 443 |
| 440 v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); | 444 v8::Handle<v8::ObjectTemplate> object_template = v8::ObjectTemplate::New(); |
| 441 object_template->SetInternalFieldCount(1); | 445 object_template->SetInternalFieldCount(1); |
| 442 object_template->SetAccessor(v8::String::New("foo"), NamedCallbackGetter); | 446 object_template->SetAccessor(v8::String::New("foo"), NamedCallbackGetter); |
| 443 v8::Handle<v8::Object> object = object_template->NewInstance(); | 447 v8::Handle<v8::Object> object = object_template->NewInstance(); |
| 444 ASSERT_FALSE(object.IsEmpty()); | 448 ASSERT_FALSE(object.IsEmpty()); |
| 445 object->Set(v8::String::New("a"), v8::String::New("b")); | 449 object->Set(v8::String::New("a"), v8::String::New("b")); |
| 446 | 450 |
| 447 V8ValueConverterImpl converter; | 451 V8ValueConverterImpl converter; |
| 448 scoped_ptr<DictionaryValue> result( | 452 scoped_ptr<base::DictionaryValue> result( |
| 449 static_cast<DictionaryValue*>(converter.FromV8Value(object, context_))); | 453 static_cast<base::DictionaryValue*>( |
| 454 converter.FromV8Value(object, context_))); |
| 450 ASSERT_TRUE(result.get()); | 455 ASSERT_TRUE(result.get()); |
| 451 EXPECT_EQ(1u, result->size()); | 456 EXPECT_EQ(1u, result->size()); |
| 452 } | 457 } |
| 453 | 458 |
| 454 TEST_F(V8ValueConverterImplTest, WeirdProperties) { | 459 TEST_F(V8ValueConverterImplTest, WeirdProperties) { |
| 455 v8::Context::Scope context_scope(context_); | 460 v8::Context::Scope context_scope(context_); |
| 456 v8::HandleScope handle_scope; | 461 v8::HandleScope handle_scope; |
| 457 | 462 |
| 458 const char* source = "(function() {" | 463 const char* source = "(function() {" |
| 459 "return {" | 464 "return {" |
| 460 "1: 'foo'," | 465 "1: 'foo'," |
| 461 "'2': 'bar'," | 466 "'2': 'bar'," |
| 462 "true: 'baz'," | 467 "true: 'baz'," |
| 463 "false: 'qux'," | 468 "false: 'qux'," |
| 464 "null: 'quux'," | 469 "null: 'quux'," |
| 465 "undefined: 'oops'" | 470 "undefined: 'oops'" |
| 466 "};" | 471 "};" |
| 467 "})();"; | 472 "})();"; |
| 468 | 473 |
| 469 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 474 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 470 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 475 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
| 471 ASSERT_FALSE(object.IsEmpty()); | 476 ASSERT_FALSE(object.IsEmpty()); |
| 472 | 477 |
| 473 V8ValueConverterImpl converter; | 478 V8ValueConverterImpl converter; |
| 474 scoped_ptr<Value> actual(converter.FromV8Value(object, context_)); | 479 scoped_ptr<base::Value> actual(converter.FromV8Value(object, context_)); |
| 475 | 480 |
| 476 scoped_ptr<Value> expected = base::test::ParseJson( | 481 scoped_ptr<base::Value> expected = base::test::ParseJson( |
| 477 "{ \n" | 482 "{ \n" |
| 478 " \"1\": \"foo\", \n" | 483 " \"1\": \"foo\", \n" |
| 479 " \"2\": \"bar\", \n" | 484 " \"2\": \"bar\", \n" |
| 480 " \"true\": \"baz\", \n" | 485 " \"true\": \"baz\", \n" |
| 481 " \"false\": \"qux\", \n" | 486 " \"false\": \"qux\", \n" |
| 482 " \"null\": \"quux\", \n" | 487 " \"null\": \"quux\", \n" |
| 483 " \"undefined\": \"oops\", \n" | 488 " \"undefined\": \"oops\", \n" |
| 484 "}"); | 489 "}"); |
| 485 | 490 |
| 486 EXPECT_TRUE(expected->Equals(actual.get())); | 491 EXPECT_TRUE(expected->Equals(actual.get())); |
| 487 } | 492 } |
| 488 | 493 |
| 489 TEST_F(V8ValueConverterImplTest, ArrayGetters) { | 494 TEST_F(V8ValueConverterImplTest, ArrayGetters) { |
| 490 v8::Context::Scope context_scope(context_); | 495 v8::Context::Scope context_scope(context_); |
| 491 v8::HandleScope handle_scope; | 496 v8::HandleScope handle_scope; |
| 492 | 497 |
| 493 const char* source = "(function() {" | 498 const char* source = "(function() {" |
| 494 "var a = [0];" | 499 "var a = [0];" |
| 495 "a.__defineGetter__(1, function() { return 'bar'; });" | 500 "a.__defineGetter__(1, function() { return 'bar'; });" |
| 496 "return a;" | 501 "return a;" |
| 497 "})();"; | 502 "})();"; |
| 498 | 503 |
| 499 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 504 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 500 v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); | 505 v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); |
| 501 ASSERT_FALSE(array.IsEmpty()); | 506 ASSERT_FALSE(array.IsEmpty()); |
| 502 | 507 |
| 503 V8ValueConverterImpl converter; | 508 V8ValueConverterImpl converter; |
| 504 scoped_ptr<ListValue> result( | 509 scoped_ptr<base::ListValue> result( |
| 505 static_cast<ListValue*>(converter.FromV8Value(array, context_))); | 510 static_cast<base::ListValue*>(converter.FromV8Value(array, context_))); |
| 506 ASSERT_TRUE(result.get()); | 511 ASSERT_TRUE(result.get()); |
| 507 EXPECT_EQ(2u, result->GetSize()); | 512 EXPECT_EQ(2u, result->GetSize()); |
| 508 } | 513 } |
| 509 | 514 |
| 510 TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) { | 515 TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) { |
| 511 v8::Context::Scope context_scope(context_); | 516 v8::Context::Scope context_scope(context_); |
| 512 v8::HandleScope handle_scope; | 517 v8::HandleScope handle_scope; |
| 513 | 518 |
| 514 v8::Handle<v8::Object> object; | 519 v8::Handle<v8::Object> object; |
| 515 { | 520 { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 526 const char* source = "(function() {" | 531 const char* source = "(function() {" |
| 527 "return [ undefined, null, function(){} ];" | 532 "return [ undefined, null, function(){} ];" |
| 528 "})();"; | 533 "})();"; |
| 529 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 534 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
| 530 array = script->Run().As<v8::Array>(); | 535 array = script->Run().As<v8::Array>(); |
| 531 ASSERT_FALSE(array.IsEmpty()); | 536 ASSERT_FALSE(array.IsEmpty()); |
| 532 } | 537 } |
| 533 | 538 |
| 534 V8ValueConverterImpl converter; | 539 V8ValueConverterImpl converter; |
| 535 | 540 |
| 536 scoped_ptr<Value> actual_object(converter.FromV8Value(object, context_)); | 541 scoped_ptr<base::Value> actual_object( |
| 537 EXPECT_TRUE(Value::Equals(base::test::ParseJson("{ \"bar\": null }").get(), | 542 converter.FromV8Value(object, context_)); |
| 538 actual_object.get())); | 543 EXPECT_TRUE(base::Value::Equals( |
| 544 base::test::ParseJson("{ \"bar\": null }").get(), actual_object.get())); |
| 539 | 545 |
| 540 // Everything is null because JSON stringification preserves array length. | 546 // Everything is null because JSON stringification preserves array length. |
| 541 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); | 547 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); |
| 542 EXPECT_TRUE(Value::Equals(base::test::ParseJson("[ null, null, null ]").get(), | 548 EXPECT_TRUE(base::Value::Equals( |
| 543 actual_array.get())); | 549 base::test::ParseJson("[ null, null, null ]").get(), actual_array.get())); |
| 544 } | 550 } |
| 545 | 551 |
| 546 } // namespace content | 552 } // namespace content |
| OLD | NEW |