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/values.h" | 9 #include "base/values.h" |
9 #include "content/renderer/v8_value_converter_impl.h" | 10 #include "content/renderer/v8_value_converter_impl.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
11 #include "v8/include/v8.h" | 12 #include "v8/include/v8.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // A dumb getter for an object's named callback. | 18 // A dumb getter for an object's named callback. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 ASSERT_TRUE(list->Get(0, &temp)); | 158 ASSERT_TRUE(list->Get(0, &temp)); |
158 EXPECT_EQ(Value::TYPE_NULL, temp->GetType()); | 159 EXPECT_EQ(Value::TYPE_NULL, temp->GetType()); |
159 } | 160 } |
160 } | 161 } |
161 | 162 |
162 // Context for the JavaScript in the test. | 163 // Context for the JavaScript in the test. |
163 v8::Persistent<v8::Context> context_; | 164 v8::Persistent<v8::Context> context_; |
164 }; | 165 }; |
165 | 166 |
166 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { | 167 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { |
167 DictionaryValue original_root; | 168 scoped_ptr<Value> original_root = base::ParseJson( |
168 original_root.Set("null", Value::CreateNullValue()); | 169 "{ \n" |
169 original_root.Set("true", Value::CreateBooleanValue(true)); | 170 " \"null\": null, \n" |
170 original_root.Set("false", Value::CreateBooleanValue(false)); | 171 " \"true\": true, \n" |
171 original_root.Set("positive-int", Value::CreateIntegerValue(42)); | 172 " \"false\": false, \n" |
172 original_root.Set("negative-int", Value::CreateIntegerValue(-42)); | 173 " \"positive-int\": 42, \n" |
173 original_root.Set("zero", Value::CreateIntegerValue(0)); | 174 " \"negative-int\": -42, \n" |
174 original_root.Set("double", Value::CreateDoubleValue(88.8)); | 175 " \"zero\": 0, \n" |
175 original_root.Set("big-integral-double", | 176 " \"double\": 88.8, \n" |
176 Value::CreateDoubleValue(pow(2.0, 53))); | 177 " \"big-integral-double\": 9007199254740992.0, \n" // 2.0^53 |
177 original_root.Set("string", Value::CreateStringValue("foobar")); | 178 " \"string\": \"foobar\", \n" |
178 original_root.Set("empty-string", Value::CreateStringValue("")); | 179 " \"empty-string\": \"\", \n" |
179 | 180 " \"dictionary\": { \n" |
180 DictionaryValue* original_sub1 = new DictionaryValue(); | 181 " \"foo\": \"bar\",\n" |
181 original_sub1->Set("foo", Value::CreateStringValue("bar")); | 182 " \"hot\": \"dog\",\n" |
182 original_sub1->Set("hot", Value::CreateStringValue("dog")); | 183 " }, \n" |
183 original_root.Set("dictionary", original_sub1); | 184 " \"empty-dictionary\": {}, \n" |
184 original_root.Set("empty-dictionary", new DictionaryValue()); | 185 " \"list\": [ \"monkey\", \"balls\" ], \n" |
185 | 186 " \"empty-list\": [], \n" |
186 ListValue* original_sub2 = new ListValue(); | 187 "}"); |
187 original_sub2->Append(Value::CreateStringValue("monkey")); | |
188 original_sub2->Append(Value::CreateStringValue("balls")); | |
189 original_root.Set("list", original_sub2); | |
190 original_root.Set("empty-list", new ListValue()); | |
191 | 188 |
192 v8::Context::Scope context_scope(context_); | 189 v8::Context::Scope context_scope(context_); |
193 v8::HandleScope handle_scope; | 190 v8::HandleScope handle_scope; |
194 | 191 |
195 V8ValueConverterImpl converter; | 192 V8ValueConverterImpl converter; |
196 v8::Handle<v8::Object> v8_object = | 193 v8::Handle<v8::Object> v8_object = |
197 converter.ToV8Value(&original_root, context_).As<v8::Object>(); | 194 converter.ToV8Value(original_root.get(), context_).As<v8::Object>(); |
198 ASSERT_FALSE(v8_object.IsEmpty()); | 195 ASSERT_FALSE(v8_object.IsEmpty()); |
199 | 196 |
200 EXPECT_EQ(original_root.size(), v8_object->GetPropertyNames()->Length()); | 197 EXPECT_EQ(static_cast<const DictionaryValue&>(*original_root).size(), |
| 198 v8_object->GetPropertyNames()->Length()); |
201 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); | 199 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); |
202 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); | 200 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); |
203 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); | 201 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); |
204 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); | 202 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); |
205 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); | 203 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); |
206 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); | 204 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); |
207 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); | 205 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); |
208 EXPECT_TRUE( | 206 EXPECT_TRUE( |
209 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); | 207 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); |
210 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); | 208 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); |
211 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); | 209 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); |
212 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); | 210 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); |
213 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); | 211 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); |
214 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); | 212 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); |
215 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); | 213 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); |
216 | 214 |
217 scoped_ptr<Value> new_root(converter.FromV8Value(v8_object, context_)); | 215 scoped_ptr<Value> new_root(converter.FromV8Value(v8_object, context_)); |
218 EXPECT_NE(&original_root, new_root.get()); | 216 EXPECT_NE(original_root.get(), new_root.get()); |
219 EXPECT_TRUE(original_root.Equals(new_root.get())); | 217 EXPECT_TRUE(original_root->Equals(new_root.get())); |
220 } | 218 } |
221 | 219 |
222 TEST_F(V8ValueConverterImplTest, KeysWithDots) { | 220 TEST_F(V8ValueConverterImplTest, KeysWithDots) { |
223 DictionaryValue original; | 221 scoped_ptr<Value> original = base::ParseJson("{ \"foo.bar\": \"baz\" }"); |
224 original.SetWithoutPathExpansion("foo.bar", Value::CreateStringValue("baz")); | |
225 | 222 |
226 v8::Context::Scope context_scope(context_); | 223 v8::Context::Scope context_scope(context_); |
227 v8::HandleScope handle_scope; | 224 v8::HandleScope handle_scope; |
228 | 225 |
229 V8ValueConverterImpl converter; | 226 V8ValueConverterImpl converter; |
230 scoped_ptr<Value> copy( | 227 scoped_ptr<Value> copy( |
231 converter.FromV8Value( | 228 converter.FromV8Value( |
232 converter.ToV8Value(&original, context_), context_)); | 229 converter.ToV8Value(original.get(), context_), context_)); |
233 | 230 |
234 EXPECT_TRUE(original.Equals(copy.get())); | 231 EXPECT_TRUE(original->Equals(copy.get())); |
235 } | 232 } |
236 | 233 |
237 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { | 234 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { |
238 v8::Context::Scope context_scope(context_); | 235 v8::Context::Scope context_scope(context_); |
239 v8::HandleScope handle_scope; | 236 v8::HandleScope handle_scope; |
240 | 237 |
241 // Set up objects to throw when reading or writing 'foo'. | 238 // Set up objects to throw when reading or writing 'foo'. |
242 const char* source = | 239 const char* source = |
243 "Object.prototype.__defineSetter__('foo', " | 240 "Object.prototype.__defineSetter__('foo', " |
244 " function() { throw new Error('muah!'); });" | 241 " function() { throw new Error('muah!'); });" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 // Converting from v8 value should replace the first item with null. | 289 // Converting from v8 value should replace the first item with null. |
293 V8ValueConverterImpl converter; | 290 V8ValueConverterImpl converter; |
294 scoped_ptr<ListValue> converted(static_cast<ListValue*>( | 291 scoped_ptr<ListValue> converted(static_cast<ListValue*>( |
295 converter.FromV8Value(array, context_))); | 292 converter.FromV8Value(array, context_))); |
296 ASSERT_TRUE(converted.get()); | 293 ASSERT_TRUE(converted.get()); |
297 // http://code.google.com/p/v8/issues/detail?id=1342 | 294 // http://code.google.com/p/v8/issues/detail?id=1342 |
298 EXPECT_EQ(2u, converted->GetSize()); | 295 EXPECT_EQ(2u, converted->GetSize()); |
299 EXPECT_TRUE(IsNull(converted.get(), 0)); | 296 EXPECT_TRUE(IsNull(converted.get(), 0)); |
300 | 297 |
301 // Converting to v8 value should drop the first item and leave a hole. | 298 // Converting to v8 value should drop the first item and leave a hole. |
302 converted.reset(new ListValue()); | 299 converted.reset(static_cast<ListValue*>( |
303 converted->Append(Value::CreateStringValue("foo")); | 300 base::ParseJson("[ \"foo\", \"bar\" ]").release())); |
304 converted->Append(Value::CreateStringValue("bar")); | |
305 v8::Handle<v8::Array> copy = | 301 v8::Handle<v8::Array> copy = |
306 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); | 302 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); |
307 ASSERT_FALSE(copy.IsEmpty()); | 303 ASSERT_FALSE(copy.IsEmpty()); |
308 EXPECT_EQ(2u, copy->Length()); | 304 EXPECT_EQ(2u, copy->Length()); |
309 EXPECT_EQ("bar", GetString(copy, 1)); | 305 EXPECT_EQ("bar", GetString(copy, 1)); |
310 } | 306 } |
311 | 307 |
312 TEST_F(V8ValueConverterImplTest, WeirdTypes) { | 308 TEST_F(V8ValueConverterImplTest, WeirdTypes) { |
313 v8::Context::Scope context_scope(context_); | 309 v8::Context::Scope context_scope(context_); |
314 v8::HandleScope handle_scope; | 310 v8::HandleScope handle_scope; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 "};" | 465 "};" |
470 "})();"; | 466 "})();"; |
471 | 467 |
472 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 468 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
473 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 469 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
474 ASSERT_FALSE(object.IsEmpty()); | 470 ASSERT_FALSE(object.IsEmpty()); |
475 | 471 |
476 V8ValueConverterImpl converter; | 472 V8ValueConverterImpl converter; |
477 scoped_ptr<Value> actual(converter.FromV8Value(object, context_)); | 473 scoped_ptr<Value> actual(converter.FromV8Value(object, context_)); |
478 | 474 |
479 DictionaryValue expected; | 475 scoped_ptr<Value> expected = base::ParseJson( |
480 expected.SetString("1", "foo"); | 476 "{ \n" |
481 expected.SetString("2", "bar"); | 477 " \"1\": \"foo\", \n" |
482 expected.SetString("true", "baz"); | 478 " \"2\": \"bar\", \n" |
483 expected.SetString("false", "qux"); | 479 " \"true\": \"baz\", \n" |
484 expected.SetString("null", "quux"); | 480 " \"false\": \"qux\", \n" |
485 expected.SetString("undefined", "oops"); | 481 " \"null\": \"quux\", \n" |
| 482 " \"undefined\": \"oops\", \n" |
| 483 "}"); |
486 | 484 |
487 EXPECT_TRUE(expected.Equals(actual.get())); | 485 EXPECT_TRUE(expected->Equals(actual.get())); |
488 } | 486 } |
489 | 487 |
490 TEST_F(V8ValueConverterImplTest, ArrayGetters) { | 488 TEST_F(V8ValueConverterImplTest, ArrayGetters) { |
491 v8::Context::Scope context_scope(context_); | 489 v8::Context::Scope context_scope(context_); |
492 v8::HandleScope handle_scope; | 490 v8::HandleScope handle_scope; |
493 | 491 |
494 const char* source = "(function() {" | 492 const char* source = "(function() {" |
495 "var a = [0];" | 493 "var a = [0];" |
496 "a.__defineGetter__(1, function() { return 'bar'; });" | 494 "a.__defineGetter__(1, function() { return 'bar'; });" |
497 "return a;" | 495 "return a;" |
(...skipping 29 matching lines...) Expand all Loading... |
527 const char* source = "(function() {" | 525 const char* source = "(function() {" |
528 "return [ undefined, null, function(){} ];" | 526 "return [ undefined, null, function(){} ];" |
529 "})();"; | 527 "})();"; |
530 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 528 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
531 array = script->Run().As<v8::Array>(); | 529 array = script->Run().As<v8::Array>(); |
532 ASSERT_FALSE(array.IsEmpty()); | 530 ASSERT_FALSE(array.IsEmpty()); |
533 } | 531 } |
534 | 532 |
535 V8ValueConverterImpl converter; | 533 V8ValueConverterImpl converter; |
536 | 534 |
537 DictionaryValue expected_object; | |
538 expected_object.Set("bar", Value::CreateNullValue()); | |
539 scoped_ptr<Value> actual_object(converter.FromV8Value(object, context_)); | 535 scoped_ptr<Value> actual_object(converter.FromV8Value(object, context_)); |
540 EXPECT_TRUE(Value::Equals(&expected_object, actual_object.get())); | 536 EXPECT_TRUE(Value::Equals(base::ParseJson("{ \"bar\": null }").get(), |
| 537 actual_object.get())); |
541 | 538 |
542 ListValue expected_array; | |
543 // Everything is null because JSON stringification preserves array length. | 539 // Everything is null because JSON stringification preserves array length. |
544 expected_array.Append(Value::CreateNullValue()); | |
545 expected_array.Append(Value::CreateNullValue()); | |
546 expected_array.Append(Value::CreateNullValue()); | |
547 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); | 540 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); |
548 EXPECT_TRUE(Value::Equals(&expected_array, actual_array.get())); | 541 EXPECT_TRUE(Value::Equals(base::ParseJson("[ null, null, null ]").get(), |
| 542 actual_array.get())); |
549 } | 543 } |
550 | 544 |
551 } // namespace content | 545 } // namespace content |
OLD | NEW |