OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/memory/ptr_util.h" | 6 #include "base/memory/ptr_util.h" |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "extensions/renderer/api_binding.h" | 10 #include "extensions/renderer/api_binding.h" |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 last_request_.reset(); | 306 last_request_.reset(); |
307 } | 307 } |
308 | 308 |
309 TEST_F(APIBindingUnittest, TestEmptyAPI) { | 309 TEST_F(APIBindingUnittest, TestEmptyAPI) { |
310 InitializeBinding(); | 310 InitializeBinding(); |
311 | 311 |
312 v8::HandleScope handle_scope(isolate()); | 312 v8::HandleScope handle_scope(isolate()); |
313 v8::Local<v8::Context> context = MainContext(); | 313 v8::Local<v8::Context> context = MainContext(); |
314 | 314 |
315 v8::Local<v8::Object> binding_object = | 315 v8::Local<v8::Object> binding_object = |
316 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 316 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
317 EXPECT_EQ( | 317 EXPECT_EQ( |
318 0u, | 318 0u, |
319 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length()); | 319 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length()); |
320 } | 320 } |
321 | 321 |
322 TEST_F(APIBindingUnittest, Test) { | 322 TEST_F(APIBindingUnittest, Test) { |
323 // TODO(devlin): Move this test to an api_signature_unittest file? It really | 323 // TODO(devlin): Move this test to an api_signature_unittest file? It really |
324 // only tests parsing. | 324 // only tests parsing. |
325 SetFunctions(kFunctions); | 325 SetFunctions(kFunctions); |
326 InitializeBinding(); | 326 InitializeBinding(); |
327 | 327 |
328 v8::HandleScope handle_scope(isolate()); | 328 v8::HandleScope handle_scope(isolate()); |
329 v8::Local<v8::Context> context = MainContext(); | 329 v8::Local<v8::Context> context = MainContext(); |
330 | 330 |
331 v8::Local<v8::Object> binding_object = | 331 v8::Local<v8::Object> binding_object = |
332 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 332 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
333 | 333 |
334 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false); | 334 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false); |
335 ExpectPass(binding_object, "obj.oneString('');", "['']", false); | 335 ExpectPass(binding_object, "obj.oneString('');", "['']", false); |
336 ExpectFailure(binding_object, "obj.oneString(1);", kError); | 336 ExpectFailure(binding_object, "obj.oneString(1);", kError); |
337 ExpectFailure(binding_object, "obj.oneString();", kError); | 337 ExpectFailure(binding_object, "obj.oneString();", kError); |
338 ExpectFailure(binding_object, "obj.oneString({});", kError); | 338 ExpectFailure(binding_object, "obj.oneString({});", kError); |
339 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); | 339 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); |
340 | 340 |
341 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]", | 341 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]", |
342 false); | 342 false); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 " 'enum': [{'name': 'omega'}]" | 416 " 'enum': [{'name': 'omega'}]" |
417 "}]"; | 417 "}]"; |
418 | 418 |
419 SetTypes(kTypes); | 419 SetTypes(kTypes); |
420 InitializeBinding(); | 420 InitializeBinding(); |
421 | 421 |
422 v8::HandleScope handle_scope(isolate()); | 422 v8::HandleScope handle_scope(isolate()); |
423 v8::Local<v8::Context> context = MainContext(); | 423 v8::Local<v8::Context> context = MainContext(); |
424 | 424 |
425 v8::Local<v8::Object> binding_object = | 425 v8::Local<v8::Object> binding_object = |
426 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 426 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
427 | 427 |
428 const char kExpected[] = | 428 const char kExpected[] = |
429 "{'ALPHA':'alpha','CAMEL_CASE':'camelCase','HYPHEN_ATED':'Hyphen-ated'," | 429 "{'ALPHA':'alpha','CAMEL_CASE':'camelCase','HYPHEN_ATED':'Hyphen-ated'," |
430 "'NUMS123':'nums123','SCREAMING':'SCREAMING','_42NUMS':'42nums'}"; | 430 "'NUMS123':'nums123','SCREAMING':'SCREAMING','_42NUMS':'42nums'}"; |
431 EXPECT_EQ(ReplaceSingleQuotes(kExpected), | 431 EXPECT_EQ(ReplaceSingleQuotes(kExpected), |
432 GetStringPropertyFromObject(binding_object, context, "first")); | 432 GetStringPropertyFromObject(binding_object, context, "first")); |
433 EXPECT_EQ(ReplaceSingleQuotes("{'OMEGA':'omega'}"), | 433 EXPECT_EQ(ReplaceSingleQuotes("{'OMEGA':'omega'}"), |
434 GetStringPropertyFromObject(binding_object, context, "last")); | 434 GetStringPropertyFromObject(binding_object, context, "last")); |
435 } | 435 } |
436 | 436 |
437 // Test that empty enum entries are (unfortunately) allowed. | 437 // Test that empty enum entries are (unfortunately) allowed. |
438 TEST_F(APIBindingUnittest, EnumWithEmptyEntry) { | 438 TEST_F(APIBindingUnittest, EnumWithEmptyEntry) { |
439 const char kTypes[] = | 439 const char kTypes[] = |
440 "[{" | 440 "[{" |
441 " 'id': 'enumWithEmpty'," | 441 " 'id': 'enumWithEmpty'," |
442 " 'type': 'string'," | 442 " 'type': 'string'," |
443 " 'enum': [{'name': ''}, {'name': 'other'}]" | 443 " 'enum': [{'name': ''}, {'name': 'other'}]" |
444 "}]"; | 444 "}]"; |
445 | 445 |
446 SetTypes(kTypes); | 446 SetTypes(kTypes); |
447 InitializeBinding(); | 447 InitializeBinding(); |
448 | 448 |
449 v8::HandleScope handle_scope(isolate()); | 449 v8::HandleScope handle_scope(isolate()); |
450 v8::Local<v8::Context> context = MainContext(); | 450 v8::Local<v8::Context> context = MainContext(); |
451 | 451 |
452 v8::Local<v8::Object> binding_object = | 452 v8::Local<v8::Object> binding_object = |
453 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 453 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
454 | 454 |
455 EXPECT_EQ( | 455 EXPECT_EQ( |
456 "{\"\":\"\",\"OTHER\":\"other\"}", | 456 "{\"\":\"\",\"OTHER\":\"other\"}", |
457 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); | 457 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); |
458 } | 458 } |
459 | 459 |
460 TEST_F(APIBindingUnittest, TypeRefsTest) { | 460 TEST_F(APIBindingUnittest, TypeRefsTest) { |
461 const char kTypes[] = | 461 const char kTypes[] = |
462 "[{" | 462 "[{" |
463 " 'id': 'refObj'," | 463 " 'id': 'refObj'," |
(...skipping 26 matching lines...) Expand all Loading... |
490 SetTypes(kTypes); | 490 SetTypes(kTypes); |
491 InitializeBinding(); | 491 InitializeBinding(); |
492 EXPECT_EQ(2u, type_refs().size()); | 492 EXPECT_EQ(2u, type_refs().size()); |
493 EXPECT_TRUE(type_refs().GetSpec("refObj")); | 493 EXPECT_TRUE(type_refs().GetSpec("refObj")); |
494 EXPECT_TRUE(type_refs().GetSpec("refEnum")); | 494 EXPECT_TRUE(type_refs().GetSpec("refEnum")); |
495 | 495 |
496 v8::HandleScope handle_scope(isolate()); | 496 v8::HandleScope handle_scope(isolate()); |
497 v8::Local<v8::Context> context = MainContext(); | 497 v8::Local<v8::Context> context = MainContext(); |
498 | 498 |
499 v8::Local<v8::Object> binding_object = | 499 v8::Local<v8::Object> binding_object = |
500 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 500 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
501 | 501 |
502 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", | 502 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", |
503 "[{'prop1':'foo'}]", false); | 503 "[{'prop1':'foo'}]", false); |
504 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", | 504 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})", |
505 "[{'prop1':'foo','prop2':2}]", false); | 505 "[{'prop1':'foo','prop2':2}]", false); |
506 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", | 506 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", |
507 kError); | 507 kError); |
508 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false); | 508 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false); |
509 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']", false); | 509 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']", false); |
510 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']", | 510 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']", |
(...skipping 28 matching lines...) Expand all Loading... |
539 auto is_available = [](const std::string& name) { | 539 auto is_available = [](const std::string& name) { |
540 std::set<std::string> allowed = {"test.allowedOne", "test.allowedTwo", | 540 std::set<std::string> allowed = {"test.allowedOne", "test.allowedTwo", |
541 "test.allowedEvent"}; | 541 "test.allowedEvent"}; |
542 std::set<std::string> restricted = { | 542 std::set<std::string> restricted = { |
543 "test.restrictedOne", "test.restrictedTwo", "test.restrictedEvent"}; | 543 "test.restrictedOne", "test.restrictedTwo", "test.restrictedEvent"}; |
544 EXPECT_TRUE(allowed.count(name) || restricted.count(name)) << name; | 544 EXPECT_TRUE(allowed.count(name) || restricted.count(name)) << name; |
545 return allowed.count(name) != 0; | 545 return allowed.count(name) != 0; |
546 }; | 546 }; |
547 | 547 |
548 v8::Local<v8::Object> binding_object = | 548 v8::Local<v8::Object> binding_object = |
549 binding()->CreateInstance(context, isolate(), base::Bind(is_available)); | 549 binding()->CreateInstance(context, base::Bind(is_available)); |
550 | 550 |
551 auto is_defined = [&binding_object, context](const std::string& name) { | 551 auto is_defined = [&binding_object, context](const std::string& name) { |
552 v8::Local<v8::Value> val = | 552 v8::Local<v8::Value> val = |
553 GetPropertyFromObject(binding_object, context, name); | 553 GetPropertyFromObject(binding_object, context, name); |
554 EXPECT_FALSE(val.IsEmpty()); | 554 EXPECT_FALSE(val.IsEmpty()); |
555 return !val->IsUndefined() && !val->IsNull(); | 555 return !val->IsUndefined() && !val->IsNull(); |
556 }; | 556 }; |
557 | 557 |
558 EXPECT_TRUE(is_defined("allowedOne")); | 558 EXPECT_TRUE(is_defined("allowedOne")); |
559 EXPECT_TRUE(is_defined("allowedTwo")); | 559 EXPECT_TRUE(is_defined("allowedTwo")); |
560 EXPECT_TRUE(is_defined("allowedEvent")); | 560 EXPECT_TRUE(is_defined("allowedEvent")); |
561 EXPECT_FALSE(is_defined("restrictedOne")); | 561 EXPECT_FALSE(is_defined("restrictedOne")); |
562 EXPECT_FALSE(is_defined("restrictedTwo")); | 562 EXPECT_FALSE(is_defined("restrictedTwo")); |
563 EXPECT_FALSE(is_defined("restrictedEvent")); | 563 EXPECT_FALSE(is_defined("restrictedEvent")); |
564 } | 564 } |
565 | 565 |
566 // Tests that events specified in the API are created as properties of the API | 566 // Tests that events specified in the API are created as properties of the API |
567 // object. | 567 // object. |
568 TEST_F(APIBindingUnittest, TestEventCreation) { | 568 TEST_F(APIBindingUnittest, TestEventCreation) { |
569 SetEvents("[{'name': 'onFoo'}, {'name': 'onBar'}]"); | 569 SetEvents("[{'name': 'onFoo'}, {'name': 'onBar'}]"); |
570 SetFunctions(kFunctions); | 570 SetFunctions(kFunctions); |
571 InitializeBinding(); | 571 InitializeBinding(); |
572 | 572 |
573 v8::HandleScope handle_scope(isolate()); | 573 v8::HandleScope handle_scope(isolate()); |
574 v8::Local<v8::Context> context = MainContext(); | 574 v8::Local<v8::Context> context = MainContext(); |
575 | 575 |
576 v8::Local<v8::Object> binding_object = | 576 v8::Local<v8::Object> binding_object = |
577 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 577 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
578 | 578 |
579 // Event behavior is tested in the APIEventHandler unittests as well as the | 579 // Event behavior is tested in the APIEventHandler unittests as well as the |
580 // APIBindingsSystem tests, so we really only need to check that the events | 580 // APIBindingsSystem tests, so we really only need to check that the events |
581 // are being initialized on the object. | 581 // are being initialized on the object. |
582 v8::Maybe<bool> has_on_foo = | 582 v8::Maybe<bool> has_on_foo = |
583 binding_object->Has(context, gin::StringToV8(isolate(), "onFoo")); | 583 binding_object->Has(context, gin::StringToV8(isolate(), "onFoo")); |
584 EXPECT_TRUE(has_on_foo.IsJust()); | 584 EXPECT_TRUE(has_on_foo.IsJust()); |
585 EXPECT_TRUE(has_on_foo.FromJust()); | 585 EXPECT_TRUE(has_on_foo.FromJust()); |
586 | 586 |
587 v8::Maybe<bool> has_on_bar = | 587 v8::Maybe<bool> has_on_bar = |
(...skipping 17 matching lines...) Expand all Loading... |
605 " 'subprop1': { 'value': 'some value', 'type': 'string' }," | 605 " 'subprop1': { 'value': 'some value', 'type': 'string' }," |
606 " 'subprop2': { 'value': true, 'type': 'boolean' }" | 606 " 'subprop2': { 'value': true, 'type': 'boolean' }" |
607 " }" | 607 " }" |
608 " }" | 608 " }" |
609 "}"); | 609 "}"); |
610 InitializeBinding(); | 610 InitializeBinding(); |
611 | 611 |
612 v8::HandleScope handle_scope(isolate()); | 612 v8::HandleScope handle_scope(isolate()); |
613 v8::Local<v8::Context> context = MainContext(); | 613 v8::Local<v8::Context> context = MainContext(); |
614 v8::Local<v8::Object> binding_object = | 614 v8::Local<v8::Object> binding_object = |
615 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 615 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
616 EXPECT_EQ("17", | 616 EXPECT_EQ("17", |
617 GetStringPropertyFromObject(binding_object, context, "prop1")); | 617 GetStringPropertyFromObject(binding_object, context, "prop1")); |
618 EXPECT_EQ(R"({"subprop1":"some value","subprop2":true})", | 618 EXPECT_EQ(R"({"subprop1":"some value","subprop2":true})", |
619 GetStringPropertyFromObject(binding_object, context, "prop2")); | 619 GetStringPropertyFromObject(binding_object, context, "prop2")); |
620 } | 620 } |
621 | 621 |
622 TEST_F(APIBindingUnittest, TestRefProperties) { | 622 TEST_F(APIBindingUnittest, TestRefProperties) { |
623 SetProperties( | 623 SetProperties( |
624 "{" | 624 "{" |
625 " 'alpha': {" | 625 " 'alpha': {" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 return result; | 657 return result; |
658 }; | 658 }; |
659 | 659 |
660 SetCreateCustomType(base::Bind(create_custom_type)); | 660 SetCreateCustomType(base::Bind(create_custom_type)); |
661 | 661 |
662 InitializeBinding(); | 662 InitializeBinding(); |
663 | 663 |
664 v8::HandleScope handle_scope(isolate()); | 664 v8::HandleScope handle_scope(isolate()); |
665 v8::Local<v8::Context> context = MainContext(); | 665 v8::Local<v8::Context> context = MainContext(); |
666 v8::Local<v8::Object> binding_object = | 666 v8::Local<v8::Object> binding_object = |
667 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 667 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
668 EXPECT_EQ(R"({"alphaProp":"alphaVal"})", | 668 EXPECT_EQ(R"({"alphaProp":"alphaVal"})", |
669 GetStringPropertyFromObject(binding_object, context, "alpha")); | 669 GetStringPropertyFromObject(binding_object, context, "alpha")); |
670 EXPECT_EQ( | 670 EXPECT_EQ( |
671 R"({"betaProp":"betaVal"})", | 671 R"({"betaProp":"betaVal"})", |
672 GetStringPropertyFromObject(binding_object, context, "beta")); | 672 GetStringPropertyFromObject(binding_object, context, "beta")); |
673 } | 673 } |
674 | 674 |
675 TEST_F(APIBindingUnittest, TestDisposedContext) { | 675 TEST_F(APIBindingUnittest, TestDisposedContext) { |
676 SetFunctions(kFunctions); | 676 SetFunctions(kFunctions); |
677 InitializeBinding(); | 677 InitializeBinding(); |
678 | 678 |
679 v8::HandleScope handle_scope(isolate()); | 679 v8::HandleScope handle_scope(isolate()); |
680 v8::Local<v8::Context> context = MainContext(); | 680 v8::Local<v8::Context> context = MainContext(); |
681 | 681 |
682 v8::Local<v8::Object> binding_object = | 682 v8::Local<v8::Object> binding_object = |
683 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 683 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
684 | 684 |
685 v8::Local<v8::Function> func = | 685 v8::Local<v8::Function> func = |
686 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); | 686 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); |
687 v8::Local<v8::Value> argv[] = {binding_object}; | 687 v8::Local<v8::Value> argv[] = {binding_object}; |
688 DisposeContext(context); | 688 DisposeContext(context); |
689 RunFunction(func, context, arraysize(argv), argv); | 689 RunFunction(func, context, arraysize(argv), argv); |
690 EXPECT_FALSE(HandlerWasInvoked()); | 690 EXPECT_FALSE(HandlerWasInvoked()); |
691 // This test passes if this does not crash, even under AddressSanitizer | 691 // This test passes if this does not crash, even under AddressSanitizer |
692 // builds. | 692 // builds. |
693 } | 693 } |
694 | 694 |
695 TEST_F(APIBindingUnittest, MultipleContexts) { | 695 TEST_F(APIBindingUnittest, MultipleContexts) { |
696 v8::HandleScope handle_scope(isolate()); | 696 v8::HandleScope handle_scope(isolate()); |
697 v8::Local<v8::Context> context_a = MainContext(); | 697 v8::Local<v8::Context> context_a = MainContext(); |
698 v8::Local<v8::Context> context_b = AddContext(); | 698 v8::Local<v8::Context> context_b = AddContext(); |
699 | 699 |
700 SetFunctions(kFunctions); | 700 SetFunctions(kFunctions); |
701 InitializeBinding(); | 701 InitializeBinding(); |
702 | 702 |
703 v8::Local<v8::Object> binding_object_a = binding()->CreateInstance( | 703 v8::Local<v8::Object> binding_object_a = |
704 context_a, isolate(), base::Bind(&AllowAllAPIs)); | 704 binding()->CreateInstance(context_a, base::Bind(&AllowAllAPIs)); |
705 v8::Local<v8::Object> binding_object_b = binding()->CreateInstance( | 705 v8::Local<v8::Object> binding_object_b = |
706 context_b, isolate(), base::Bind(&AllowAllAPIs)); | 706 binding()->CreateInstance(context_b, base::Bind(&AllowAllAPIs)); |
707 | 707 |
708 ExpectPass(context_a, binding_object_a, "obj.oneString('foo');", "['foo']", | 708 ExpectPass(context_a, binding_object_a, "obj.oneString('foo');", "['foo']", |
709 false); | 709 false); |
710 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", | 710 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", |
711 false); | 711 false); |
712 DisposeContext(context_a); | 712 DisposeContext(context_a); |
713 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", | 713 ExpectPass(context_b, binding_object_b, "obj.oneString('foo');", "['foo']", |
714 false); | 714 false); |
715 } | 715 } |
716 | 716 |
(...skipping 20 matching lines...) Expand all Loading... |
737 }; | 737 }; |
738 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); | 738 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); |
739 SetHooksDelegate(std::move(hooks)); | 739 SetHooksDelegate(std::move(hooks)); |
740 | 740 |
741 InitializeBinding(); | 741 InitializeBinding(); |
742 | 742 |
743 v8::HandleScope handle_scope(isolate()); | 743 v8::HandleScope handle_scope(isolate()); |
744 v8::Local<v8::Context> context = MainContext(); | 744 v8::Local<v8::Context> context = MainContext(); |
745 | 745 |
746 v8::Local<v8::Object> binding_object = | 746 v8::Local<v8::Object> binding_object = |
747 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 747 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
748 | 748 |
749 // First try calling the oneString() method, which has a custom hook | 749 // First try calling the oneString() method, which has a custom hook |
750 // installed. | 750 // installed. |
751 v8::Local<v8::Function> func = | 751 v8::Local<v8::Function> func = |
752 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); | 752 FunctionFromString(context, "(function(obj) { obj.oneString('foo'); })"); |
753 v8::Local<v8::Value> args[] = {binding_object}; | 753 v8::Local<v8::Value> args[] = {binding_object}; |
754 RunFunction(func, context, 1, args); | 754 RunFunction(func, context, 1, args); |
755 EXPECT_TRUE(did_call); | 755 EXPECT_TRUE(did_call); |
756 | 756 |
757 // Other methods, like stringAndInt(), should behave normally. | 757 // Other methods, like stringAndInt(), should behave normally. |
(...skipping 20 matching lines...) Expand all Loading... |
778 FunctionFromString(context, kRegisterHook); | 778 FunctionFromString(context, kRegisterHook); |
779 v8::Local<v8::Value> args[] = {js_hooks}; | 779 v8::Local<v8::Value> args[] = {js_hooks}; |
780 RunFunctionOnGlobal(function, context, arraysize(args), args); | 780 RunFunctionOnGlobal(function, context, arraysize(args), args); |
781 } | 781 } |
782 | 782 |
783 SetFunctions(kFunctions); | 783 SetFunctions(kFunctions); |
784 SetHooks(std::move(hooks)); | 784 SetHooks(std::move(hooks)); |
785 InitializeBinding(); | 785 InitializeBinding(); |
786 | 786 |
787 v8::Local<v8::Object> binding_object = | 787 v8::Local<v8::Object> binding_object = |
788 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 788 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
789 | 789 |
790 // First try calling with an invalid invocation. An error should be raised and | 790 // First try calling with an invalid invocation. An error should be raised and |
791 // the hook should never have been called, since the arguments didn't match. | 791 // the hook should never have been called, since the arguments didn't match. |
792 ExpectFailure(binding_object, "obj.oneString(1);", kError); | 792 ExpectFailure(binding_object, "obj.oneString(1);", kError); |
793 v8::Local<v8::Value> property = | 793 v8::Local<v8::Value> property = |
794 GetPropertyFromObject(context->Global(), context, "requestArguments"); | 794 GetPropertyFromObject(context->Global(), context, "requestArguments"); |
795 ASSERT_FALSE(property.IsEmpty()); | 795 ASSERT_FALSE(property.IsEmpty()); |
796 EXPECT_TRUE(property->IsUndefined()); | 796 EXPECT_TRUE(property->IsUndefined()); |
797 | 797 |
798 // Try calling the oneString() method with valid arguments. The hook should | 798 // Try calling the oneString() method with valid arguments. The hook should |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); | 830 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); |
831 v8::Local<v8::Function> function = FunctionFromString(context, kRegisterHook); | 831 v8::Local<v8::Function> function = FunctionFromString(context, kRegisterHook); |
832 v8::Local<v8::Value> args[] = {js_hooks}; | 832 v8::Local<v8::Value> args[] = {js_hooks}; |
833 RunFunctionOnGlobal(function, context, arraysize(args), args); | 833 RunFunctionOnGlobal(function, context, arraysize(args), args); |
834 | 834 |
835 SetHooks(std::move(hooks)); | 835 SetHooks(std::move(hooks)); |
836 SetFunctions(kFunctions); | 836 SetFunctions(kFunctions); |
837 InitializeBinding(); | 837 InitializeBinding(); |
838 | 838 |
839 v8::Local<v8::Object> binding_object = | 839 v8::Local<v8::Object> binding_object = |
840 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 840 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
841 | 841 |
842 // Call the method with a hook. Since the hook updates arguments before | 842 // Call the method with a hook. Since the hook updates arguments before |
843 // validation, we should be able to pass in invalid arguments and still | 843 // validation, we should be able to pass in invalid arguments and still |
844 // have the hook called. | 844 // have the hook called. |
845 ExpectFailure(binding_object, "obj.oneString(false);", kError); | 845 ExpectFailure(binding_object, "obj.oneString(false);", kError); |
846 EXPECT_EQ("[false]", GetStringPropertyFromObject( | 846 EXPECT_EQ("[false]", GetStringPropertyFromObject( |
847 context->Global(), context, "requestArguments")); | 847 context->Global(), context, "requestArguments")); |
848 | 848 |
849 ExpectPass(binding_object, "obj.oneString(true);", "['hooked']", false); | 849 ExpectPass(binding_object, "obj.oneString(true);", "['hooked']", false); |
850 EXPECT_EQ("[true]", GetStringPropertyFromObject( | 850 EXPECT_EQ("[true]", GetStringPropertyFromObject( |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 FunctionFromString(context, kRegisterHook); | 888 FunctionFromString(context, kRegisterHook); |
889 v8::Local<v8::Value> args[] = {js_hooks}; | 889 v8::Local<v8::Value> args[] = {js_hooks}; |
890 RunFunctionOnGlobal(function, context, arraysize(args), args); | 890 RunFunctionOnGlobal(function, context, arraysize(args), args); |
891 } | 891 } |
892 | 892 |
893 SetHooks(std::move(hooks)); | 893 SetHooks(std::move(hooks)); |
894 SetFunctions(kFunctions); | 894 SetFunctions(kFunctions); |
895 InitializeBinding(); | 895 InitializeBinding(); |
896 | 896 |
897 v8::Local<v8::Object> binding_object = | 897 v8::Local<v8::Object> binding_object = |
898 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 898 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
899 | 899 |
900 v8::Local<v8::Function> function = | 900 v8::Local<v8::Function> function = |
901 FunctionFromString(context, | 901 FunctionFromString(context, |
902 "(function(obj) { return obj.oneString('ping'); })"); | 902 "(function(obj) { return obj.oneString('ping'); })"); |
903 v8::Local<v8::Value> args[] = {binding_object}; | 903 v8::Local<v8::Value> args[] = {binding_object}; |
904 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 904 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
905 arraysize(args), args, | 905 arraysize(args), args, |
906 "Uncaught Error: Custom Hook Error"); | 906 "Uncaught Error: Custom Hook Error"); |
907 | 907 |
908 // Other methods, like stringAndInt(), should behave normally. | 908 // Other methods, like stringAndInt(), should behave normally. |
(...skipping 21 matching lines...) Expand all Loading... |
930 FunctionFromString(context, kRegisterHook); | 930 FunctionFromString(context, kRegisterHook); |
931 v8::Local<v8::Value> args[] = {js_hooks}; | 931 v8::Local<v8::Value> args[] = {js_hooks}; |
932 RunFunctionOnGlobal(function, context, arraysize(args), args); | 932 RunFunctionOnGlobal(function, context, arraysize(args), args); |
933 } | 933 } |
934 | 934 |
935 SetHooks(std::move(hooks)); | 935 SetHooks(std::move(hooks)); |
936 SetFunctions(kFunctions); | 936 SetFunctions(kFunctions); |
937 InitializeBinding(); | 937 InitializeBinding(); |
938 | 938 |
939 v8::Local<v8::Object> binding_object = | 939 v8::Local<v8::Object> binding_object = |
940 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 940 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
941 | 941 |
942 v8::Local<v8::Function> function = | 942 v8::Local<v8::Function> function = |
943 FunctionFromString(context, | 943 FunctionFromString(context, |
944 "(function(obj) { return obj.oneString('ping'); })"); | 944 "(function(obj) { return obj.oneString('ping'); })"); |
945 v8::Local<v8::Value> args[] = {binding_object}; | 945 v8::Local<v8::Value> args[] = {binding_object}; |
946 v8::Local<v8::Value> result = | 946 v8::Local<v8::Value> result = |
947 RunFunction(function, context, arraysize(args), args); | 947 RunFunction(function, context, arraysize(args), args); |
948 ASSERT_FALSE(result.IsEmpty()); | 948 ASSERT_FALSE(result.IsEmpty()); |
949 std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context); | 949 std::unique_ptr<base::Value> json_result = V8ToBaseValue(result, context); |
950 ASSERT_TRUE(json_result); | 950 ASSERT_TRUE(json_result); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
991 FunctionFromString(context, kRegisterHook); | 991 FunctionFromString(context, kRegisterHook); |
992 v8::Local<v8::Value> args[] = {js_hooks}; | 992 v8::Local<v8::Value> args[] = {js_hooks}; |
993 RunFunctionOnGlobal(function, context, arraysize(args), args); | 993 RunFunctionOnGlobal(function, context, arraysize(args), args); |
994 } | 994 } |
995 | 995 |
996 SetHooks(std::move(hooks)); | 996 SetHooks(std::move(hooks)); |
997 SetFunctions(kFunctions); | 997 SetFunctions(kFunctions); |
998 InitializeBinding(); | 998 InitializeBinding(); |
999 | 999 |
1000 v8::Local<v8::Object> binding_object = | 1000 v8::Local<v8::Object> binding_object = |
1001 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1001 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
1002 | 1002 |
1003 v8::Local<v8::Function> function = | 1003 v8::Local<v8::Function> function = |
1004 FunctionFromString(context, | 1004 FunctionFromString(context, |
1005 "(function(obj) { return obj.oneString('ping'); })"); | 1005 "(function(obj) { return obj.oneString('ping'); })"); |
1006 v8::Local<v8::Value> args[] = {binding_object}; | 1006 v8::Local<v8::Value> args[] = {binding_object}; |
1007 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 1007 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
1008 arraysize(args), args, | 1008 arraysize(args), args, |
1009 "Uncaught Error: Custom Hook Error"); | 1009 "Uncaught Error: Custom Hook Error"); |
1010 } | 1010 } |
1011 | 1011 |
(...skipping 29 matching lines...) Expand all Loading... |
1041 gin::StringToV8(context->GetIsolate(), arg_value + " pong"); | 1041 gin::StringToV8(context->GetIsolate(), arg_value + " pong"); |
1042 return result; | 1042 return result; |
1043 }; | 1043 }; |
1044 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); | 1044 hooks->AddHandler("test.oneString", base::Bind(hook, &did_call)); |
1045 | 1045 |
1046 SetHooksDelegate(std::move(hooks)); | 1046 SetHooksDelegate(std::move(hooks)); |
1047 SetFunctions(kFunctions); | 1047 SetFunctions(kFunctions); |
1048 InitializeBinding(); | 1048 InitializeBinding(); |
1049 | 1049 |
1050 v8::Local<v8::Object> binding_object = | 1050 v8::Local<v8::Object> binding_object = |
1051 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1051 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
1052 | 1052 |
1053 { | 1053 { |
1054 // Test an invocation that we expect to throw an exception. | 1054 // Test an invocation that we expect to throw an exception. |
1055 v8::Local<v8::Function> function = | 1055 v8::Local<v8::Function> function = |
1056 FunctionFromString( | 1056 FunctionFromString( |
1057 context, "(function(obj) { return obj.oneString('throw'); })"); | 1057 context, "(function(obj) { return obj.oneString('throw'); })"); |
1058 v8::Local<v8::Value> args[] = {binding_object}; | 1058 v8::Local<v8::Value> args[] = {binding_object}; |
1059 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), | 1059 RunFunctionAndExpectError(function, context, v8::Undefined(isolate()), |
1060 arraysize(args), args, | 1060 arraysize(args), args, |
1061 "Uncaught Error: Custom Hook Error"); | 1061 "Uncaught Error: Custom Hook Error"); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 FunctionFromString(context, kRegisterHook); | 1097 FunctionFromString(context, kRegisterHook); |
1098 v8::Local<v8::Value> args[] = {js_hooks}; | 1098 v8::Local<v8::Value> args[] = {js_hooks}; |
1099 RunFunctionOnGlobal(function, context, arraysize(args), args); | 1099 RunFunctionOnGlobal(function, context, arraysize(args), args); |
1100 } | 1100 } |
1101 | 1101 |
1102 SetHooks(std::move(hooks)); | 1102 SetHooks(std::move(hooks)); |
1103 SetFunctions(kFunctions); | 1103 SetFunctions(kFunctions); |
1104 InitializeBinding(); | 1104 InitializeBinding(); |
1105 | 1105 |
1106 v8::Local<v8::Object> binding_object = | 1106 v8::Local<v8::Object> binding_object = |
1107 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1107 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
1108 | 1108 |
1109 // Try calling the method with an invalid signature. Since it's invalid, we | 1109 // Try calling the method with an invalid signature. Since it's invalid, we |
1110 // should never enter the hook. | 1110 // should never enter the hook. |
1111 ExpectFailure(binding_object, "obj.oneString(false);", kError); | 1111 ExpectFailure(binding_object, "obj.oneString(false);", kError); |
1112 EXPECT_EQ("undefined", GetStringPropertyFromObject( | 1112 EXPECT_EQ("undefined", GetStringPropertyFromObject( |
1113 context->Global(), context, "requestArguments")); | 1113 context->Global(), context, "requestArguments")); |
1114 | 1114 |
1115 // Call the method with a valid signature. The hook should be entered and | 1115 // Call the method with a valid signature. The hook should be entered and |
1116 // manipulate the arguments. | 1116 // manipulate the arguments. |
1117 ExpectPass(binding_object, "obj.oneString('ping');", "['pong']", false); | 1117 ExpectPass(binding_object, "obj.oneString('ping');", "['pong']", false); |
(...skipping 27 matching lines...) Expand all Loading... |
1145 FunctionFromString(context, kRegisterHook); | 1145 FunctionFromString(context, kRegisterHook); |
1146 v8::Local<v8::Value> args[] = {js_hooks}; | 1146 v8::Local<v8::Value> args[] = {js_hooks}; |
1147 RunFunctionOnGlobal(function, context, arraysize(args), args); | 1147 RunFunctionOnGlobal(function, context, arraysize(args), args); |
1148 } | 1148 } |
1149 | 1149 |
1150 SetHooks(std::move(hooks)); | 1150 SetHooks(std::move(hooks)); |
1151 SetFunctions(kFunctions); | 1151 SetFunctions(kFunctions); |
1152 InitializeBinding(); | 1152 InitializeBinding(); |
1153 | 1153 |
1154 v8::Local<v8::Object> binding_object = | 1154 v8::Local<v8::Object> binding_object = |
1155 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1155 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
1156 | 1156 |
1157 // Call the method with a valid signature. The hook should be entered and | 1157 // Call the method with a valid signature. The hook should be entered and |
1158 // manipulate the arguments. | 1158 // manipulate the arguments. |
1159 ExpectPass(binding_object, "obj.oneString('ping');", "[{}]", false); | 1159 ExpectPass(binding_object, "obj.oneString('ping');", "[{}]", false); |
1160 } | 1160 } |
1161 | 1161 |
1162 // Test that user gestures are properly recorded when calling APIs. | 1162 // Test that user gestures are properly recorded when calling APIs. |
1163 TEST_F(APIBindingUnittest, TestUserGestures) { | 1163 TEST_F(APIBindingUnittest, TestUserGestures) { |
1164 SetFunctions(kFunctions); | 1164 SetFunctions(kFunctions); |
1165 InitializeBinding(); | 1165 InitializeBinding(); |
1166 | 1166 |
1167 v8::HandleScope handle_scope(isolate()); | 1167 v8::HandleScope handle_scope(isolate()); |
1168 v8::Local<v8::Context> context = MainContext(); | 1168 v8::Local<v8::Context> context = MainContext(); |
1169 | 1169 |
1170 v8::Local<v8::Object> binding_object = | 1170 v8::Local<v8::Object> binding_object = |
1171 binding()->CreateInstance(context, isolate(), base::Bind(&AllowAllAPIs)); | 1171 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); |
1172 | 1172 |
1173 v8::Local<v8::Function> function = | 1173 v8::Local<v8::Function> function = |
1174 FunctionFromString(context, "(function(obj) { obj.oneString('foo');})"); | 1174 FunctionFromString(context, "(function(obj) { obj.oneString('foo');})"); |
1175 ASSERT_FALSE(function.IsEmpty()); | 1175 ASSERT_FALSE(function.IsEmpty()); |
1176 | 1176 |
1177 v8::Local<v8::Value> argv[] = {binding_object}; | 1177 v8::Local<v8::Value> argv[] = {binding_object}; |
1178 RunFunction(function, context, arraysize(argv), argv); | 1178 RunFunction(function, context, arraysize(argv), argv); |
1179 ASSERT_TRUE(last_request()); | 1179 ASSERT_TRUE(last_request()); |
1180 EXPECT_FALSE(last_request()->has_user_gesture); | 1180 EXPECT_FALSE(last_request()->has_user_gesture); |
1181 reset_last_request(); | 1181 reset_last_request(); |
1182 | 1182 |
1183 blink::WebScopedUserGesture user_gesture(nullptr); | 1183 blink::WebScopedUserGesture user_gesture(nullptr); |
1184 RunFunction(function, context, arraysize(argv), argv); | 1184 RunFunction(function, context, arraysize(argv), argv); |
1185 ASSERT_TRUE(last_request()); | 1185 ASSERT_TRUE(last_request()); |
1186 EXPECT_TRUE(last_request()->has_user_gesture); | 1186 EXPECT_TRUE(last_request()->has_user_gesture); |
1187 | 1187 |
1188 reset_last_request(); | 1188 reset_last_request(); |
1189 } | 1189 } |
1190 | 1190 |
1191 } // namespace extensions | 1191 } // namespace extensions |
OLD | NEW |