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/memory/ptr_util.h" | 5 #include "base/memory/ptr_util.h" |
6 #include "base/values.h" | 6 #include "base/values.h" |
7 #include "extensions/renderer/api_binding_test_util.h" | 7 #include "extensions/renderer/api_binding_test_util.h" |
8 #include "extensions/renderer/argument_spec.h" | 8 #include "extensions/renderer/argument_spec.h" |
9 #include "gin/converter.h" | 9 #include "gin/converter.h" |
10 #include "gin/public/isolate_holder.h" | 10 #include "gin/public/isolate_holder.h" |
11 #include "gin/test/v8_test.h" | 11 #include "gin/test/v8_test.h" |
12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
13 #include "v8/include/v8.h" | 13 #include "v8/include/v8.h" |
14 | 14 |
15 namespace extensions { | 15 namespace extensions { |
16 | 16 |
17 class ArgumentSpecUnitTest : public gin::V8Test { | 17 class ArgumentSpecUnitTest : public gin::V8Test { |
18 protected: | 18 protected: |
19 ArgumentSpecUnitTest() {} | 19 ArgumentSpecUnitTest() {} |
20 ~ArgumentSpecUnitTest() override {} | 20 ~ArgumentSpecUnitTest() override {} |
21 void ExpectSuccess(const ArgumentSpec& spec, | 21 void ExpectSuccess(const ArgumentSpec& spec, |
22 const std::string& script_source, | 22 const std::string& script_source, |
23 const std::string& expected_json_single_quotes) { | 23 const std::string& expected_json_single_quotes) { |
24 RunTest(spec, script_source, TestResult::PASS, | 24 RunTest(spec, script_source, true, TestResult::PASS, |
25 ReplaceSingleQuotes(expected_json_single_quotes), std::string()); | 25 ReplaceSingleQuotes(expected_json_single_quotes), std::string()); |
26 } | 26 } |
27 | 27 |
| 28 void ExpectSuccessWithNoConversion(const ArgumentSpec& spec, |
| 29 const std::string& script_source) { |
| 30 RunTest(spec, script_source, false, TestResult::PASS, |
| 31 std::string(), std::string()); |
| 32 } |
| 33 |
28 void ExpectFailure(const ArgumentSpec& spec, | 34 void ExpectFailure(const ArgumentSpec& spec, |
29 const std::string& script_source) { | 35 const std::string& script_source) { |
30 RunTest(spec, script_source, TestResult::FAIL, std::string(), | 36 RunTest(spec, script_source, true, TestResult::FAIL, std::string(), |
| 37 std::string()); |
| 38 } |
| 39 |
| 40 void ExpectFailureWithNoConversion(const ArgumentSpec& spec, |
| 41 const std::string& script_source) { |
| 42 RunTest(spec, script_source, false, TestResult::FAIL, std::string(), |
31 std::string()); | 43 std::string()); |
32 } | 44 } |
33 | 45 |
34 void ExpectThrow(const ArgumentSpec& spec, | 46 void ExpectThrow(const ArgumentSpec& spec, |
35 const std::string& script_source, | 47 const std::string& script_source, |
36 const std::string& expected_thrown_message) { | 48 const std::string& expected_thrown_message) { |
37 RunTest(spec, script_source, TestResult::THROW, std::string(), | 49 RunTest(spec, script_source, true, TestResult::THROW, std::string(), |
38 expected_thrown_message); | 50 expected_thrown_message); |
39 } | 51 } |
40 | 52 |
41 void AddTypeRef(const std::string& id, std::unique_ptr<ArgumentSpec> spec) { | 53 void AddTypeRef(const std::string& id, std::unique_ptr<ArgumentSpec> spec) { |
42 type_refs_[id] = std::move(spec); | 54 type_refs_[id] = std::move(spec); |
43 } | 55 } |
44 | 56 |
45 private: | 57 private: |
46 enum class TestResult { PASS, FAIL, THROW, }; | 58 enum class TestResult { PASS, FAIL, THROW, }; |
47 | 59 |
48 void RunTest(const ArgumentSpec& spec, | 60 void RunTest(const ArgumentSpec& spec, |
49 const std::string& script_source, | 61 const std::string& script_source, |
| 62 bool should_convert, |
50 TestResult expected_result, | 63 TestResult expected_result, |
51 const std::string& expected_json, | 64 const std::string& expected_json, |
52 const std::string& expected_thrown_message); | 65 const std::string& expected_thrown_message); |
53 | 66 |
54 ArgumentSpec::RefMap type_refs_; | 67 ArgumentSpec::RefMap type_refs_; |
55 | 68 |
56 DISALLOW_COPY_AND_ASSIGN(ArgumentSpecUnitTest); | 69 DISALLOW_COPY_AND_ASSIGN(ArgumentSpecUnitTest); |
57 }; | 70 }; |
58 | 71 |
59 void ArgumentSpecUnitTest::RunTest(const ArgumentSpec& spec, | 72 void ArgumentSpecUnitTest::RunTest(const ArgumentSpec& spec, |
60 const std::string& script_source, | 73 const std::string& script_source, |
| 74 bool should_convert, |
61 TestResult expected_result, | 75 TestResult expected_result, |
62 const std::string& expected_json, | 76 const std::string& expected_json, |
63 const std::string& expected_thrown_message) { | 77 const std::string& expected_thrown_message) { |
64 v8::Isolate* isolate = instance_->isolate(); | 78 v8::Isolate* isolate = instance_->isolate(); |
65 v8::HandleScope handle_scope(instance_->isolate()); | 79 v8::HandleScope handle_scope(instance_->isolate()); |
66 | 80 |
67 v8::Local<v8::Context> context = | 81 v8::Local<v8::Context> context = |
68 v8::Local<v8::Context>::New(instance_->isolate(), context_); | 82 v8::Local<v8::Context>::New(instance_->isolate(), context_); |
69 v8::TryCatch try_catch(isolate); | 83 v8::TryCatch try_catch(isolate); |
70 v8::Local<v8::Value> val = V8ValueFromScriptSource(context, script_source); | 84 v8::Local<v8::Value> val = V8ValueFromScriptSource(context, script_source); |
71 ASSERT_FALSE(val.IsEmpty()) << script_source; | 85 ASSERT_FALSE(val.IsEmpty()) << script_source; |
72 | 86 |
73 std::string error; | 87 std::string error; |
74 std::unique_ptr<base::Value> out_value = | 88 std::unique_ptr<base::Value> out_value; |
75 spec.ConvertArgument(context, val, type_refs_, &error); | 89 bool did_succeed = |
| 90 spec.ParseArgument(context, val, type_refs_, |
| 91 should_convert ? &out_value : nullptr, &error); |
76 bool should_succeed = expected_result == TestResult::PASS; | 92 bool should_succeed = expected_result == TestResult::PASS; |
77 ASSERT_EQ(should_succeed, !!out_value) << script_source << ", " << error; | 93 ASSERT_EQ(should_succeed, did_succeed) << script_source << ", " << error; |
| 94 ASSERT_EQ(did_succeed && should_convert, !!out_value); |
78 bool should_throw = expected_result == TestResult::THROW; | 95 bool should_throw = expected_result == TestResult::THROW; |
79 ASSERT_EQ(should_throw, try_catch.HasCaught()) << script_source; | 96 ASSERT_EQ(should_throw, try_catch.HasCaught()) << script_source; |
80 if (should_succeed) { | 97 if (should_succeed && should_convert) { |
81 ASSERT_TRUE(out_value); | 98 ASSERT_TRUE(out_value); |
82 EXPECT_EQ(expected_json, ValueToString(*out_value)); | 99 EXPECT_EQ(expected_json, ValueToString(*out_value)); |
83 } else if (should_throw) { | 100 } else if (should_throw) { |
84 EXPECT_EQ(expected_thrown_message, | 101 EXPECT_EQ(expected_thrown_message, |
85 gin::V8ToString(try_catch.Message()->Get())); | 102 gin::V8ToString(try_catch.Message()->Get())); |
86 } | 103 } |
87 } | 104 } |
88 | 105 |
89 TEST_F(ArgumentSpecUnitTest, Test) { | 106 TEST_F(ArgumentSpecUnitTest, Test) { |
90 { | 107 { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 "x = {prop1: 'foo'};\n" | 227 "x = {prop1: 'foo'};\n" |
211 "Object.defineProperty(\n" | 228 "Object.defineProperty(\n" |
212 " x, 'prop2',\n" | 229 " x, 'prop2',\n" |
213 " { get: () => { throw new Error('Badness'); } });\n" | 230 " { get: () => { throw new Error('Badness'); } });\n" |
214 "x;", | 231 "x;", |
215 "Uncaught Error: Badness"); | 232 "Uncaught Error: Badness"); |
216 } | 233 } |
217 | 234 |
218 { | 235 { |
219 const char kFunctionSpec[] = "{ 'type': 'function' }"; | 236 const char kFunctionSpec[] = "{ 'type': 'function' }"; |
220 // We don't allow conversion of functions (converting to a base::Value is | |
221 // impossible), but we should still be able to parse a function | |
222 // specification. | |
223 ArgumentSpec spec(*ValueFromString(kFunctionSpec)); | 237 ArgumentSpec spec(*ValueFromString(kFunctionSpec)); |
224 EXPECT_EQ(ArgumentType::FUNCTION, spec.type()); | 238 ExpectSuccessWithNoConversion(spec, "(function() {})"); |
| 239 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })"); |
| 240 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })"); |
| 241 ExpectFailureWithNoConversion(spec, "({a: function() {}})"); |
| 242 ExpectFailureWithNoConversion(spec, "([function() {}])"); |
| 243 ExpectFailureWithNoConversion(spec, "1"); |
225 } | 244 } |
226 } | 245 } |
227 | 246 |
228 TEST_F(ArgumentSpecUnitTest, TypeRefsTest) { | 247 TEST_F(ArgumentSpecUnitTest, TypeRefsTest) { |
229 const char kObjectType[] = | 248 const char kObjectType[] = |
230 "{" | 249 "{" |
231 " 'id': 'refObj'," | 250 " 'id': 'refObj'," |
232 " 'type': 'object'," | 251 " 'type': 'object'," |
233 " 'properties': {" | 252 " 'properties': {" |
234 " 'prop1': {'type': 'string'}," | 253 " 'prop1': {'type': 'string'}," |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 ExpectSuccess(spec, "['alpha']", "['alpha']"); | 327 ExpectSuccess(spec, "['alpha']", "['alpha']"); |
309 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']"); | 328 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']"); |
310 ExpectSuccess(spec, "({prop1: 'alpha'})", "{'prop1':'alpha'}"); | 329 ExpectSuccess(spec, "({prop1: 'alpha'})", "{'prop1':'alpha'}"); |
311 ExpectFailure(spec, "({prop1: 1})"); | 330 ExpectFailure(spec, "({prop1: 1})"); |
312 ExpectFailure(spec, "'alpha'"); | 331 ExpectFailure(spec, "'alpha'"); |
313 ExpectFailure(spec, "42"); | 332 ExpectFailure(spec, "42"); |
314 } | 333 } |
315 } | 334 } |
316 | 335 |
317 } // namespace extensions | 336 } // namespace extensions |
OLD | NEW |