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 "extensions/renderer/api_bindings_system.h" | 5 #include "extensions/renderer/api_bindings_system.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 | 84 |
85 const char kGammaAPIName[] = "gamma"; | 85 const char kGammaAPIName[] = "gamma"; |
86 const char kGammaAPISpec[] = | 86 const char kGammaAPISpec[] = |
87 "{" | 87 "{" |
88 " 'functions': [{" | 88 " 'functions': [{" |
89 " 'name': 'functionWithExternalRef'," | 89 " 'name': 'functionWithExternalRef'," |
90 " 'parameters': [{ 'name': 'someRef', '$ref': 'alpha.objRef' }]" | 90 " 'parameters': [{ 'name': 'someRef', '$ref': 'alpha.objRef' }]" |
91 " }]" | 91 " }]" |
92 "}"; | 92 "}"; |
93 | 93 |
94 bool AllowAllAPIs(const std::string& name) { | 94 bool AllowAllAPIs(v8::Local<v8::Context> context, const std::string& name) { |
95 return true; | 95 return true; |
96 } | 96 } |
97 | 97 |
98 } // namespace | 98 } // namespace |
99 | 99 |
100 APIBindingsSystemTest::APIBindingsSystemTest() {} | 100 APIBindingsSystemTest::APIBindingsSystemTest() {} |
101 APIBindingsSystemTest::~APIBindingsSystemTest() = default; | 101 APIBindingsSystemTest::~APIBindingsSystemTest() = default; |
102 | 102 |
103 void APIBindingsSystemTest::SetUp() { | 103 void APIBindingsSystemTest::SetUp() { |
104 APIBindingTest::SetUp(); | 104 APIBindingTest::SetUp(); |
105 | 105 |
106 // Create the fake API schemas. | 106 // Create the fake API schemas. |
107 for (const auto& api : GetAPIs()) { | 107 for (const auto& api : GetAPIs()) { |
108 std::unique_ptr<base::DictionaryValue> api_schema = | 108 std::unique_ptr<base::DictionaryValue> api_schema = |
109 DictionaryValueFromString(api.spec); | 109 DictionaryValueFromString(api.spec); |
110 ASSERT_TRUE(api_schema); | 110 ASSERT_TRUE(api_schema); |
111 api_schemas_[api.name] = std::move(api_schema); | 111 api_schemas_[api.name] = std::move(api_schema); |
112 } | 112 } |
113 | 113 |
114 bindings_system_ = base::MakeUnique<APIBindingsSystem>( | 114 bindings_system_ = base::MakeUnique<APIBindingsSystem>( |
115 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 115 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
116 base::Bind(&RunFunctionOnGlobalAndReturnHandle), | 116 base::Bind(&RunFunctionOnGlobalAndReturnHandle), |
117 base::Bind(&APIBindingsSystemTest::GetAPISchema, base::Unretained(this)), | 117 base::Bind(&APIBindingsSystemTest::GetAPISchema, base::Unretained(this)), |
| 118 base::Bind(&AllowAllAPIs), |
118 base::Bind(&APIBindingsSystemTest::OnAPIRequest, base::Unretained(this)), | 119 base::Bind(&APIBindingsSystemTest::OnAPIRequest, base::Unretained(this)), |
119 base::Bind(&APIBindingsSystemTest::OnEventListenersChanged, | 120 base::Bind(&APIBindingsSystemTest::OnEventListenersChanged, |
120 base::Unretained(this)), | 121 base::Unretained(this)), |
121 APILastError(base::Bind(&APIBindingsSystemTest::GetLastErrorParent, | 122 APILastError(base::Bind(&APIBindingsSystemTest::GetLastErrorParent, |
122 base::Unretained(this)), | 123 base::Unretained(this)), |
123 APILastError::AddConsoleError())); | 124 APILastError::AddConsoleError())); |
124 } | 125 } |
125 | 126 |
126 void APIBindingsSystemTest::TearDown() { | 127 void APIBindingsSystemTest::TearDown() { |
127 // Dispose all contexts now so that we call WillReleaseContext(). | 128 // Dispose all contexts now so that we call WillReleaseContext(). |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 v8::Local<v8::Value> argv[] = {object}; | 199 v8::Local<v8::Value> argv[] = {object}; |
199 return RunFunction(func, context, 1, argv); | 200 return RunFunction(func, context, 1, argv); |
200 } | 201 } |
201 | 202 |
202 // Tests API object initialization, calling a method on the supplied APIs, and | 203 // Tests API object initialization, calling a method on the supplied APIs, and |
203 // triggering the callback for the request. | 204 // triggering the callback for the request. |
204 TEST_F(APIBindingsSystemTest, TestInitializationAndCallbacks) { | 205 TEST_F(APIBindingsSystemTest, TestInitializationAndCallbacks) { |
205 v8::HandleScope handle_scope(isolate()); | 206 v8::HandleScope handle_scope(isolate()); |
206 v8::Local<v8::Context> context = MainContext(); | 207 v8::Local<v8::Context> context = MainContext(); |
207 | 208 |
208 v8::Local<v8::Object> alpha_api = bindings_system()->CreateAPIInstance( | 209 v8::Local<v8::Object> alpha_api = |
209 kAlphaAPIName, context, base::Bind(&AllowAllAPIs), nullptr); | 210 bindings_system()->CreateAPIInstance(kAlphaAPIName, context, nullptr); |
210 ASSERT_FALSE(alpha_api.IsEmpty()); | 211 ASSERT_FALSE(alpha_api.IsEmpty()); |
211 v8::Local<v8::Object> beta_api = bindings_system()->CreateAPIInstance( | 212 v8::Local<v8::Object> beta_api = |
212 kBetaAPIName, context, base::Bind(&AllowAllAPIs), nullptr); | 213 bindings_system()->CreateAPIInstance(kBetaAPIName, context, nullptr); |
213 ASSERT_FALSE(beta_api.IsEmpty()); | 214 ASSERT_FALSE(beta_api.IsEmpty()); |
214 | 215 |
215 { | 216 { |
216 // Test a simple call -> response. | 217 // Test a simple call -> response. |
217 const char kTestCall[] = | 218 const char kTestCall[] = |
218 "obj.functionWithCallback('foo', function() {\n" | 219 "obj.functionWithCallback('foo', function() {\n" |
219 " this.callbackArguments = Array.from(arguments);\n" | 220 " this.callbackArguments = Array.from(arguments);\n" |
220 "});"; | 221 "});"; |
221 CallFunctionOnObject(context, alpha_api, kTestCall); | 222 CallFunctionOnObject(context, alpha_api, kTestCall); |
222 | 223 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 return result; | 333 return result; |
333 }; | 334 }; |
334 | 335 |
335 auto test_hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); | 336 auto test_hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); |
336 test_hooks->AddHandler("alpha.functionWithCallback", | 337 test_hooks->AddHandler("alpha.functionWithCallback", |
337 base::Bind(hook, &did_call)); | 338 base::Bind(hook, &did_call)); |
338 APIBindingHooks* binding_hooks = | 339 APIBindingHooks* binding_hooks = |
339 bindings_system()->GetHooksForAPI(kAlphaAPIName); | 340 bindings_system()->GetHooksForAPI(kAlphaAPIName); |
340 binding_hooks->SetDelegate(std::move(test_hooks)); | 341 binding_hooks->SetDelegate(std::move(test_hooks)); |
341 | 342 |
342 v8::Local<v8::Object> alpha_api = bindings_system()->CreateAPIInstance( | 343 v8::Local<v8::Object> alpha_api = |
343 kAlphaAPIName, context, base::Bind(&AllowAllAPIs), nullptr); | 344 bindings_system()->CreateAPIInstance(kAlphaAPIName, context, nullptr); |
344 ASSERT_FALSE(alpha_api.IsEmpty()); | 345 ASSERT_FALSE(alpha_api.IsEmpty()); |
345 | 346 |
346 { | 347 { |
347 // Test a simple call -> response. | 348 // Test a simple call -> response. |
348 const char kTestCall[] = | 349 const char kTestCall[] = |
349 "obj.functionWithCallback('foo', function() {\n" | 350 "obj.functionWithCallback('foo', function() {\n" |
350 " this.callbackArguments = Array.from(arguments);\n" | 351 " this.callbackArguments = Array.from(arguments);\n" |
351 "});"; | 352 "});"; |
352 CallFunctionOnObject(context, alpha_api, kTestCall); | 353 CallFunctionOnObject(context, alpha_api, kTestCall); |
353 EXPECT_TRUE(did_call); | 354 EXPECT_TRUE(did_call); |
(...skipping 16 matching lines...) Expand all Loading... |
370 " firstResult, secondResult) => {\n" | 371 " firstResult, secondResult) => {\n" |
371 " this.methodName = name;\n" | 372 " this.methodName = name;\n" |
372 // TODO(devlin): Currently, we don't actually pass anything useful in for | 373 // TODO(devlin): Currently, we don't actually pass anything useful in for |
373 // the |request| object. If/when we do, we should test it. | 374 // the |request| object. If/when we do, we should test it. |
374 " this.results = [firstResult, secondResult];\n" | 375 " this.results = [firstResult, secondResult];\n" |
375 " originalCallback(secondResult);\n" | 376 " originalCallback(secondResult);\n" |
376 " });\n" | 377 " });\n" |
377 "})"; | 378 "})"; |
378 | 379 |
379 APIBindingHooks* hooks = nullptr; | 380 APIBindingHooks* hooks = nullptr; |
380 v8::Local<v8::Object> alpha_api = bindings_system()->CreateAPIInstance( | 381 v8::Local<v8::Object> alpha_api = |
381 kAlphaAPIName, context, base::Bind(&AllowAllAPIs), &hooks); | 382 bindings_system()->CreateAPIInstance(kAlphaAPIName, context, &hooks); |
382 ASSERT_FALSE(alpha_api.IsEmpty()); | 383 ASSERT_FALSE(alpha_api.IsEmpty()); |
383 ASSERT_TRUE(hooks); | 384 ASSERT_TRUE(hooks); |
384 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); | 385 v8::Local<v8::Object> js_hooks = hooks->GetJSHookInterface(context); |
385 v8::Local<v8::Function> function = FunctionFromString(context, kHook); | 386 v8::Local<v8::Function> function = FunctionFromString(context, kHook); |
386 v8::Local<v8::Value> args[] = {js_hooks}; | 387 v8::Local<v8::Value> args[] = {js_hooks}; |
387 RunFunctionOnGlobal(function, context, arraysize(args), args); | 388 RunFunctionOnGlobal(function, context, arraysize(args), args); |
388 | 389 |
389 { | 390 { |
390 const char kTestCall[] = | 391 const char kTestCall[] = |
391 "obj.functionWithCallback('foo', function() {\n" | 392 "obj.functionWithCallback('foo', function() {\n" |
(...skipping 21 matching lines...) Expand all Loading... |
413 } | 414 } |
414 | 415 |
415 // Test that references to other API's types works. | 416 // Test that references to other API's types works. |
416 TEST_F(APIBindingsSystemTest, CrossAPIReferences) { | 417 TEST_F(APIBindingsSystemTest, CrossAPIReferences) { |
417 v8::HandleScope handle_scope(isolate()); | 418 v8::HandleScope handle_scope(isolate()); |
418 v8::Local<v8::Context> context = MainContext(); | 419 v8::Local<v8::Context> context = MainContext(); |
419 | 420 |
420 // Instantiate gamma API. Note: It's important that we haven't instantiated | 421 // Instantiate gamma API. Note: It's important that we haven't instantiated |
421 // alpha API yet, since this tests that we can lazily populate the type | 422 // alpha API yet, since this tests that we can lazily populate the type |
422 // information. | 423 // information. |
423 v8::Local<v8::Object> gamma_api = bindings_system()->CreateAPIInstance( | 424 v8::Local<v8::Object> gamma_api = |
424 kGammaAPIName, context, base::Bind(&AllowAllAPIs), nullptr); | 425 bindings_system()->CreateAPIInstance(kGammaAPIName, context, nullptr); |
425 ASSERT_FALSE(gamma_api.IsEmpty()); | 426 ASSERT_FALSE(gamma_api.IsEmpty()); |
426 | 427 |
427 { | 428 { |
428 // Test a simple call -> response. | 429 // Test a simple call -> response. |
429 const char kTestCall[] = "obj.functionWithExternalRef({prop1: 'foo'});"; | 430 const char kTestCall[] = "obj.functionWithExternalRef({prop1: 'foo'});"; |
430 CallFunctionOnObject(context, gamma_api, kTestCall); | 431 CallFunctionOnObject(context, gamma_api, kTestCall); |
431 ValidateLastRequest("gamma.functionWithExternalRef", "[{'prop1':'foo'}]"); | 432 ValidateLastRequest("gamma.functionWithExternalRef", "[{'prop1':'foo'}]"); |
432 reset_last_request(); | 433 reset_last_request(); |
433 } | 434 } |
434 } | 435 } |
(...skipping 12 matching lines...) Expand all Loading... |
447 .ToChecked(); | 448 .ToChecked(); |
448 return ret.As<v8::Value>(); | 449 return ret.As<v8::Value>(); |
449 }; | 450 }; |
450 | 451 |
451 auto test_hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); | 452 auto test_hooks = base::MakeUnique<APIBindingHooksTestDelegate>(); |
452 test_hooks->SetCustomEvent(base::Bind(create_custom_event)); | 453 test_hooks->SetCustomEvent(base::Bind(create_custom_event)); |
453 APIBindingHooks* binding_hooks = | 454 APIBindingHooks* binding_hooks = |
454 bindings_system()->GetHooksForAPI(kAlphaAPIName); | 455 bindings_system()->GetHooksForAPI(kAlphaAPIName); |
455 binding_hooks->SetDelegate(std::move(test_hooks)); | 456 binding_hooks->SetDelegate(std::move(test_hooks)); |
456 | 457 |
457 v8::Local<v8::Object> api = bindings_system()->CreateAPIInstance( | 458 v8::Local<v8::Object> api = |
458 kAlphaAPIName, context, base::Bind(&AllowAllAPIs), nullptr); | 459 bindings_system()->CreateAPIInstance(kAlphaAPIName, context, nullptr); |
459 | 460 |
460 v8::Local<v8::Value> event = | 461 v8::Local<v8::Value> event = |
461 GetPropertyFromObject(api, context, "alphaEvent"); | 462 GetPropertyFromObject(api, context, "alphaEvent"); |
462 ASSERT_TRUE(event->IsObject()); | 463 ASSERT_TRUE(event->IsObject()); |
463 EXPECT_EQ( | 464 EXPECT_EQ( |
464 "\"alpha.alphaEvent\"", | 465 "\"alpha.alphaEvent\"", |
465 GetStringPropertyFromObject(event.As<v8::Object>(), context, "name")); | 466 GetStringPropertyFromObject(event.As<v8::Object>(), context, "name")); |
466 v8::Local<v8::Value> event2 = | 467 v8::Local<v8::Value> event2 = |
467 GetPropertyFromObject(api, context, "alphaEvent"); | 468 GetPropertyFromObject(api, context, "alphaEvent"); |
468 EXPECT_EQ(event, event2); | 469 EXPECT_EQ(event, event2); |
469 | 470 |
470 v8::Local<v8::Value> other_event = | 471 v8::Local<v8::Value> other_event = |
471 GetPropertyFromObject(api, context, "alphaOtherEvent"); | 472 GetPropertyFromObject(api, context, "alphaOtherEvent"); |
472 ASSERT_TRUE(other_event->IsObject()); | 473 ASSERT_TRUE(other_event->IsObject()); |
473 EXPECT_EQ("\"alpha.alphaOtherEvent\"", | 474 EXPECT_EQ("\"alpha.alphaOtherEvent\"", |
474 GetStringPropertyFromObject(other_event.As<v8::Object>(), context, | 475 GetStringPropertyFromObject(other_event.As<v8::Object>(), context, |
475 "name")); | 476 "name")); |
476 EXPECT_NE(event, other_event); | 477 EXPECT_NE(event, other_event); |
477 } | 478 } |
478 | 479 |
479 } // namespace extensions | 480 } // namespace extensions |
OLD | NEW |