OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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_signature.h" | 5 #include "extensions/renderer/api_signature.h" |
6 | 6 |
7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "extensions/renderer/api_binding_test.h" | 9 #include "extensions/renderer/api_binding_test.h" |
10 #include "extensions/renderer/api_binding_test_util.h" | 10 #include "extensions/renderer/api_binding_test_util.h" |
| 11 #include "extensions/renderer/api_invocation_errors.h" |
11 #include "extensions/renderer/api_type_reference_map.h" | 12 #include "extensions/renderer/api_type_reference_map.h" |
12 #include "extensions/renderer/argument_spec.h" | 13 #include "extensions/renderer/argument_spec.h" |
13 #include "extensions/renderer/argument_spec_builder.h" | 14 #include "extensions/renderer/argument_spec_builder.h" |
14 #include "gin/converter.h" | 15 #include "gin/converter.h" |
15 | 16 |
16 namespace extensions { | 17 namespace extensions { |
17 namespace { | 18 namespace { |
18 | 19 |
19 using SpecVector = std::vector<std::unique_ptr<ArgumentSpec>>; | 20 using SpecVector = std::vector<std::unique_ptr<ArgumentSpec>>; |
20 | 21 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 137 |
137 type_refs_.AddSpec("refEnum", ArgumentSpecBuilder(ArgumentType::STRING) | 138 type_refs_.AddSpec("refEnum", ArgumentSpecBuilder(ArgumentType::STRING) |
138 .SetEnums({"alpha", "beta"}) | 139 .SetEnums({"alpha", "beta"}) |
139 .Build()); | 140 .Build()); |
140 } | 141 } |
141 | 142 |
142 void ExpectPass(const APISignature& signature, | 143 void ExpectPass(const APISignature& signature, |
143 base::StringPiece arg_values, | 144 base::StringPiece arg_values, |
144 base::StringPiece expected_parsed_args, | 145 base::StringPiece expected_parsed_args, |
145 bool expect_callback) { | 146 bool expect_callback) { |
146 RunTest(signature, arg_values, expected_parsed_args, expect_callback, true); | 147 RunTest(signature, arg_values, expected_parsed_args, expect_callback, true, |
| 148 std::string()); |
147 } | 149 } |
148 | 150 |
149 void ExpectFailure(const APISignature& signature, | 151 void ExpectFailure(const APISignature& signature, |
150 base::StringPiece arg_values) { | 152 base::StringPiece arg_values, |
151 RunTest(signature, arg_values, base::StringPiece(), false, false); | 153 const std::string& expected_error) { |
| 154 RunTest(signature, arg_values, base::StringPiece(), false, false, |
| 155 expected_error); |
152 } | 156 } |
153 | 157 |
154 private: | 158 private: |
155 void RunTest(const APISignature& signature, | 159 void RunTest(const APISignature& signature, |
156 base::StringPiece arg_values, | 160 base::StringPiece arg_values, |
157 base::StringPiece expected_parsed_args, | 161 base::StringPiece expected_parsed_args, |
158 bool expect_callback, | 162 bool expect_callback, |
159 bool should_succeed) { | 163 bool should_succeed, |
| 164 const std::string& expected_error) { |
160 SCOPED_TRACE(arg_values); | 165 SCOPED_TRACE(arg_values); |
161 v8::Local<v8::Context> context = MainContext(); | 166 v8::Local<v8::Context> context = MainContext(); |
162 v8::Local<v8::Value> v8_args = V8ValueFromScriptSource(context, arg_values); | 167 v8::Local<v8::Value> v8_args = V8ValueFromScriptSource(context, arg_values); |
163 ASSERT_FALSE(v8_args.IsEmpty()); | 168 ASSERT_FALSE(v8_args.IsEmpty()); |
164 ASSERT_TRUE(v8_args->IsArray()); | 169 ASSERT_TRUE(v8_args->IsArray()); |
165 std::vector<v8::Local<v8::Value>> vector_args; | 170 std::vector<v8::Local<v8::Value>> vector_args; |
166 ASSERT_TRUE(gin::ConvertFromV8(isolate(), v8_args, &vector_args)); | 171 ASSERT_TRUE(gin::ConvertFromV8(isolate(), v8_args, &vector_args)); |
167 | 172 |
168 std::unique_ptr<base::ListValue> result; | 173 std::unique_ptr<base::ListValue> result; |
169 v8::Local<v8::Function> callback; | 174 v8::Local<v8::Function> callback; |
170 std::string error; | 175 std::string error; |
171 bool success = signature.ParseArgumentsToJSON( | 176 bool success = signature.ParseArgumentsToJSON( |
172 context, vector_args, type_refs_, &result, &callback, &error); | 177 context, vector_args, type_refs_, &result, &callback, &error); |
173 EXPECT_EQ(should_succeed, success); | 178 EXPECT_EQ(should_succeed, success); |
174 ASSERT_EQ(should_succeed, !!result); | 179 ASSERT_EQ(should_succeed, !!result); |
175 EXPECT_EQ(expect_callback, !callback.IsEmpty()); | 180 EXPECT_EQ(expect_callback, !callback.IsEmpty()); |
176 if (should_succeed) { | 181 if (should_succeed) { |
177 EXPECT_EQ(ReplaceSingleQuotes(expected_parsed_args), | 182 EXPECT_EQ(ReplaceSingleQuotes(expected_parsed_args), |
178 ValueToString(*result)); | 183 ValueToString(*result)); |
| 184 } else { |
| 185 EXPECT_EQ(expected_error, error); |
179 } | 186 } |
180 } | 187 } |
181 | 188 |
182 APITypeReferenceMap type_refs_; | 189 APITypeReferenceMap type_refs_; |
183 | 190 |
184 DISALLOW_COPY_AND_ASSIGN(APISignatureTest); | 191 DISALLOW_COPY_AND_ASSIGN(APISignatureTest); |
185 }; | 192 }; |
186 | 193 |
187 TEST_F(APISignatureTest, BasicSignatureParsing) { | 194 TEST_F(APISignatureTest, BasicSignatureParsing) { |
| 195 using namespace api_errors; |
| 196 |
188 v8::HandleScope handle_scope(isolate()); | 197 v8::HandleScope handle_scope(isolate()); |
189 | 198 |
190 { | 199 { |
191 auto signature = OneString(); | 200 auto signature = OneString(); |
192 ExpectPass(*signature, "['foo']", "['foo']", false); | 201 ExpectPass(*signature, "['foo']", "['foo']", false); |
193 ExpectPass(*signature, "['']", "['']", false); | 202 ExpectPass(*signature, "['']", "['']", false); |
194 ExpectFailure(*signature, "[1]"); | 203 ExpectFailure( |
195 ExpectFailure(*signature, "[]"); | 204 *signature, "[1]", |
196 ExpectFailure(*signature, "[{}]"); | 205 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
197 ExpectFailure(*signature, "['foo', 'bar']"); | 206 ExpectFailure(*signature, "[]", MissingRequiredArgument("string")); |
| 207 ExpectFailure( |
| 208 *signature, "[{}]", |
| 209 ArgumentError("string", InvalidType(kTypeString, kTypeObject))); |
| 210 ExpectFailure(*signature, "['foo', 'bar']", TooManyArguments()); |
198 } | 211 } |
199 | 212 |
200 { | 213 { |
201 auto signature = StringAndInt(); | 214 auto signature = StringAndInt(); |
202 ExpectPass(*signature, "['foo', 42]", "['foo',42]", false); | 215 ExpectPass(*signature, "['foo', 42]", "['foo',42]", false); |
203 ExpectPass(*signature, "['foo', -1]", "['foo',-1]", false); | 216 ExpectPass(*signature, "['foo', -1]", "['foo',-1]", false); |
204 ExpectFailure(*signature, "[1]"); | 217 ExpectFailure( |
205 ExpectFailure(*signature, "['foo'];"); | 218 *signature, "[1]", |
206 ExpectFailure(*signature, "[1, 'foo']"); | 219 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
207 ExpectFailure(*signature, "['foo', 'foo']"); | 220 ExpectFailure(*signature, "['foo'];", MissingRequiredArgument("int")); |
208 ExpectFailure(*signature, "['foo', '1']"); | 221 ExpectFailure( |
209 ExpectFailure(*signature, "['foo', 2.3]"); | 222 *signature, "[1, 'foo']", |
| 223 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
| 224 ExpectFailure(*signature, "['foo', 'foo']", |
| 225 ArgumentError("int", InvalidType(kTypeInteger, kTypeString))); |
| 226 ExpectFailure(*signature, "['foo', '1']", |
| 227 ArgumentError("int", InvalidType(kTypeInteger, kTypeString))); |
| 228 ExpectFailure(*signature, "['foo', 2.3]", |
| 229 ArgumentError("int", InvalidType(kTypeInteger, kTypeDouble))); |
210 } | 230 } |
211 | 231 |
212 { | 232 { |
213 auto signature = StringOptionalIntAndBool(); | 233 auto signature = StringOptionalIntAndBool(); |
214 ExpectPass(*signature, "['foo', 42, true]", "['foo',42,true]", false); | 234 ExpectPass(*signature, "['foo', 42, true]", "['foo',42,true]", false); |
215 ExpectPass(*signature, "['foo', true]", "['foo',null,true]", false); | 235 ExpectPass(*signature, "['foo', true]", "['foo',null,true]", false); |
216 ExpectFailure(*signature, "['foo', 'bar', true]"); | 236 ExpectFailure( |
| 237 *signature, "['foo', 'bar', true]", |
| 238 ArgumentError("bool", InvalidType(kTypeBoolean, kTypeString))); |
217 } | 239 } |
218 | 240 |
219 { | 241 { |
220 auto signature = OneObject(); | 242 auto signature = OneObject(); |
221 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); | 243 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); |
222 ExpectFailure(*signature, | 244 ExpectFailure(*signature, |
223 "[{ get prop1() { throw new Error('Badness'); } }]"); | 245 "[{ get prop1() { throw new Error('Badness'); } }]", |
| 246 ArgumentError("obj", ScriptThrewError())); |
224 } | 247 } |
225 | 248 |
226 { | 249 { |
227 auto signature = NoArgs(); | 250 auto signature = NoArgs(); |
228 ExpectPass(*signature, "[]", "[]", false); | 251 ExpectPass(*signature, "[]", "[]", false); |
229 ExpectFailure(*signature, "[0]"); | 252 ExpectFailure(*signature, "[0]", TooManyArguments()); |
230 ExpectFailure(*signature, "['']"); | 253 ExpectFailure(*signature, "['']", TooManyArguments()); |
231 ExpectFailure(*signature, "[null]"); | 254 ExpectFailure(*signature, "[null]", TooManyArguments()); |
232 ExpectFailure(*signature, "[undefined]"); | 255 ExpectFailure(*signature, "[undefined]", TooManyArguments()); |
233 } | 256 } |
234 | 257 |
235 { | 258 { |
236 auto signature = IntAndCallback(); | 259 auto signature = IntAndCallback(); |
237 ExpectPass(*signature, "[1, function() {}]", "[1]", true); | 260 ExpectPass(*signature, "[1, function() {}]", "[1]", true); |
238 ExpectFailure(*signature, "[function() {}]"); | 261 ExpectFailure( |
239 ExpectFailure(*signature, "[1]"); | 262 *signature, "[function() {}]", |
| 263 ArgumentError("int", InvalidType(kTypeInteger, kTypeFunction))); |
| 264 ExpectFailure(*signature, "[1]", MissingRequiredArgument("callback")); |
240 } | 265 } |
241 | 266 |
242 { | 267 { |
243 auto signature = OptionalIntAndCallback(); | 268 auto signature = OptionalIntAndCallback(); |
244 ExpectPass(*signature, "[1, function() {}]", "[1]", true); | 269 ExpectPass(*signature, "[1, function() {}]", "[1]", true); |
245 ExpectPass(*signature, "[function() {}]", "[null]", true); | 270 ExpectPass(*signature, "[function() {}]", "[null]", true); |
246 ExpectFailure(*signature, "[1]"); | 271 ExpectFailure(*signature, "[1]", MissingRequiredArgument("callback")); |
247 } | 272 } |
248 | 273 |
249 { | 274 { |
250 auto signature = OptionalCallback(); | 275 auto signature = OptionalCallback(); |
251 ExpectPass(*signature, "[function() {}]", "[]", true); | 276 ExpectPass(*signature, "[function() {}]", "[]", true); |
252 ExpectPass(*signature, "[]", "[]", false); | 277 ExpectPass(*signature, "[]", "[]", false); |
253 ExpectPass(*signature, "[undefined]", "[]", false); | 278 ExpectPass(*signature, "[undefined]", "[]", false); |
254 ExpectFailure(*signature, "[0]"); | 279 ExpectFailure( |
| 280 *signature, "[0]", |
| 281 ArgumentError("callback", InvalidType(kTypeFunction, kTypeInteger))); |
255 } | 282 } |
256 | 283 |
257 { | 284 { |
258 auto signature = IntAnyOptionalObjectOptionalCallback(); | 285 auto signature = IntAnyOptionalObjectOptionalCallback(); |
259 ExpectPass(*signature, "[4, {foo: 'bar'}, function() {}]", | 286 ExpectPass(*signature, "[4, {foo: 'bar'}, function() {}]", |
260 "[4,{'foo':'bar'},null]", true); | 287 "[4,{'foo':'bar'},null]", true); |
261 ExpectPass(*signature, "[4, {foo: 'bar'}]", "[4,{'foo':'bar'},null]", | 288 ExpectPass(*signature, "[4, {foo: 'bar'}]", "[4,{'foo':'bar'},null]", |
262 false); | 289 false); |
263 ExpectPass(*signature, "[4, {foo: 'bar'}, {}]", "[4,{'foo':'bar'},{}]", | 290 ExpectPass(*signature, "[4, {foo: 'bar'}, {}]", "[4,{'foo':'bar'},{}]", |
264 false); | 291 false); |
265 ExpectFailure(*signature, "[4, function() {}]"); | 292 ExpectFailure(*signature, "[4, function() {}]", |
266 ExpectFailure(*signature, "[4]"); | 293 ArgumentError("any", UnserializableValue())); |
| 294 ExpectFailure(*signature, "[4]", MissingRequiredArgument("any")); |
267 } | 295 } |
268 } | 296 } |
269 | 297 |
270 TEST_F(APISignatureTest, TypeRefsTest) { | 298 TEST_F(APISignatureTest, TypeRefsTest) { |
| 299 using namespace api_errors; |
| 300 |
271 v8::HandleScope handle_scope(isolate()); | 301 v8::HandleScope handle_scope(isolate()); |
272 | 302 |
273 { | 303 { |
274 auto signature = RefObj(); | 304 auto signature = RefObj(); |
275 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); | 305 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); |
276 ExpectPass(*signature, "[{prop1: 'foo', prop2: 2}]", | 306 ExpectPass(*signature, "[{prop1: 'foo', prop2: 2}]", |
277 "[{'prop1':'foo','prop2':2}]", false); | 307 "[{'prop1':'foo','prop2':2}]", false); |
278 ExpectFailure(*signature, "[{prop1: 'foo', prop2: 'a'}]"); | 308 ExpectFailure( |
| 309 *signature, "[{prop1: 'foo', prop2: 'a'}]", |
| 310 ArgumentError("obj", PropertyError("prop2", InvalidType(kTypeInteger, |
| 311 kTypeString)))); |
279 } | 312 } |
280 | 313 |
281 { | 314 { |
282 auto signature = RefEnum(); | 315 auto signature = RefEnum(); |
283 ExpectPass(*signature, "['alpha']", "['alpha']", false); | 316 ExpectPass(*signature, "['alpha']", "['alpha']", false); |
284 ExpectPass(*signature, "['beta']", "['beta']", false); | 317 ExpectPass(*signature, "['beta']", "['beta']", false); |
285 ExpectFailure(*signature, "['gamma']"); | 318 ExpectFailure(*signature, "['gamma']", |
| 319 ArgumentError("enum", InvalidEnumValue({"alpha", "beta"}))); |
286 } | 320 } |
287 } | 321 } |
288 | 322 |
289 } // namespace extensions | 323 } // namespace extensions |
OLD | NEW |