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