| 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 "gin/converter.h" | 14 #include "gin/converter.h" |
| 14 | 15 |
| 15 namespace extensions { | 16 namespace extensions { |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 using SpecVector = std::vector<std::unique_ptr<ArgumentSpec>>; | 19 using SpecVector = std::vector<std::unique_ptr<ArgumentSpec>>; |
| 19 | 20 |
| 20 std::unique_ptr<APISignature> OneString() { | 21 std::unique_ptr<APISignature> OneString() { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 | 168 |
| 168 auto ref_enum_spec = base::MakeUnique<ArgumentSpec>(ArgumentType::STRING); | 169 auto ref_enum_spec = base::MakeUnique<ArgumentSpec>(ArgumentType::STRING); |
| 169 ref_enum_spec->set_enum_values({"alpha", "beta"}); | 170 ref_enum_spec->set_enum_values({"alpha", "beta"}); |
| 170 type_refs_.AddSpec("refEnum", std::move(ref_enum_spec)); | 171 type_refs_.AddSpec("refEnum", std::move(ref_enum_spec)); |
| 171 } | 172 } |
| 172 | 173 |
| 173 void ExpectPass(const APISignature& signature, | 174 void ExpectPass(const APISignature& signature, |
| 174 base::StringPiece arg_values, | 175 base::StringPiece arg_values, |
| 175 base::StringPiece expected_parsed_args, | 176 base::StringPiece expected_parsed_args, |
| 176 bool expect_callback) { | 177 bool expect_callback) { |
| 177 RunTest(signature, arg_values, expected_parsed_args, expect_callback, true); | 178 RunTest(signature, arg_values, expected_parsed_args, expect_callback, true, |
| 179 std::string()); |
| 178 } | 180 } |
| 179 | 181 |
| 180 void ExpectFailure(const APISignature& signature, | 182 void ExpectFailure(const APISignature& signature, |
| 181 base::StringPiece arg_values) { | 183 base::StringPiece arg_values, |
| 182 RunTest(signature, arg_values, base::StringPiece(), false, false); | 184 const std::string& expected_error) { |
| 185 RunTest(signature, arg_values, base::StringPiece(), false, false, |
| 186 expected_error); |
| 183 } | 187 } |
| 184 | 188 |
| 185 private: | 189 private: |
| 186 void RunTest(const APISignature& signature, | 190 void RunTest(const APISignature& signature, |
| 187 base::StringPiece arg_values, | 191 base::StringPiece arg_values, |
| 188 base::StringPiece expected_parsed_args, | 192 base::StringPiece expected_parsed_args, |
| 189 bool expect_callback, | 193 bool expect_callback, |
| 190 bool should_succeed) { | 194 bool should_succeed, |
| 195 const std::string& expected_error) { |
| 191 SCOPED_TRACE(arg_values); | 196 SCOPED_TRACE(arg_values); |
| 192 v8::Local<v8::Context> context = MainContext(); | 197 v8::Local<v8::Context> context = MainContext(); |
| 193 v8::Local<v8::Value> v8_args = V8ValueFromScriptSource(context, arg_values); | 198 v8::Local<v8::Value> v8_args = V8ValueFromScriptSource(context, arg_values); |
| 194 ASSERT_FALSE(v8_args.IsEmpty()); | 199 ASSERT_FALSE(v8_args.IsEmpty()); |
| 195 ASSERT_TRUE(v8_args->IsArray()); | 200 ASSERT_TRUE(v8_args->IsArray()); |
| 196 std::vector<v8::Local<v8::Value>> vector_args; | 201 std::vector<v8::Local<v8::Value>> vector_args; |
| 197 ASSERT_TRUE(gin::ConvertFromV8(isolate(), v8_args, &vector_args)); | 202 ASSERT_TRUE(gin::ConvertFromV8(isolate(), v8_args, &vector_args)); |
| 198 | 203 |
| 199 std::unique_ptr<base::ListValue> result; | 204 std::unique_ptr<base::ListValue> result; |
| 200 v8::Local<v8::Function> callback; | 205 v8::Local<v8::Function> callback; |
| 201 std::string error; | 206 std::string error; |
| 202 bool success = signature.ParseArgumentsToJSON( | 207 bool success = signature.ParseArgumentsToJSON( |
| 203 context, vector_args, type_refs_, &result, &callback, &error); | 208 context, vector_args, type_refs_, &result, &callback, &error); |
| 204 EXPECT_EQ(should_succeed, success); | 209 EXPECT_EQ(should_succeed, success); |
| 205 ASSERT_EQ(should_succeed, !!result); | 210 ASSERT_EQ(should_succeed, !!result); |
| 206 EXPECT_EQ(expect_callback, !callback.IsEmpty()); | 211 EXPECT_EQ(expect_callback, !callback.IsEmpty()); |
| 207 if (should_succeed) { | 212 if (should_succeed) { |
| 208 EXPECT_EQ(ReplaceSingleQuotes(expected_parsed_args), | 213 EXPECT_EQ(ReplaceSingleQuotes(expected_parsed_args), |
| 209 ValueToString(*result)); | 214 ValueToString(*result)); |
| 215 } else { |
| 216 EXPECT_EQ(expected_error, error); |
| 210 } | 217 } |
| 211 } | 218 } |
| 212 | 219 |
| 213 APITypeReferenceMap type_refs_; | 220 APITypeReferenceMap type_refs_; |
| 214 | 221 |
| 215 DISALLOW_COPY_AND_ASSIGN(APISignatureTest); | 222 DISALLOW_COPY_AND_ASSIGN(APISignatureTest); |
| 216 }; | 223 }; |
| 217 | 224 |
| 218 TEST_F(APISignatureTest, Foo) { | 225 TEST_F(APISignatureTest, Foo) { |
| 226 using namespace api_errors; |
| 227 |
| 219 v8::HandleScope handle_scope(isolate()); | 228 v8::HandleScope handle_scope(isolate()); |
| 220 | 229 |
| 221 { | 230 { |
| 222 auto signature = OneString(); | 231 auto signature = OneString(); |
| 223 ExpectPass(*signature, "['foo']", "['foo']", false); | 232 ExpectPass(*signature, "['foo']", "['foo']", false); |
| 224 ExpectPass(*signature, "['']", "['']", false); | 233 ExpectPass(*signature, "['']", "['']", false); |
| 225 ExpectFailure(*signature, "[1]"); | 234 ExpectFailure( |
| 226 ExpectFailure(*signature, "[]"); | 235 *signature, "[1]", |
| 227 ExpectFailure(*signature, "[{}]"); | 236 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
| 228 ExpectFailure(*signature, "['foo', 'bar']"); | 237 ExpectFailure(*signature, "[]", MissingRequiredArgument("string")); |
| 238 ExpectFailure( |
| 239 *signature, "[{}]", |
| 240 ArgumentError("string", InvalidType(kTypeString, kTypeObject))); |
| 241 ExpectFailure(*signature, "['foo', 'bar']", TooManyArguments()); |
| 229 } | 242 } |
| 230 | 243 |
| 231 { | 244 { |
| 232 auto signature = StringAndInt(); | 245 auto signature = StringAndInt(); |
| 233 ExpectPass(*signature, "['foo', 42]", "['foo',42]", false); | 246 ExpectPass(*signature, "['foo', 42]", "['foo',42]", false); |
| 234 ExpectPass(*signature, "['foo', -1]", "['foo',-1]", false); | 247 ExpectPass(*signature, "['foo', -1]", "['foo',-1]", false); |
| 235 ExpectFailure(*signature, "[1]"); | 248 ExpectFailure( |
| 236 ExpectFailure(*signature, "['foo'];"); | 249 *signature, "[1]", |
| 237 ExpectFailure(*signature, "[1, 'foo']"); | 250 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
| 238 ExpectFailure(*signature, "['foo', 'foo']"); | 251 ExpectFailure(*signature, "['foo'];", MissingRequiredArgument("int")); |
| 239 ExpectFailure(*signature, "['foo', '1']"); | 252 ExpectFailure( |
| 240 ExpectFailure(*signature, "['foo', 2.3]"); | 253 *signature, "[1, 'foo']", |
| 254 ArgumentError("string", InvalidType(kTypeString, kTypeInteger))); |
| 255 ExpectFailure(*signature, "['foo', 'foo']", |
| 256 ArgumentError("int", InvalidType(kTypeInteger, kTypeString))); |
| 257 ExpectFailure(*signature, "['foo', '1']", |
| 258 ArgumentError("int", InvalidType(kTypeInteger, kTypeString))); |
| 259 ExpectFailure(*signature, "['foo', 2.3]", |
| 260 ArgumentError("int", InvalidType(kTypeInteger, kTypeDouble))); |
| 241 } | 261 } |
| 242 | 262 |
| 243 { | 263 { |
| 244 auto signature = StringOptionalIntAndBool(); | 264 auto signature = StringOptionalIntAndBool(); |
| 245 ExpectPass(*signature, "['foo', 42, true]", "['foo',42,true]", false); | 265 ExpectPass(*signature, "['foo', 42, true]", "['foo',42,true]", false); |
| 246 ExpectPass(*signature, "['foo', true]", "['foo',null,true]", false); | 266 ExpectPass(*signature, "['foo', true]", "['foo',null,true]", false); |
| 247 ExpectFailure(*signature, "['foo', 'bar', true]"); | 267 ExpectFailure( |
| 268 *signature, "['foo', 'bar', true]", |
| 269 ArgumentError("bool", InvalidType(kTypeBoolean, kTypeString))); |
| 248 } | 270 } |
| 249 | 271 |
| 250 { | 272 { |
| 251 auto signature = OneObject(); | 273 auto signature = OneObject(); |
| 252 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); | 274 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); |
| 253 ExpectFailure(*signature, | 275 ExpectFailure(*signature, |
| 254 "[{ get prop1() { throw new Error('Badness'); } }]"); | 276 "[{ get prop1() { throw new Error('Badness'); } }]", |
| 277 ArgumentError("obj", ScriptThrewError())); |
| 255 } | 278 } |
| 256 | 279 |
| 257 { | 280 { |
| 258 auto signature = NoArgs(); | 281 auto signature = NoArgs(); |
| 259 ExpectPass(*signature, "[]", "[]", false); | 282 ExpectPass(*signature, "[]", "[]", false); |
| 260 ExpectFailure(*signature, "[0]"); | 283 ExpectFailure(*signature, "[0]", TooManyArguments()); |
| 261 ExpectFailure(*signature, "['']"); | 284 ExpectFailure(*signature, "['']", TooManyArguments()); |
| 262 ExpectFailure(*signature, "[null]"); | 285 ExpectFailure(*signature, "[null]", TooManyArguments()); |
| 263 ExpectFailure(*signature, "[undefined]"); | 286 ExpectFailure(*signature, "[undefined]", TooManyArguments()); |
| 264 } | 287 } |
| 265 | 288 |
| 266 { | 289 { |
| 267 auto signature = IntAndCallback(); | 290 auto signature = IntAndCallback(); |
| 268 ExpectPass(*signature, "[1, function() {}]", "[1]", true); | 291 ExpectPass(*signature, "[1, function() {}]", "[1]", true); |
| 269 ExpectFailure(*signature, "[function() {}]"); | 292 ExpectFailure( |
| 270 ExpectFailure(*signature, "[1]"); | 293 *signature, "[function() {}]", |
| 294 ArgumentError("int", InvalidType(kTypeInteger, kTypeFunction))); |
| 295 ExpectFailure(*signature, "[1]", MissingRequiredArgument("callback")); |
| 271 } | 296 } |
| 272 | 297 |
| 273 { | 298 { |
| 274 auto signature = OptionalIntAndCallback(); | 299 auto signature = OptionalIntAndCallback(); |
| 275 ExpectPass(*signature, "[1, function() {}]", "[1]", true); | 300 ExpectPass(*signature, "[1, function() {}]", "[1]", true); |
| 276 ExpectPass(*signature, "[function() {}]", "[null]", true); | 301 ExpectPass(*signature, "[function() {}]", "[null]", true); |
| 277 ExpectFailure(*signature, "[1]"); | 302 ExpectFailure(*signature, "[1]", MissingRequiredArgument("callback")); |
| 278 } | 303 } |
| 279 | 304 |
| 280 { | 305 { |
| 281 auto signature = OptionalCallback(); | 306 auto signature = OptionalCallback(); |
| 282 ExpectPass(*signature, "[function() {}]", "[]", true); | 307 ExpectPass(*signature, "[function() {}]", "[]", true); |
| 283 ExpectPass(*signature, "[]", "[]", false); | 308 ExpectPass(*signature, "[]", "[]", false); |
| 284 ExpectPass(*signature, "[undefined]", "[]", false); | 309 ExpectPass(*signature, "[undefined]", "[]", false); |
| 285 ExpectFailure(*signature, "[0]"); | 310 ExpectFailure( |
| 311 *signature, "[0]", |
| 312 ArgumentError("callback", InvalidType(kTypeFunction, kTypeInteger))); |
| 286 } | 313 } |
| 287 | 314 |
| 288 { | 315 { |
| 289 auto signature = IntAnyOptionalObjectOptionalCallback(); | 316 auto signature = IntAnyOptionalObjectOptionalCallback(); |
| 290 ExpectPass(*signature, "[4, {foo: 'bar'}, function() {}]", | 317 ExpectPass(*signature, "[4, {foo: 'bar'}, function() {}]", |
| 291 "[4,{'foo':'bar'},null]", true); | 318 "[4,{'foo':'bar'},null]", true); |
| 292 ExpectPass(*signature, "[4, {foo: 'bar'}]", "[4,{'foo':'bar'},null]", | 319 ExpectPass(*signature, "[4, {foo: 'bar'}]", "[4,{'foo':'bar'},null]", |
| 293 false); | 320 false); |
| 294 ExpectPass(*signature, "[4, {foo: 'bar'}, {}]", "[4,{'foo':'bar'},{}]", | 321 ExpectPass(*signature, "[4, {foo: 'bar'}, {}]", "[4,{'foo':'bar'},{}]", |
| 295 false); | 322 false); |
| 296 ExpectFailure(*signature, "[4, function() {}]"); | 323 ExpectFailure(*signature, "[4, function() {}]", |
| 297 ExpectFailure(*signature, "[4]"); | 324 ArgumentError("any", UnserializableValue())); |
| 325 ExpectFailure(*signature, "[4]", MissingRequiredArgument("any")); |
| 298 } | 326 } |
| 299 } | 327 } |
| 300 | 328 |
| 301 TEST_F(APISignatureTest, TypeRefsTest) { | 329 TEST_F(APISignatureTest, TypeRefsTest) { |
| 330 using namespace api_errors; |
| 331 |
| 302 v8::HandleScope handle_scope(isolate()); | 332 v8::HandleScope handle_scope(isolate()); |
| 303 | 333 |
| 304 { | 334 { |
| 305 auto signature = RefObj(); | 335 auto signature = RefObj(); |
| 306 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); | 336 ExpectPass(*signature, "[{prop1: 'foo'}]", "[{'prop1':'foo'}]", false); |
| 307 ExpectPass(*signature, "[{prop1: 'foo', prop2: 2}]", | 337 ExpectPass(*signature, "[{prop1: 'foo', prop2: 2}]", |
| 308 "[{'prop1':'foo','prop2':2}]", false); | 338 "[{'prop1':'foo','prop2':2}]", false); |
| 309 ExpectFailure(*signature, "[{prop1: 'foo', prop2: 'a'}]"); | 339 ExpectFailure( |
| 340 *signature, "[{prop1: 'foo', prop2: 'a'}]", |
| 341 ArgumentError("obj", PropertyError("prop2", InvalidType(kTypeInteger, |
| 342 kTypeString)))); |
| 310 } | 343 } |
| 311 | 344 |
| 312 { | 345 { |
| 313 auto signature = RefEnum(); | 346 auto signature = RefEnum(); |
| 314 ExpectPass(*signature, "['alpha']", "['alpha']", false); | 347 ExpectPass(*signature, "['alpha']", "['alpha']", false); |
| 315 ExpectPass(*signature, "['beta']", "['beta']", false); | 348 ExpectPass(*signature, "['beta']", "['beta']", false); |
| 316 ExpectFailure(*signature, "['gamma']"); | 349 ExpectFailure(*signature, "['gamma']", |
| 350 ArgumentError("enum", InvalidEnumValue({"alpha", "beta"}))); |
| 317 } | 351 } |
| 318 } | 352 } |
| 319 | 353 |
| 320 } // namespace extensions | 354 } // namespace extensions |
| OLD | NEW |