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 "content/public/child/v8_value_converter.h" | 10 #include "content/public/child/v8_value_converter.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 " 'name': 'optionalCallback'," | 89 " 'name': 'optionalCallback'," |
90 " 'parameters': [{" | 90 " 'parameters': [{" |
91 " 'name': 'callback'," | 91 " 'name': 'callback'," |
92 " 'type': 'function'," | 92 " 'type': 'function'," |
93 " 'optional': true" | 93 " 'optional': true" |
94 " }]" | 94 " }]" |
95 "}]"; | 95 "}]"; |
96 | 96 |
97 const char kError[] = "Uncaught TypeError: Invalid invocation"; | 97 const char kError[] = "Uncaught TypeError: Invalid invocation"; |
98 | 98 |
99 void RunJSFunction(v8::Local<v8::Function> function, | |
100 v8::Local<v8::Context> context, | |
101 int argc, | |
102 v8::Local<v8::Value> argv[]) { | |
103 v8::MaybeLocal<v8::Value> result = | |
104 function->Call(context, context->Global(), argc, argv); | |
105 EXPECT_FALSE(result.IsEmpty()); | |
106 } | |
107 | |
108 } // namespace | 99 } // namespace |
109 | 100 |
110 class APIBindingTest : public gin::V8Test { | 101 class APIBindingTest : public gin::V8Test { |
111 public: | 102 public: |
112 void OnFunctionCall(const std::string& name, | 103 void OnFunctionCall(const std::string& name, |
113 std::unique_ptr<base::ListValue> arguments, | 104 std::unique_ptr<base::ListValue> arguments, |
114 v8::Isolate* isolate, | 105 v8::Isolate* isolate, |
115 v8::Local<v8::Context> context, | 106 v8::Local<v8::Context> context, |
116 v8::Local<v8::Function> callback) { | 107 v8::Local<v8::Function> callback) { |
117 last_request_id_.clear(); | 108 last_request_id_.clear(); |
118 arguments_ = std::move(arguments); | 109 arguments_ = std::move(arguments); |
119 if (!callback.IsEmpty()) { | 110 if (!callback.IsEmpty()) { |
120 last_request_id_ = | 111 last_request_id_ = |
121 request_handler_->AddPendingRequest(isolate, callback, context); | 112 request_handler_->AddPendingRequest(isolate, callback, context); |
122 } | 113 } |
123 } | 114 } |
124 | 115 |
125 protected: | 116 protected: |
126 APIBindingTest() {} | 117 APIBindingTest() {} |
127 void SetUp() override { | 118 void SetUp() override { |
128 gin::V8Test::SetUp(); | 119 gin::V8Test::SetUp(); |
129 v8::HandleScope handle_scope(instance_->isolate()); | 120 v8::HandleScope handle_scope(instance_->isolate()); |
130 holder_ = base::MakeUnique<gin::ContextHolder>(instance_->isolate()); | 121 holder_ = base::MakeUnique<gin::ContextHolder>(instance_->isolate()); |
131 holder_->SetContext( | 122 holder_->SetContext( |
132 v8::Local<v8::Context>::New(instance_->isolate(), context_)); | 123 v8::Local<v8::Context>::New(instance_->isolate(), context_)); |
133 request_handler_ = base::MakeUnique<APIRequestHandler>( | 124 request_handler_ = base::MakeUnique<APIRequestHandler>( |
134 base::Bind(&RunJSFunction)); | 125 base::Bind(&RunFunctionOnGlobalAndIgnoreResult)); |
135 } | 126 } |
136 | 127 |
137 void TearDown() override { | 128 void TearDown() override { |
138 request_handler_.reset(); | 129 request_handler_.reset(); |
139 holder_.reset(); | 130 holder_.reset(); |
140 gin::V8Test::TearDown(); | 131 gin::V8Test::TearDown(); |
141 } | 132 } |
142 | 133 |
143 void ExpectPass(v8::Local<v8::Object> object, | 134 void ExpectPass(v8::Local<v8::Object> object, |
144 const std::string& script_source, | 135 const std::string& script_source, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 std::string wrapped_script_source = | 172 std::string wrapped_script_source = |
182 base::StringPrintf("(function(obj) { %s })", script_source.c_str()); | 173 base::StringPrintf("(function(obj) { %s })", script_source.c_str()); |
183 v8::Isolate* isolate = instance_->isolate(); | 174 v8::Isolate* isolate = instance_->isolate(); |
184 | 175 |
185 v8::Local<v8::Context> context = | 176 v8::Local<v8::Context> context = |
186 v8::Local<v8::Context>::New(isolate, context_); | 177 v8::Local<v8::Context>::New(isolate, context_); |
187 v8::Local<v8::Function> func = | 178 v8::Local<v8::Function> func = |
188 FunctionFromString(context, wrapped_script_source); | 179 FunctionFromString(context, wrapped_script_source); |
189 ASSERT_FALSE(func.IsEmpty()); | 180 ASSERT_FALSE(func.IsEmpty()); |
190 | 181 |
191 v8::TryCatch try_catch(isolate); | |
192 v8::Local<v8::Value> argv[] = {object}; | 182 v8::Local<v8::Value> argv[] = {object}; |
193 func->Call(v8::Undefined(isolate), 1, argv); | |
194 | 183 |
195 if (should_pass) { | 184 if (should_pass) { |
196 EXPECT_FALSE(try_catch.HasCaught()) | 185 RunFunction(func, context, 1, argv); |
197 << gin::V8ToString(try_catch.Message()->Get()); | |
198 ASSERT_TRUE(arguments_) << script_source; | 186 ASSERT_TRUE(arguments_) << script_source; |
199 EXPECT_EQ(expected_json_arguments, ValueToString(*arguments_)); | 187 EXPECT_EQ(expected_json_arguments, ValueToString(*arguments_)); |
200 } else { | 188 } else { |
201 ASSERT_TRUE(try_catch.HasCaught()) << script_source; | 189 RunFunctionAndExpectError(func, context, 1, argv, expected_error); |
202 std::string message = gin::V8ToString(try_catch.Message()->Get()); | 190 EXPECT_FALSE(arguments_); |
203 EXPECT_EQ(expected_error, message); | |
204 } | 191 } |
205 | 192 |
206 arguments_.reset(); | 193 arguments_.reset(); |
207 } | 194 } |
208 | 195 |
209 TEST_F(APIBindingTest, Test) { | 196 TEST_F(APIBindingTest, Test) { |
210 std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); | 197 std::unique_ptr<base::ListValue> functions = ListValueFromString(kFunctions); |
211 ASSERT_TRUE(functions); | 198 ASSERT_TRUE(functions); |
212 ArgumentSpec::RefMap refs; | 199 ArgumentSpec::RefMap refs; |
213 APIBinding binding( | 200 APIBinding binding( |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 v8::Local<v8::Object> binding_object = | 366 v8::Local<v8::Object> binding_object = |
380 binding.CreateInstance(context, isolate); | 367 binding.CreateInstance(context, isolate); |
381 | 368 |
382 ExpectPass(binding_object, kTestCall, "['foo']"); | 369 ExpectPass(binding_object, kTestCall, "['foo']"); |
383 ASSERT_FALSE(last_request_id().empty()); | 370 ASSERT_FALSE(last_request_id().empty()); |
384 const char kResponseArgsJson[] = "['response',1,{'key':42}]"; | 371 const char kResponseArgsJson[] = "['response',1,{'key':42}]"; |
385 std::unique_ptr<base::ListValue> expected_args = | 372 std::unique_ptr<base::ListValue> expected_args = |
386 ListValueFromString(kResponseArgsJson); | 373 ListValueFromString(kResponseArgsJson); |
387 request_handler()->CompleteRequest(last_request_id(), *expected_args); | 374 request_handler()->CompleteRequest(last_request_id(), *expected_args); |
388 | 375 |
389 v8::Local<v8::Value> res; | 376 v8::Local<v8::Value> res = |
390 ASSERT_TRUE(context->Global() | 377 GetPropertyFromObject(context->Global(), context, "callbackArguments"); |
391 ->Get(context, gin::StringToV8(isolate, "callbackArguments")) | |
392 .ToLocal(&res)); | |
393 | 378 |
394 std::unique_ptr<base::Value> out_val = V8ToBaseValue(res, context); | 379 std::unique_ptr<base::Value> out_val = V8ToBaseValue(res, context); |
395 ASSERT_TRUE(out_val); | 380 ASSERT_TRUE(out_val); |
396 EXPECT_EQ(ReplaceSingleQuotes(kResponseArgsJson), ValueToString(*out_val)); | 381 EXPECT_EQ(ReplaceSingleQuotes(kResponseArgsJson), ValueToString(*out_val)); |
397 } | 382 } |
398 | 383 |
399 } // namespace extensions | 384 } // namespace extensions |
OLD | NEW |