Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: extensions/renderer/api_binding_unittest.cc

Issue 2847843002: [Extensions Bindings] Move signature parsing tests to their own file (Closed)
Patch Set: Builder Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 28 matching lines...) Expand all
39 "}, {" 39 "}, {"
40 " 'name': 'stringAndInt'," 40 " 'name': 'stringAndInt',"
41 " 'parameters': [{" 41 " 'parameters': [{"
42 " 'type': 'string'," 42 " 'type': 'string',"
43 " 'name': 'str'" 43 " 'name': 'str'"
44 " }, {" 44 " }, {"
45 " 'type': 'integer'," 45 " 'type': 'integer',"
46 " 'name': 'int'" 46 " 'name': 'int'"
47 " }]" 47 " }]"
48 "}, {" 48 "}, {"
49 " 'name': 'stringOptionalIntAndBool',"
50 " 'parameters': [{"
51 " 'type': 'string',"
52 " 'name': 'str'"
53 " }, {"
54 " 'type': 'integer',"
55 " 'name': 'optionalint',"
56 " 'optional': true"
57 " }, {"
58 " 'type': 'boolean',"
59 " 'name': 'bool'"
60 " }]"
61 "}, {"
62 " 'name': 'oneObject'," 49 " 'name': 'oneObject',"
63 " 'parameters': [{" 50 " 'parameters': [{"
64 " 'type': 'object'," 51 " 'type': 'object',"
65 " 'name': 'foo'," 52 " 'name': 'foo',"
66 " 'properties': {" 53 " 'properties': {"
67 " 'prop1': {'type': 'string'}," 54 " 'prop1': {'type': 'string'},"
68 " 'prop2': {'type': 'string', 'optional': true}" 55 " 'prop2': {'type': 'string', 'optional': true}"
69 " }" 56 " }"
70 " }]" 57 " }]"
71 "}, {" 58 "}, {"
72 " 'name': 'noArgs',"
73 " 'parameters': []"
74 "}, {"
75 " 'name': 'intAndCallback'," 59 " 'name': 'intAndCallback',"
76 " 'parameters': [{" 60 " 'parameters': [{"
77 " 'name': 'int'," 61 " 'name': 'int',"
78 " 'type': 'integer'" 62 " 'type': 'integer'"
79 " }, {" 63 " }, {"
80 " 'name': 'callback'," 64 " 'name': 'callback',"
81 " 'type': 'function'" 65 " 'type': 'function'"
82 " }]" 66 " }]"
83 "}, {"
84 " 'name': 'optionalIntAndCallback',"
85 " 'parameters': [{"
86 " 'name': 'int',"
87 " 'type': 'integer',"
88 " 'optional': true"
89 " }, {"
90 " 'name': 'callback',"
91 " 'type': 'function'"
92 " }]"
93 "}, {"
94 " 'name': 'optionalCallback',"
95 " 'parameters': [{"
96 " 'name': 'callback',"
97 " 'type': 'function',"
98 " 'optional': true"
99 " }]"
100 "}, {"
101 " 'name': 'intAnyOptionalObjectOptionalCallback',"
102 " 'parameters': [{"
103 " 'type': 'integer', 'name': 'tabId', 'minimum': 0"
104 " }, {"
105 " 'type': 'any', 'name': 'message'"
106 " }, {"
107 " 'type': 'object',"
108 " 'name': 'options',"
109 " 'properties': {"
110 " 'frameId': {'type': 'integer', 'optional': true, 'minimum': 0}"
111 " },"
112 " 'optional': true"
113 " }, {"
114 " 'type': 'function', 'name': 'responseCallback', 'optional': true"
115 " }]"
116 "}]"; 67 "}]";
117 68
118 const char kError[] = "Uncaught TypeError: Invalid invocation"; 69 const char kError[] = "Uncaught TypeError: Invalid invocation";
119 70
120 bool AllowAllAPIs(const std::string& name) { 71 bool AllowAllAPIs(const std::string& name) {
121 return true; 72 return true;
122 } 73 }
123 74
124 void OnEventListenersChanged(const std::string& event_name, 75 void OnEventListenersChanged(const std::string& event_name,
125 binding::EventListenersChanged change, 76 binding::EventListenersChanged change,
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 v8::HandleScope handle_scope(isolate()); 263 v8::HandleScope handle_scope(isolate());
313 v8::Local<v8::Context> context = MainContext(); 264 v8::Local<v8::Context> context = MainContext();
314 265
315 v8::Local<v8::Object> binding_object = 266 v8::Local<v8::Object> binding_object =
316 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); 267 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs));
317 EXPECT_EQ( 268 EXPECT_EQ(
318 0u, 269 0u,
319 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length()); 270 binding_object->GetOwnPropertyNames(context).ToLocalChecked()->Length());
320 } 271 }
321 272
322 TEST_F(APIBindingUnittest, Test) { 273 // Tests the basic call -> request flow of the API binding (ensuring that
323 // TODO(devlin): Move this test to an api_signature_unittest file? It really 274 // functions are set up correctly and correctly enforced).
324 // only tests parsing. 275 TEST_F(APIBindingUnittest, TestBasicAPICalls) {
325 SetFunctions(kFunctions); 276 SetFunctions(kFunctions);
326 InitializeBinding(); 277 InitializeBinding();
327 278
328 v8::HandleScope handle_scope(isolate()); 279 v8::HandleScope handle_scope(isolate());
329 v8::Local<v8::Context> context = MainContext(); 280 v8::Local<v8::Context> context = MainContext();
330 281
331 v8::Local<v8::Object> binding_object = 282 v8::Local<v8::Object> binding_object =
332 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); 283 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs));
333 284
285 // Argument parsing is tested primarily in APISignature and ArgumentSpec
286 // tests, so do a few quick sanity checks...
334 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false); 287 ExpectPass(binding_object, "obj.oneString('foo');", "['foo']", false);
335 ExpectPass(binding_object, "obj.oneString('');", "['']", false);
336 ExpectFailure(binding_object, "obj.oneString(1);", kError); 288 ExpectFailure(binding_object, "obj.oneString(1);", kError);
337 ExpectFailure(binding_object, "obj.oneString();", kError); 289 ExpectPass(binding_object, "obj.stringAndInt('foo', 1)", "['foo',1]", false);
338 ExpectFailure(binding_object, "obj.oneString({});", kError); 290 ExpectFailure(binding_object, "obj.stringAndInt(1)", kError);
339 ExpectFailure(binding_object, "obj.oneString('foo', 'bar');", kError); 291 ExpectPass(binding_object, "obj.intAndCallback(1, function() {})", "[1]",
292 true);
293 ExpectFailure(binding_object, "obj.intAndCallback(function() {})", kError);
340 294
341 ExpectPass(binding_object, "obj.stringAndInt('foo', 42);", "['foo',42]", 295 // ...And an interesting case (throwing an error during parsing).
342 false);
343 ExpectPass(binding_object, "obj.stringAndInt('foo', -1);", "['foo',-1]",
344 false);
345 ExpectFailure(binding_object, "obj.stringAndInt(1);", kError);
346 ExpectFailure(binding_object, "obj.stringAndInt('foo');", kError);
347 ExpectFailure(binding_object, "obj.stringAndInt(1, 'foo');", kError);
348 ExpectFailure(binding_object, "obj.stringAndInt('foo', 'foo');", kError);
349 ExpectFailure(binding_object, "obj.stringAndInt('foo', '1');", kError);
350 ExpectFailure(binding_object, "obj.stringAndInt('foo', 2.3);", kError);
351
352 ExpectPass(binding_object, "obj.stringOptionalIntAndBool('foo', 42, true);",
353 "['foo',42,true]", false);
354 ExpectPass(binding_object, "obj.stringOptionalIntAndBool('foo', true);",
355 "['foo',null,true]", false);
356 ExpectFailure(binding_object,
357 "obj.stringOptionalIntAndBool('foo', 'bar', true);", kError);
358
359 ExpectPass(binding_object, "obj.oneObject({prop1: 'foo'});",
360 "[{'prop1':'foo'}]", false);
361 ExpectFailure( 296 ExpectFailure(
362 binding_object, 297 binding_object,
363 "obj.oneObject({ get prop1() { throw new Error('Badness'); } });", 298 "obj.oneObject({ get prop1() { throw new Error('Badness'); } });",
364 "Uncaught Error: Badness"); 299 "Uncaught Error: Badness");
365
366 ExpectPass(binding_object, "obj.noArgs()", "[]", false);
367 ExpectFailure(binding_object, "obj.noArgs(0)", kError);
368 ExpectFailure(binding_object, "obj.noArgs('')", kError);
369 ExpectFailure(binding_object, "obj.noArgs(null)", kError);
370 ExpectFailure(binding_object, "obj.noArgs(undefined)", kError);
371
372 ExpectPass(binding_object, "obj.intAndCallback(1, function() {})", "[1]",
373 true);
374 ExpectFailure(binding_object, "obj.intAndCallback(function() {})", kError);
375 ExpectFailure(binding_object, "obj.intAndCallback(1)", kError);
376
377 ExpectPass(binding_object, "obj.optionalIntAndCallback(1, function() {})",
378 "[1]", true);
379 ExpectPass(binding_object, "obj.optionalIntAndCallback(function() {})",
380 "[null]", true);
381 ExpectFailure(binding_object, "obj.optionalIntAndCallback(1)", kError);
382
383 ExpectPass(binding_object, "obj.optionalCallback(function() {})", "[]", true);
384 ExpectPass(binding_object, "obj.optionalCallback()", "[]", false);
385 ExpectPass(binding_object, "obj.optionalCallback(undefined)", "[]", false);
386 ExpectFailure(binding_object, "obj.optionalCallback(0)", kError);
387
388 ExpectPass(binding_object,
389 "obj.intAnyOptionalObjectOptionalCallback(4, {foo: 'bar'}, "
390 "function() {})",
391 "[4,{'foo':'bar'},null]", true);
392 ExpectPass(binding_object,
393 "obj.intAnyOptionalObjectOptionalCallback(4, {foo: 'bar'})",
394 "[4,{'foo':'bar'},null]", false);
395 ExpectPass(binding_object,
396 "obj.intAnyOptionalObjectOptionalCallback(4, {foo: 'bar'}, {})",
397 "[4,{'foo':'bar'},{}]", false);
398 ExpectFailure(binding_object,
399 "obj.intAnyOptionalObjectOptionalCallback(4, function() {})",
400 kError);
401 ExpectFailure(binding_object, "obj.intAnyOptionalObjectOptionalCallback(4)",
402 kError);
403 } 300 }
404 301
405 // Test that enum values are properly exposed on the binding object. 302 // Test that enum values are properly exposed on the binding object.
406 TEST_F(APIBindingUnittest, EnumValues) { 303 TEST_F(APIBindingUnittest, EnumValues) {
407 const char kTypes[] = 304 const char kTypes[] =
408 "[{" 305 "[{"
409 " 'id': 'first'," 306 " 'id': 'first',"
410 " 'type': 'string'," 307 " 'type': 'string',"
411 " 'enum': ['alpha', 'camelCase', 'Hyphen-ated'," 308 " 'enum': ['alpha', 'camelCase', 'Hyphen-ated',"
412 " 'SCREAMING', 'nums123', '42nums']" 309 " 'SCREAMING', 'nums123', '42nums']"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 v8::Local<v8::Context> context = MainContext(); 347 v8::Local<v8::Context> context = MainContext();
451 348
452 v8::Local<v8::Object> binding_object = 349 v8::Local<v8::Object> binding_object =
453 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); 350 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs));
454 351
455 EXPECT_EQ( 352 EXPECT_EQ(
456 "{\"\":\"\",\"OTHER\":\"other\"}", 353 "{\"\":\"\",\"OTHER\":\"other\"}",
457 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty")); 354 GetStringPropertyFromObject(binding_object, context, "enumWithEmpty"));
458 } 355 }
459 356
357 // Test that type references are correctly set up in the API.
460 TEST_F(APIBindingUnittest, TypeRefsTest) { 358 TEST_F(APIBindingUnittest, TypeRefsTest) {
461 const char kTypes[] = 359 const char kTypes[] =
462 "[{" 360 "[{"
463 " 'id': 'refObj'," 361 " 'id': 'refObj',"
464 " 'type': 'object'," 362 " 'type': 'object',"
465 " 'properties': {" 363 " 'properties': {"
466 " 'prop1': {'type': 'string'}," 364 " 'prop1': {'type': 'string'},"
467 " 'prop2': {'type': 'integer', 'optional': true}" 365 " 'prop2': {'type': 'integer', 'optional': true}"
468 " }" 366 " }"
469 "}, {" 367 "}, {"
(...skipping 22 matching lines...) Expand all
492 EXPECT_EQ(2u, type_refs().size()); 390 EXPECT_EQ(2u, type_refs().size());
493 EXPECT_TRUE(type_refs().GetSpec("refObj")); 391 EXPECT_TRUE(type_refs().GetSpec("refObj"));
494 EXPECT_TRUE(type_refs().GetSpec("refEnum")); 392 EXPECT_TRUE(type_refs().GetSpec("refEnum"));
495 393
496 v8::HandleScope handle_scope(isolate()); 394 v8::HandleScope handle_scope(isolate());
497 v8::Local<v8::Context> context = MainContext(); 395 v8::Local<v8::Context> context = MainContext();
498 396
499 v8::Local<v8::Object> binding_object = 397 v8::Local<v8::Object> binding_object =
500 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs)); 398 binding()->CreateInstance(context, base::Bind(&AllowAllAPIs));
501 399
400 // Parsing in general is tested in APISignature and ArgumentSpec tests, but
401 // we test that the binding a) correctly finds the definitions, and b) accepts
402 // properties from the API object.
502 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})", 403 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo'})",
503 "[{'prop1':'foo'}]", false); 404 "[{'prop1':'foo'}]", false);
504 ExpectPass(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 2})",
505 "[{'prop1':'foo','prop2':2}]", false);
506 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})", 405 ExpectFailure(binding_object, "obj.takesRefObj({prop1: 'foo', prop2: 'a'})",
507 kError); 406 kError);
508 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false); 407 ExpectPass(binding_object, "obj.takesRefEnum('alpha')", "['alpha']", false);
509 ExpectPass(binding_object, "obj.takesRefEnum('beta')", "['beta']", false);
510 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']", 408 ExpectPass(binding_object, "obj.takesRefEnum(obj.refEnum.BETA)", "['beta']",
511 false); 409 false);
512 ExpectFailure(binding_object, "obj.takesRefEnum('gamma')", kError); 410 ExpectFailure(binding_object, "obj.takesRefEnum('gamma')", kError);
513 } 411 }
514 412
515 TEST_F(APIBindingUnittest, RestrictedAPIs) { 413 TEST_F(APIBindingUnittest, RestrictedAPIs) {
516 const char kFunctions[] = 414 const char kFunctions[] =
517 "[{" 415 "[{"
518 " 'name': 'allowedOne'," 416 " 'name': 'allowedOne',"
519 " 'parameters': []" 417 " 'parameters': []"
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 }; 1145 };
1248 1146
1249 check_supports_filters("unfilteredOne", false); 1147 check_supports_filters("unfilteredOne", false);
1250 check_supports_filters("unfilteredTwo", false); 1148 check_supports_filters("unfilteredTwo", false);
1251 check_supports_filters("unfilteredThree", false); 1149 check_supports_filters("unfilteredThree", false);
1252 check_supports_filters("filteredOne", true); 1150 check_supports_filters("filteredOne", true);
1253 check_supports_filters("filteredTwo", true); 1151 check_supports_filters("filteredTwo", true);
1254 } 1152 }
1255 1153
1256 } // namespace extensions 1154 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698