Commit f89894a0 authored by jbroman's avatar jbroman Committed by Commit bot

[Extensions Bindings] Make function definitions optional for an API.

chrome.storage, for instance, has events but no functions directly on the
API object. See extensions/common/api/storage.json.

BUG=653596

Review-Url: https://codereview.chromium.org/2610743002
Cr-Commit-Position: refs/heads/master@{#441459}
parent ff829858
...@@ -64,7 +64,7 @@ void CallbackHelper(const v8::FunctionCallbackInfo<v8::Value>& info) { ...@@ -64,7 +64,7 @@ void CallbackHelper(const v8::FunctionCallbackInfo<v8::Value>& info) {
} // namespace } // namespace
APIBinding::APIBinding(const std::string& api_name, APIBinding::APIBinding(const std::string& api_name,
const base::ListValue& function_definitions, const base::ListValue* function_definitions,
const base::ListValue* type_definitions, const base::ListValue* type_definitions,
const base::ListValue* event_definitions, const base::ListValue* event_definitions,
const APIMethodCallback& callback, const APIMethodCallback& callback,
...@@ -76,15 +76,17 @@ APIBinding::APIBinding(const std::string& api_name, ...@@ -76,15 +76,17 @@ APIBinding::APIBinding(const std::string& api_name,
type_refs_(type_refs), type_refs_(type_refs),
weak_factory_(this) { weak_factory_(this) {
DCHECK(!method_callback_.is_null()); DCHECK(!method_callback_.is_null());
for (const auto& func : function_definitions) { if (function_definitions) {
const base::DictionaryValue* func_dict = nullptr; for (const auto& func : *function_definitions) {
CHECK(func->GetAsDictionary(&func_dict)); const base::DictionaryValue* func_dict = nullptr;
std::string name; CHECK(func->GetAsDictionary(&func_dict));
CHECK(func_dict->GetString("name", &name)); std::string name;
CHECK(func_dict->GetString("name", &name));
const base::ListValue* params = nullptr;
CHECK(func_dict->GetList("parameters", &params)); const base::ListValue* params = nullptr;
signatures_[name] = base::MakeUnique<APISignature>(*params); CHECK(func_dict->GetList("parameters", &params));
signatures_[name] = base::MakeUnique<APISignature>(*params);
}
} }
if (type_definitions) { if (type_definitions) {
for (const auto& type : *type_definitions) { for (const auto& type : *type_definitions) {
......
...@@ -57,10 +57,10 @@ class APIBinding { ...@@ -57,10 +57,10 @@ class APIBinding {
using HandlerCallback = base::Callback<void(gin::Arguments*)>; using HandlerCallback = base::Callback<void(gin::Arguments*)>;
// The ArgumentSpec::RefMap is required to outlive this object. // The ArgumentSpec::RefMap is required to outlive this object.
// |type_definitions| and |event_definitions| may be null if the API does not // |function_definitions|, |type_definitions| and |event_definitions|
// specify any types or events. // may be null if the API does not specify any of that category.
APIBinding(const std::string& name, APIBinding(const std::string& name,
const base::ListValue& function_definitions, const base::ListValue* function_definitions,
const base::ListValue* type_definitions, const base::ListValue* type_definitions,
const base::ListValue* event_definitions, const base::ListValue* event_definitions,
const APIMethodCallback& callback, const APIMethodCallback& callback,
......
...@@ -189,12 +189,32 @@ void APIBindingUnittest::RunTest(v8::Local<v8::Object> object, ...@@ -189,12 +189,32 @@ void APIBindingUnittest::RunTest(v8::Local<v8::Object> object,
arguments_.reset(); arguments_.reset();
} }
TEST_F(APIBindingUnittest, TestEmptyAPI) {
ArgumentSpec::RefMap refs;
APIBinding binding(
"empty", nullptr, nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
EXPECT_TRUE(refs.empty());
v8::HandleScope handle_scope(isolate());
v8::Local<v8::Context> context = ContextLocal();
APIEventHandler event_handler(
base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
v8::Local<v8::Object> binding_object = binding.CreateInstance(
context, isolate(), &event_handler, base::Bind(&AllowAllAPIs));
EXPECT_EQ(
0u,
binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length());
}
TEST_F(APIBindingUnittest, Test) { TEST_F(APIBindingUnittest, Test) {
std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions);
ASSERT_TRUE(functions); ASSERT_TRUE(functions);
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, nullptr, "test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
EXPECT_TRUE(refs.empty()); EXPECT_TRUE(refs.empty());
...@@ -295,7 +315,7 @@ TEST_F(APIBindingUnittest, TypeRefsTest) { ...@@ -295,7 +315,7 @@ TEST_F(APIBindingUnittest, TypeRefsTest) {
ASSERT_TRUE(types); ASSERT_TRUE(types);
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, types.get(), nullptr, "test", functions.get(), types.get(), nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
EXPECT_EQ(2u, refs.size()); EXPECT_EQ(2u, refs.size());
...@@ -341,7 +361,7 @@ TEST_F(APIBindingUnittest, RestrictedAPIs) { ...@@ -341,7 +361,7 @@ TEST_F(APIBindingUnittest, RestrictedAPIs) {
ASSERT_TRUE(functions); ASSERT_TRUE(functions);
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, nullptr, "test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
...@@ -384,7 +404,7 @@ TEST_F(APIBindingUnittest, TestEventCreation) { ...@@ -384,7 +404,7 @@ TEST_F(APIBindingUnittest, TestEventCreation) {
ASSERT_TRUE(functions); ASSERT_TRUE(functions);
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, events.get(), "test", functions.get(), nullptr, events.get(),
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
...@@ -420,7 +440,7 @@ TEST_F(APIBindingUnittest, TestDisposedContext) { ...@@ -420,7 +440,7 @@ TEST_F(APIBindingUnittest, TestDisposedContext) {
ASSERT_TRUE(functions); ASSERT_TRUE(functions);
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, nullptr, "test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs); base::MakeUnique<APIBindingHooks>(binding::RunJSFunction()), &refs);
EXPECT_TRUE(refs.empty()); EXPECT_TRUE(refs.empty());
...@@ -466,7 +486,7 @@ TEST_F(APIBindingUnittest, TestCustomHooks) { ...@@ -466,7 +486,7 @@ TEST_F(APIBindingUnittest, TestCustomHooks) {
hooks->RegisterHandleRequest("test.oneString", base::Bind(hook, &did_call)); hooks->RegisterHandleRequest("test.oneString", base::Bind(hook, &did_call));
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, nullptr, "test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
std::move(hooks), &refs); std::move(hooks), &refs);
EXPECT_TRUE(refs.empty()); EXPECT_TRUE(refs.empty());
...@@ -517,7 +537,7 @@ TEST_F(APIBindingUnittest, TestJSCustomHook) { ...@@ -517,7 +537,7 @@ TEST_F(APIBindingUnittest, TestJSCustomHook) {
ArgumentSpec::RefMap refs; ArgumentSpec::RefMap refs;
APIBinding binding( APIBinding binding(
"test", *functions, nullptr, nullptr, "test", functions.get(), nullptr, nullptr,
base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)), base::Bind(&APIBindingUnittest::OnFunctionCall, base::Unretained(this)),
std::move(hooks), &refs); std::move(hooks), &refs);
EXPECT_TRUE(refs.empty()); EXPECT_TRUE(refs.empty());
......
...@@ -45,9 +45,8 @@ std::unique_ptr<APIBinding> APIBindingsSystem::CreateNewAPIBinding( ...@@ -45,9 +45,8 @@ std::unique_ptr<APIBinding> APIBindingsSystem::CreateNewAPIBinding(
const base::DictionaryValue& api_schema = get_api_schema_.Run(api_name); const base::DictionaryValue& api_schema = get_api_schema_.Run(api_name);
const base::ListValue* function_definitions = nullptr; const base::ListValue* function_definitions = nullptr;
CHECK(api_schema.GetList("functions", &function_definitions)); api_schema.GetList("functions", &function_definitions);
const base::ListValue* type_definitions = nullptr; const base::ListValue* type_definitions = nullptr;
// Type definitions might not exist for the given API.
api_schema.GetList("types", &type_definitions); api_schema.GetList("types", &type_definitions);
const base::ListValue* event_definitions = nullptr; const base::ListValue* event_definitions = nullptr;
api_schema.GetList("events", &event_definitions); api_schema.GetList("events", &event_definitions);
...@@ -66,7 +65,7 @@ std::unique_ptr<APIBinding> APIBindingsSystem::CreateNewAPIBinding( ...@@ -66,7 +65,7 @@ std::unique_ptr<APIBinding> APIBindingsSystem::CreateNewAPIBinding(
} }
return base::MakeUnique<APIBinding>( return base::MakeUnique<APIBinding>(
api_name, *function_definitions, type_definitions, event_definitions, api_name, function_definitions, type_definitions, event_definitions,
base::Bind(&APIBindingsSystem::OnAPICall, base::Unretained(this)), base::Bind(&APIBindingsSystem::OnAPICall, base::Unretained(this)),
std::move(hooks), &type_reference_map_); std::move(hooks), &type_reference_map_);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment