| 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 |