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