| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 13 #include "base/test/values_test_util.h" | 13 #include "base/test/values_test_util.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "content/child/v8_value_converter_impl.h" | 15 #include "content/child/v8_value_converter_impl.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" | |
| 18 #include "v8/include/v8.h" | 17 #include "v8/include/v8.h" |
| 19 | 18 |
| 20 namespace content { | 19 namespace content { |
| 21 | 20 |
| 22 // To improve the performance of | 21 // To improve the performance of |
| 23 // V8ValueConverterImpl::UpdateAndCheckUniqueness, identity hashes of objects | 22 // V8ValueConverterImpl::UpdateAndCheckUniqueness, identity hashes of objects |
| 24 // are used during checking for duplicates. For testing purposes we need to | 23 // are used during checking for duplicates. For testing purposes we need to |
| 25 // ignore the hash sometimes. Create this helper object to avoid using identity | 24 // ignore the hash sometimes. Create this helper object to avoid using identity |
| 26 // hashes for the lifetime of the helper. | 25 // hashes for the lifetime of the helper. |
| 27 class ScopedAvoidIdentityHashForTesting { | 26 class ScopedAvoidIdentityHashForTesting { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 converter.ToV8Value(original.get(), context), context)); | 280 converter.ToV8Value(original.get(), context), context)); |
| 282 | 281 |
| 283 EXPECT_TRUE(original->Equals(copy.get())); | 282 EXPECT_TRUE(original->Equals(copy.get())); |
| 284 } | 283 } |
| 285 | 284 |
| 286 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { | 285 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { |
| 287 v8::HandleScope handle_scope(isolate_); | 286 v8::HandleScope handle_scope(isolate_); |
| 288 v8::Local<v8::Context> context = | 287 v8::Local<v8::Context> context = |
| 289 v8::Local<v8::Context>::New(isolate_, context_); | 288 v8::Local<v8::Context>::New(isolate_, context_); |
| 290 v8::Context::Scope context_scope(context); | 289 v8::Context::Scope context_scope(context); |
| 291 blink::WebScopedMicrotaskSuppression microtasks_scope; | 290 v8::MicrotasksScope microtasks( |
| 291 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 292 | 292 |
| 293 // Set up objects to throw when reading or writing 'foo'. | 293 // Set up objects to throw when reading or writing 'foo'. |
| 294 const char* source = | 294 const char* source = |
| 295 "Object.prototype.__defineSetter__('foo', " | 295 "Object.prototype.__defineSetter__('foo', " |
| 296 " function() { throw new Error('muah!'); });" | 296 " function() { throw new Error('muah!'); });" |
| 297 "Object.prototype.__defineGetter__('foo', " | 297 "Object.prototype.__defineGetter__('foo', " |
| 298 " function() { throw new Error('muah!'); });"; | 298 " function() { throw new Error('muah!'); });"; |
| 299 | 299 |
| 300 v8::Local<v8::Script> script( | 300 v8::Local<v8::Script> script( |
| 301 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); | 301 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 324 EXPECT_FALSE(copy.IsEmpty()); | 324 EXPECT_FALSE(copy.IsEmpty()); |
| 325 EXPECT_EQ(2u, copy->GetPropertyNames()->Length()); | 325 EXPECT_EQ(2u, copy->GetPropertyNames()->Length()); |
| 326 EXPECT_EQ("bar", GetString(copy, "bar")); | 326 EXPECT_EQ("bar", GetString(copy, "bar")); |
| 327 } | 327 } |
| 328 | 328 |
| 329 TEST_F(V8ValueConverterImplTest, ArrayExceptions) { | 329 TEST_F(V8ValueConverterImplTest, ArrayExceptions) { |
| 330 v8::HandleScope handle_scope(isolate_); | 330 v8::HandleScope handle_scope(isolate_); |
| 331 v8::Local<v8::Context> context = | 331 v8::Local<v8::Context> context = |
| 332 v8::Local<v8::Context>::New(isolate_, context_); | 332 v8::Local<v8::Context>::New(isolate_, context_); |
| 333 v8::Context::Scope context_scope(context); | 333 v8::Context::Scope context_scope(context); |
| 334 blink::WebScopedMicrotaskSuppression microtasks_scope; | 334 v8::MicrotasksScope microtasks( |
| 335 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 335 | 336 |
| 336 const char* source = "(function() {" | 337 const char* source = "(function() {" |
| 337 "var arr = [];" | 338 "var arr = [];" |
| 338 "arr.__defineSetter__(0, " | 339 "arr.__defineSetter__(0, " |
| 339 " function() { throw new Error('muah!'); });" | 340 " function() { throw new Error('muah!'); });" |
| 340 "arr.__defineGetter__(0, " | 341 "arr.__defineGetter__(0, " |
| 341 " function() { throw new Error('muah!'); });" | 342 " function() { throw new Error('muah!'); });" |
| 342 "arr[1] = 'bar';" | 343 "arr[1] = 'bar';" |
| 343 "return arr;" | 344 "return arr;" |
| 344 "})();"; | 345 "})();"; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 regex, | 402 regex, |
| 402 base::Value::TYPE_STRING, | 403 base::Value::TYPE_STRING, |
| 403 scoped_ptr<base::Value>(new base::StringValue("/./"))); | 404 scoped_ptr<base::Value>(new base::StringValue("/./"))); |
| 404 } | 405 } |
| 405 | 406 |
| 406 TEST_F(V8ValueConverterImplTest, Prototype) { | 407 TEST_F(V8ValueConverterImplTest, Prototype) { |
| 407 v8::HandleScope handle_scope(isolate_); | 408 v8::HandleScope handle_scope(isolate_); |
| 408 v8::Local<v8::Context> context = | 409 v8::Local<v8::Context> context = |
| 409 v8::Local<v8::Context>::New(isolate_, context_); | 410 v8::Local<v8::Context>::New(isolate_, context_); |
| 410 v8::Context::Scope context_scope(context); | 411 v8::Context::Scope context_scope(context); |
| 411 blink::WebScopedMicrotaskSuppression microtasks_scope; | 412 v8::MicrotasksScope microtasks( |
| 413 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 412 | 414 |
| 413 const char* source = "(function() {" | 415 const char* source = "(function() {" |
| 414 "Object.prototype.foo = 'foo';" | 416 "Object.prototype.foo = 'foo';" |
| 415 "return {};" | 417 "return {};" |
| 416 "})();"; | 418 "})();"; |
| 417 | 419 |
| 418 v8::Local<v8::Script> script( | 420 v8::Local<v8::Script> script( |
| 419 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); | 421 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); |
| 420 v8::Local<v8::Object> object = script->Run().As<v8::Object>(); | 422 v8::Local<v8::Object> object = script->Run().As<v8::Object>(); |
| 421 ASSERT_FALSE(object.IsEmpty()); | 423 ASSERT_FALSE(object.IsEmpty()); |
| 422 | 424 |
| 423 V8ValueConverterImpl converter; | 425 V8ValueConverterImpl converter; |
| 424 scoped_ptr<base::DictionaryValue> result( | 426 scoped_ptr<base::DictionaryValue> result( |
| 425 static_cast<base::DictionaryValue*>( | 427 static_cast<base::DictionaryValue*>( |
| 426 converter.FromV8Value(object, context))); | 428 converter.FromV8Value(object, context))); |
| 427 ASSERT_TRUE(result.get()); | 429 ASSERT_TRUE(result.get()); |
| 428 EXPECT_EQ(0u, result->size()); | 430 EXPECT_EQ(0u, result->size()); |
| 429 } | 431 } |
| 430 | 432 |
| 431 TEST_F(V8ValueConverterImplTest, StripNullFromObjects) { | 433 TEST_F(V8ValueConverterImplTest, StripNullFromObjects) { |
| 432 v8::HandleScope handle_scope(isolate_); | 434 v8::HandleScope handle_scope(isolate_); |
| 433 v8::Local<v8::Context> context = | 435 v8::Local<v8::Context> context = |
| 434 v8::Local<v8::Context>::New(isolate_, context_); | 436 v8::Local<v8::Context>::New(isolate_, context_); |
| 435 v8::Context::Scope context_scope(context); | 437 v8::Context::Scope context_scope(context); |
| 436 blink::WebScopedMicrotaskSuppression microtasks_scope; | 438 v8::MicrotasksScope microtasks( |
| 439 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 437 | 440 |
| 438 const char* source = "(function() {" | 441 const char* source = "(function() {" |
| 439 "return { foo: undefined, bar: null };" | 442 "return { foo: undefined, bar: null };" |
| 440 "})();"; | 443 "})();"; |
| 441 | 444 |
| 442 v8::Local<v8::Script> script( | 445 v8::Local<v8::Script> script( |
| 443 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); | 446 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); |
| 444 v8::Local<v8::Object> object = script->Run().As<v8::Object>(); | 447 v8::Local<v8::Object> object = script->Run().As<v8::Object>(); |
| 445 ASSERT_FALSE(object.IsEmpty()); | 448 ASSERT_FALSE(object.IsEmpty()); |
| 446 | 449 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 ASSERT_TRUE(list_result.get()); | 488 ASSERT_TRUE(list_result.get()); |
| 486 EXPECT_EQ(2u, list_result->GetSize()); | 489 EXPECT_EQ(2u, list_result->GetSize()); |
| 487 EXPECT_TRUE(IsNull(list_result.get(), 1)); | 490 EXPECT_TRUE(IsNull(list_result.get(), 1)); |
| 488 } | 491 } |
| 489 | 492 |
| 490 TEST_F(V8ValueConverterImplTest, WeirdProperties) { | 493 TEST_F(V8ValueConverterImplTest, WeirdProperties) { |
| 491 v8::HandleScope handle_scope(isolate_); | 494 v8::HandleScope handle_scope(isolate_); |
| 492 v8::Local<v8::Context> context = | 495 v8::Local<v8::Context> context = |
| 493 v8::Local<v8::Context>::New(isolate_, context_); | 496 v8::Local<v8::Context>::New(isolate_, context_); |
| 494 v8::Context::Scope context_scope(context); | 497 v8::Context::Scope context_scope(context); |
| 495 blink::WebScopedMicrotaskSuppression microtasks_scope; | 498 v8::MicrotasksScope microtasks( |
| 499 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 496 | 500 |
| 497 const char* source = "(function() {" | 501 const char* source = "(function() {" |
| 498 "return {" | 502 "return {" |
| 499 "1: 'foo'," | 503 "1: 'foo'," |
| 500 "'2': 'bar'," | 504 "'2': 'bar'," |
| 501 "true: 'baz'," | 505 "true: 'baz'," |
| 502 "false: 'qux'," | 506 "false: 'qux'," |
| 503 "null: 'quux'," | 507 "null: 'quux'," |
| 504 "undefined: 'oops'" | 508 "undefined: 'oops'" |
| 505 "};" | 509 "};" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 524 "}"); | 528 "}"); |
| 525 | 529 |
| 526 EXPECT_TRUE(expected->Equals(actual.get())); | 530 EXPECT_TRUE(expected->Equals(actual.get())); |
| 527 } | 531 } |
| 528 | 532 |
| 529 TEST_F(V8ValueConverterImplTest, ArrayGetters) { | 533 TEST_F(V8ValueConverterImplTest, ArrayGetters) { |
| 530 v8::HandleScope handle_scope(isolate_); | 534 v8::HandleScope handle_scope(isolate_); |
| 531 v8::Local<v8::Context> context = | 535 v8::Local<v8::Context> context = |
| 532 v8::Local<v8::Context>::New(isolate_, context_); | 536 v8::Local<v8::Context>::New(isolate_, context_); |
| 533 v8::Context::Scope context_scope(context); | 537 v8::Context::Scope context_scope(context); |
| 534 blink::WebScopedMicrotaskSuppression microtasks_scope; | 538 v8::MicrotasksScope microtasks( |
| 539 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 535 | 540 |
| 536 const char* source = "(function() {" | 541 const char* source = "(function() {" |
| 537 "var a = [0];" | 542 "var a = [0];" |
| 538 "a.__defineGetter__(1, function() { return 'bar'; });" | 543 "a.__defineGetter__(1, function() { return 'bar'; });" |
| 539 "return a;" | 544 "return a;" |
| 540 "})();"; | 545 "})();"; |
| 541 | 546 |
| 542 v8::Local<v8::Script> script( | 547 v8::Local<v8::Script> script( |
| 543 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); | 548 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); |
| 544 v8::Local<v8::Array> array = script->Run().As<v8::Array>(); | 549 v8::Local<v8::Array> array = script->Run().As<v8::Array>(); |
| 545 ASSERT_FALSE(array.IsEmpty()); | 550 ASSERT_FALSE(array.IsEmpty()); |
| 546 | 551 |
| 547 V8ValueConverterImpl converter; | 552 V8ValueConverterImpl converter; |
| 548 scoped_ptr<base::ListValue> result( | 553 scoped_ptr<base::ListValue> result( |
| 549 static_cast<base::ListValue*>(converter.FromV8Value(array, context))); | 554 static_cast<base::ListValue*>(converter.FromV8Value(array, context))); |
| 550 ASSERT_TRUE(result.get()); | 555 ASSERT_TRUE(result.get()); |
| 551 EXPECT_EQ(2u, result->GetSize()); | 556 EXPECT_EQ(2u, result->GetSize()); |
| 552 } | 557 } |
| 553 | 558 |
| 554 TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) { | 559 TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) { |
| 555 v8::HandleScope handle_scope(isolate_); | 560 v8::HandleScope handle_scope(isolate_); |
| 556 v8::Local<v8::Context> context = | 561 v8::Local<v8::Context> context = |
| 557 v8::Local<v8::Context>::New(isolate_, context_); | 562 v8::Local<v8::Context>::New(isolate_, context_); |
| 558 v8::Context::Scope context_scope(context); | 563 v8::Context::Scope context_scope(context); |
| 559 blink::WebScopedMicrotaskSuppression microtasks_scope; | 564 v8::MicrotasksScope microtasks( |
| 565 isolate_, v8::MicrotasksScope::kDoNotRunMicrotasks); |
| 560 | 566 |
| 561 v8::Local<v8::Object> object; | 567 v8::Local<v8::Object> object; |
| 562 { | 568 { |
| 563 const char* source = "(function() {" | 569 const char* source = "(function() {" |
| 564 "return { foo: undefined, bar: null, baz: function(){} };" | 570 "return { foo: undefined, bar: null, baz: function(){} };" |
| 565 "})();"; | 571 "})();"; |
| 566 v8::Local<v8::Script> script( | 572 v8::Local<v8::Script> script( |
| 567 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); | 573 v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); |
| 568 object = script->Run().As<v8::Object>(); | 574 object = script->Run().As<v8::Object>(); |
| 569 ASSERT_FALSE(object.IsEmpty()); | 575 ASSERT_FALSE(object.IsEmpty()); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 EXPECT_TRUE( | 884 EXPECT_TRUE( |
| 879 base::Value::Equals(reference_number_value.get(), number_value.get())); | 885 base::Value::Equals(reference_number_value.get(), number_value.get())); |
| 880 | 886 |
| 881 v8::Local<v8::Primitive> undefined(v8::Undefined(isolate_)); | 887 v8::Local<v8::Primitive> undefined(v8::Undefined(isolate_)); |
| 882 scoped_ptr<base::Value> undefined_value( | 888 scoped_ptr<base::Value> undefined_value( |
| 883 converter.FromV8Value(undefined, context)); | 889 converter.FromV8Value(undefined, context)); |
| 884 EXPECT_FALSE(undefined_value); | 890 EXPECT_FALSE(undefined_value); |
| 885 } | 891 } |
| 886 | 892 |
| 887 } // namespace content | 893 } // namespace content |
| OLD | NEW |