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

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

Issue 2837023003: [Extensions Bindings] Add argument parsing errors (Closed)
Patch Set: rebase 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 "extensions/renderer/argument_spec.h"
5 #include "base/memory/ptr_util.h" 6 #include "base/memory/ptr_util.h"
6 #include "base/values.h" 7 #include "base/values.h"
7 #include "extensions/renderer/api_binding_test_util.h" 8 #include "extensions/renderer/api_binding_test_util.h"
9 #include "extensions/renderer/api_invocation_errors.h"
8 #include "extensions/renderer/api_type_reference_map.h" 10 #include "extensions/renderer/api_type_reference_map.h"
9 #include "extensions/renderer/argument_spec.h"
10 #include "gin/converter.h" 11 #include "gin/converter.h"
11 #include "gin/public/isolate_holder.h" 12 #include "gin/public/isolate_holder.h"
12 #include "gin/test/v8_test.h" 13 #include "gin/test/v8_test.h"
13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/gtest/include/gtest/gtest.h"
14 #include "v8/include/v8.h" 15 #include "v8/include/v8.h"
15 16
16 namespace extensions { 17 namespace extensions {
17 18
18 class ArgumentSpecUnitTest : public gin::V8Test { 19 class ArgumentSpecUnitTest : public gin::V8Test {
19 protected: 20 protected:
20 ArgumentSpecUnitTest() 21 ArgumentSpecUnitTest()
21 : type_refs_(APITypeReferenceMap::InitializeTypeCallback()) {} 22 : type_refs_(APITypeReferenceMap::InitializeTypeCallback()) {}
22 ~ArgumentSpecUnitTest() override {} 23 ~ArgumentSpecUnitTest() override {}
24
25 enum class TestResult {
26 PASS,
27 FAIL,
28 THROW,
29 };
30
31 struct RunTestParams {
32 RunTestParams(const ArgumentSpec& spec,
33 base::StringPiece script_source,
34 TestResult result)
35 : spec(spec), script_source(script_source), expected_result(result) {}
36
37 const ArgumentSpec& spec;
38 base::StringPiece script_source;
39 TestResult expected_result;
40 base::StringPiece expected_json;
41 base::StringPiece expected_error;
42 base::StringPiece expected_thrown_message;
43 const base::Value* expected_value = nullptr;
44 bool should_convert = true;
45 };
46
23 void ExpectSuccess(const ArgumentSpec& spec, 47 void ExpectSuccess(const ArgumentSpec& spec,
24 const std::string& script_source, 48 const std::string& script_source,
25 const std::string& expected_json_single_quotes) { 49 const std::string& expected_json_single_quotes) {
26 RunTest(spec, script_source, true, TestResult::PASS, 50 RunTestParams params(spec, script_source, TestResult::PASS);
27 ReplaceSingleQuotes(expected_json_single_quotes), nullptr, 51 std::string expected_json =
28 std::string()); 52 ReplaceSingleQuotes(expected_json_single_quotes);
53 params.expected_json = expected_json;
54 RunTest(params);
29 } 55 }
30 56
31 void ExpectSuccess(const ArgumentSpec& spec, 57 void ExpectSuccess(const ArgumentSpec& spec,
32 const std::string& script_source, 58 const std::string& script_source,
33 const base::Value& expected_value) { 59 const base::Value& expected_value) {
34 RunTest(spec, script_source, true, TestResult::PASS, std::string(), 60 RunTestParams params(spec, script_source, TestResult::PASS);
35 &expected_value, std::string()); 61 params.expected_value = &expected_value;
62 RunTest(params);
36 } 63 }
37 64
38 void ExpectSuccessWithNoConversion(const ArgumentSpec& spec, 65 void ExpectSuccessWithNoConversion(const ArgumentSpec& spec,
39 const std::string& script_source) { 66 const std::string& script_source) {
40 RunTest(spec, script_source, false, TestResult::PASS, std::string(), 67 RunTestParams params(spec, script_source, TestResult::PASS);
41 nullptr, std::string()); 68 params.should_convert = false;
69 RunTest(params);
42 } 70 }
43 71
44 void ExpectFailure(const ArgumentSpec& spec, 72 void ExpectFailure(const ArgumentSpec& spec,
45 const std::string& script_source) { 73 const std::string& script_source,
46 RunTest(spec, script_source, true, TestResult::FAIL, std::string(), nullptr, 74 const std::string& expected_error) {
47 std::string()); 75 RunTestParams params(spec, script_source, TestResult::FAIL);
76 params.expected_error = expected_error;
77 RunTest(params);
48 } 78 }
49 79
50 void ExpectFailureWithNoConversion(const ArgumentSpec& spec, 80 void ExpectFailureWithNoConversion(const ArgumentSpec& spec,
51 const std::string& script_source) { 81 const std::string& script_source,
52 RunTest(spec, script_source, false, TestResult::FAIL, std::string(), 82 const std::string& expected_error) {
53 nullptr, std::string()); 83 RunTestParams params(spec, script_source, TestResult::FAIL);
84 params.should_convert = false;
85 params.expected_error = expected_error;
86 RunTest(params);
54 } 87 }
55 88
56 void ExpectThrow(const ArgumentSpec& spec, 89 void ExpectThrow(const ArgumentSpec& spec,
57 const std::string& script_source, 90 const std::string& script_source,
58 const std::string& expected_thrown_message) { 91 const std::string& expected_thrown_message) {
59 RunTest(spec, script_source, true, TestResult::THROW, std::string(), 92 RunTestParams params(spec, script_source, TestResult::THROW);
60 nullptr, expected_thrown_message); 93 params.expected_thrown_message = expected_thrown_message;
94 RunTest(params);
61 } 95 }
62 96
63 void AddTypeRef(const std::string& id, std::unique_ptr<ArgumentSpec> spec) { 97 void AddTypeRef(const std::string& id, std::unique_ptr<ArgumentSpec> spec) {
64 type_refs_.AddSpec(id, std::move(spec)); 98 type_refs_.AddSpec(id, std::move(spec));
65 } 99 }
66 100
67 private: 101 private:
68 enum class TestResult { PASS, FAIL, THROW, }; 102 void RunTest(const RunTestParams& params);
69
70 void RunTest(const ArgumentSpec& spec,
71 const std::string& script_source,
72 bool should_convert,
73 TestResult expected_result,
74 const std::string& expected_json,
75 const base::Value* expected_value,
76 const std::string& expected_thrown_message);
77 103
78 APITypeReferenceMap type_refs_; 104 APITypeReferenceMap type_refs_;
79 105
80 DISALLOW_COPY_AND_ASSIGN(ArgumentSpecUnitTest); 106 DISALLOW_COPY_AND_ASSIGN(ArgumentSpecUnitTest);
81 }; 107 };
82 108
83 void ArgumentSpecUnitTest::RunTest(const ArgumentSpec& spec, 109 void ArgumentSpecUnitTest::RunTest(const RunTestParams& params) {
84 const std::string& script_source,
85 bool should_convert,
86 TestResult expected_result,
87 const std::string& expected_json,
88 const base::Value* expected_value,
89 const std::string& expected_thrown_message) {
90 v8::Isolate* isolate = instance_->isolate(); 110 v8::Isolate* isolate = instance_->isolate();
91 v8::HandleScope handle_scope(instance_->isolate()); 111 v8::HandleScope handle_scope(instance_->isolate());
92 112
93 v8::Local<v8::Context> context = 113 v8::Local<v8::Context> context =
94 v8::Local<v8::Context>::New(instance_->isolate(), context_); 114 v8::Local<v8::Context>::New(instance_->isolate(), context_);
95 v8::TryCatch try_catch(isolate); 115 v8::TryCatch try_catch(isolate);
96 v8::Local<v8::Value> val = V8ValueFromScriptSource(context, script_source); 116 v8::Local<v8::Value> val =
97 ASSERT_FALSE(val.IsEmpty()) << script_source; 117 V8ValueFromScriptSource(context, params.script_source);
118 ASSERT_FALSE(val.IsEmpty()) << params.script_source;
98 119
99 std::string error; 120 std::string error;
100 std::unique_ptr<base::Value> out_value; 121 std::unique_ptr<base::Value> out_value;
101 bool did_succeed = 122 bool did_succeed = params.spec.ParseArgument(
102 spec.ParseArgument(context, val, type_refs_, 123 context, val, type_refs_, params.should_convert ? &out_value : nullptr,
103 should_convert ? &out_value : nullptr, &error); 124 &error);
104 bool should_succeed = expected_result == TestResult::PASS; 125 bool should_succeed = params.expected_result == TestResult::PASS;
105 ASSERT_EQ(should_succeed, did_succeed) << script_source << ", " << error; 126 ASSERT_EQ(should_succeed, did_succeed)
106 ASSERT_EQ(did_succeed && should_convert, !!out_value); 127 << params.script_source << ", " << error;
107 bool should_throw = expected_result == TestResult::THROW; 128 ASSERT_EQ(did_succeed && params.should_convert, !!out_value);
108 ASSERT_EQ(should_throw, try_catch.HasCaught()) << script_source; 129 bool should_throw = params.expected_result == TestResult::THROW;
109 if (should_succeed && should_convert) { 130 ASSERT_EQ(should_throw, try_catch.HasCaught()) << params.script_source;
131
132 if (!params.expected_error.empty())
133 EXPECT_EQ(params.expected_error, error) << params.script_source;
134
135 if (should_succeed && params.should_convert) {
110 ASSERT_TRUE(out_value); 136 ASSERT_TRUE(out_value);
111 if (expected_value) 137 if (params.expected_value)
112 EXPECT_TRUE(expected_value->Equals(out_value.get())) << script_source; 138 EXPECT_TRUE(params.expected_value->Equals(out_value.get()))
139 << params.script_source;
113 else 140 else
114 EXPECT_EQ(expected_json, ValueToString(*out_value)); 141 EXPECT_EQ(params.expected_json, ValueToString(*out_value));
115 } else if (should_throw) { 142 } else if (should_throw) {
116 EXPECT_EQ(expected_thrown_message, 143 EXPECT_EQ(params.expected_thrown_message,
117 gin::V8ToString(try_catch.Message()->Get())); 144 gin::V8ToString(try_catch.Message()->Get()));
118 } 145 }
119 } 146 }
120 147
121 TEST_F(ArgumentSpecUnitTest, Test) { 148 TEST_F(ArgumentSpecUnitTest, Test) {
149 using namespace api_errors;
150
151 // Shorthand for getting an invalid type error.
152 auto invalid_type = [](const char* expected, const char* actual) {
153 return GetError(kInvalidType, expected, actual);
154 };
155
122 { 156 {
123 ArgumentSpec spec(*ValueFromString("{'type': 'integer'}")); 157 ArgumentSpec spec(*ValueFromString("{'type': 'integer'}"));
124 ExpectSuccess(spec, "1", "1"); 158 ExpectSuccess(spec, "1", "1");
125 ExpectSuccess(spec, "-1", "-1"); 159 ExpectSuccess(spec, "-1", "-1");
126 ExpectSuccess(spec, "0", "0"); 160 ExpectSuccess(spec, "0", "0");
127 ExpectSuccess(spec, "0.0", "0"); 161 ExpectSuccess(spec, "0.0", "0");
128 ExpectFailure(spec, "undefined"); 162 ExpectFailure(spec, "undefined",
129 ExpectFailure(spec, "null"); 163 invalid_type(kTypeInteger, kTypeUndefined));
130 ExpectFailure(spec, "1.1"); 164 ExpectFailure(spec, "null", invalid_type(kTypeInteger, kTypeNull));
131 ExpectFailure(spec, "'foo'"); 165 ExpectFailure(spec, "1.1", invalid_type(kTypeInteger, kTypeDouble));
132 ExpectFailure(spec, "'1'"); 166 ExpectFailure(spec, "'foo'", invalid_type(kTypeInteger, kTypeString));
133 ExpectFailure(spec, "{}"); 167 ExpectFailure(spec, "'1'", invalid_type(kTypeInteger, kTypeString));
134 ExpectFailure(spec, "[1]"); 168 ExpectFailure(spec, "({})", invalid_type(kTypeInteger, kTypeObject));
169 ExpectFailure(spec, "[1]", invalid_type(kTypeInteger, kTypeList));
135 } 170 }
136 171
137 { 172 {
138 ArgumentSpec spec(*ValueFromString("{'type': 'number'}")); 173 ArgumentSpec spec(*ValueFromString("{'type': 'number'}"));
139 ExpectSuccess(spec, "1", "1.0"); 174 ExpectSuccess(spec, "1", "1.0");
140 ExpectSuccess(spec, "-1", "-1.0"); 175 ExpectSuccess(spec, "-1", "-1.0");
141 ExpectSuccess(spec, "0", "0.0"); 176 ExpectSuccess(spec, "0", "0.0");
142 ExpectSuccess(spec, "1.1", "1.1"); 177 ExpectSuccess(spec, "1.1", "1.1");
143 ExpectSuccess(spec, "1.", "1.0"); 178 ExpectSuccess(spec, "1.", "1.0");
144 ExpectSuccess(spec, ".1", "0.1"); 179 ExpectSuccess(spec, ".1", "0.1");
145 ExpectFailure(spec, "undefined"); 180 ExpectFailure(spec, "undefined", invalid_type(kTypeDouble, kTypeUndefined));
146 ExpectFailure(spec, "null"); 181 ExpectFailure(spec, "null", invalid_type(kTypeDouble, kTypeNull));
147 ExpectFailure(spec, "'foo'"); 182 ExpectFailure(spec, "'foo'", invalid_type(kTypeDouble, kTypeString));
148 ExpectFailure(spec, "'1.1'"); 183 ExpectFailure(spec, "'1.1'", invalid_type(kTypeDouble, kTypeString));
149 ExpectFailure(spec, "{}"); 184 ExpectFailure(spec, "({})", invalid_type(kTypeDouble, kTypeObject));
150 ExpectFailure(spec, "[1.1]"); 185 ExpectFailure(spec, "[1.1]", invalid_type(kTypeDouble, kTypeList));
151 } 186 }
152 187
153 { 188 {
154 ArgumentSpec spec(*ValueFromString("{'type': 'integer', 'minimum': 1}")); 189 ArgumentSpec spec(*ValueFromString("{'type': 'integer', 'minimum': 1}"));
155 ExpectSuccess(spec, "2", "2"); 190 ExpectSuccess(spec, "2", "2");
156 ExpectSuccess(spec, "1", "1"); 191 ExpectSuccess(spec, "1", "1");
157 ExpectFailure(spec, "0"); 192 ExpectFailure(spec, "0", GetError(kNumberTooSmall, 1));
158 ExpectFailure(spec, "-1"); 193 ExpectFailure(spec, "-1", GetError(kNumberTooSmall, 1));
159 } 194 }
160 195
161 { 196 {
162 ArgumentSpec spec(*ValueFromString("{'type': 'integer', 'maximum': 10}")); 197 ArgumentSpec spec(*ValueFromString("{'type': 'integer', 'maximum': 10}"));
163 ExpectSuccess(spec, "10", "10"); 198 ExpectSuccess(spec, "10", "10");
164 ExpectSuccess(spec, "1", "1"); 199 ExpectSuccess(spec, "1", "1");
165 ExpectFailure(spec, "11"); 200 ExpectFailure(spec, "11", GetError(kNumberTooLarge, 10));
166 } 201 }
167 202
168 { 203 {
169 ArgumentSpec spec(*ValueFromString("{'type': 'string'}")); 204 ArgumentSpec spec(*ValueFromString("{'type': 'string'}"));
170 ExpectSuccess(spec, "'foo'", "'foo'"); 205 ExpectSuccess(spec, "'foo'", "'foo'");
171 ExpectSuccess(spec, "''", "''"); 206 ExpectSuccess(spec, "''", "''");
172 ExpectFailure(spec, "1"); 207 ExpectFailure(spec, "1", invalid_type(kTypeString, kTypeInteger));
173 ExpectFailure(spec, "{}"); 208 ExpectFailure(spec, "({})", invalid_type(kTypeString, kTypeObject));
174 ExpectFailure(spec, "['foo']"); 209 ExpectFailure(spec, "['foo']", invalid_type(kTypeString, kTypeList));
175 } 210 }
176 211
177 { 212 {
178 ArgumentSpec spec( 213 ArgumentSpec spec(
179 *ValueFromString("{'type': 'string', 'enum': ['foo', 'bar']}")); 214 *ValueFromString("{'type': 'string', 'enum': ['foo', 'bar']}"));
180 ExpectSuccess(spec, "'foo'", "'foo'"); 215 ExpectSuccess(spec, "'foo'", "'foo'");
181 ExpectSuccess(spec, "'bar'", "'bar'"); 216 ExpectSuccess(spec, "'bar'", "'bar'");
182 ExpectFailure(spec, "['foo']"); 217 ExpectFailure(spec, "['foo']", invalid_type(kTypeString, kTypeList));
183 ExpectFailure(spec, "'fo'"); 218 ExpectFailure(spec, "'fo'", GetError(kInvalidEnumValue, "bar, foo"));
184 ExpectFailure(spec, "'foobar'"); 219 ExpectFailure(spec, "'foobar'", GetError(kInvalidEnumValue, "bar, foo"));
185 ExpectFailure(spec, "'baz'"); 220 ExpectFailure(spec, "'baz'", GetError(kInvalidEnumValue, "bar, foo"));
186 ExpectFailure(spec, "''"); 221 ExpectFailure(spec, "''", GetError(kInvalidEnumValue, "bar, foo"));
187 } 222 }
188 223
189 { 224 {
190 ArgumentSpec spec(*ValueFromString( 225 ArgumentSpec spec(*ValueFromString(
191 "{'type': 'string', 'enum': [{'name': 'foo'}, {'name': 'bar'}]}")); 226 "{'type': 'string', 'enum': [{'name': 'foo'}, {'name': 'bar'}]}"));
192 ExpectSuccess(spec, "'foo'", "'foo'"); 227 ExpectSuccess(spec, "'foo'", "'foo'");
193 ExpectSuccess(spec, "'bar'", "'bar'"); 228 ExpectSuccess(spec, "'bar'", "'bar'");
194 ExpectFailure(spec, "['foo']"); 229 ExpectFailure(spec, "['foo']", invalid_type(kTypeString, kTypeList));
195 ExpectFailure(spec, "'fo'"); 230 ExpectFailure(spec, "'fo'", GetError(kInvalidEnumValue, "bar, foo"));
196 ExpectFailure(spec, "'foobar'"); 231 ExpectFailure(spec, "'foobar'", GetError(kInvalidEnumValue, "bar, foo"));
197 ExpectFailure(spec, "'baz'"); 232 ExpectFailure(spec, "'baz'", GetError(kInvalidEnumValue, "bar, foo"));
198 ExpectFailure(spec, "''"); 233 ExpectFailure(spec, "''", GetError(kInvalidEnumValue, "bar, foo"));
199 } 234 }
200 235
201 { 236 {
202 ArgumentSpec spec(*ValueFromString("{'type': 'boolean'}")); 237 ArgumentSpec spec(*ValueFromString("{'type': 'boolean'}"));
203 ExpectSuccess(spec, "true", "true"); 238 ExpectSuccess(spec, "true", "true");
204 ExpectSuccess(spec, "false", "false"); 239 ExpectSuccess(spec, "false", "false");
205 ExpectFailure(spec, "1"); 240 ExpectFailure(spec, "1", invalid_type(kTypeBoolean, kTypeInteger));
206 ExpectFailure(spec, "'true'"); 241 ExpectFailure(spec, "'true'", invalid_type(kTypeBoolean, kTypeString));
207 ExpectFailure(spec, "null"); 242 ExpectFailure(spec, "null", invalid_type(kTypeBoolean, kTypeNull));
208 } 243 }
209 244
210 { 245 {
211 ArgumentSpec spec( 246 ArgumentSpec spec(
212 *ValueFromString("{'type': 'array', 'items': {'type': 'string'}}")); 247 *ValueFromString("{'type': 'array', 'items': {'type': 'string'}}"));
213 ExpectSuccess(spec, "[]", "[]"); 248 ExpectSuccess(spec, "[]", "[]");
214 ExpectSuccess(spec, "['foo']", "['foo']"); 249 ExpectSuccess(spec, "['foo']", "['foo']");
215 ExpectSuccess(spec, "['foo', 'bar']", "['foo','bar']"); 250 ExpectSuccess(spec, "['foo', 'bar']", "['foo','bar']");
216 ExpectSuccess(spec, "var x = new Array(); x[0] = 'foo'; x;", "['foo']"); 251 ExpectSuccess(spec, "var x = new Array(); x[0] = 'foo'; x;", "['foo']");
217 ExpectFailure(spec, "'foo'"); 252 ExpectFailure(spec, "'foo'", invalid_type(kTypeList, kTypeString));
218 ExpectFailure(spec, "[1, 2]"); 253 ExpectFailure(spec, "[1, 2]",
219 ExpectFailure(spec, "['foo', 1]"); 254 GetIndexError(0u, invalid_type(kTypeString, kTypeInteger)));
255 ExpectFailure(spec, "['foo', 1]",
256 GetIndexError(1u, invalid_type(kTypeString, kTypeInteger)));
220 ExpectFailure(spec, 257 ExpectFailure(spec,
221 "var x = ['a', 'b', 'c'];" 258 "var x = ['a', 'b', 'c'];"
222 "x[4] = 'd';" // x[3] is undefined, violating the spec. 259 "x[4] = 'd';" // x[3] is undefined, violating the spec.
223 "x;"); 260 "x;",
261 GetIndexError(3u, invalid_type(kTypeString, kTypeUndefined)));
224 ExpectThrow( 262 ExpectThrow(
225 spec, 263 spec,
226 "var x = [];" 264 "var x = [];"
227 "Object.defineProperty(" 265 "Object.defineProperty("
228 " x, 0," 266 " x, 0,"
229 " { get: () => { throw new Error('Badness'); } });" 267 " { get: () => { throw new Error('Badness'); } });"
230 "x;", 268 "x;",
231 "Uncaught Error: Badness"); 269 "Uncaught Error: Badness");
232 } 270 }
233 271
234 { 272 {
235 const char kObjectSpec[] = 273 const char kObjectSpec[] =
236 "{" 274 "{"
237 " 'type': 'object'," 275 " 'type': 'object',"
238 " 'properties': {" 276 " 'properties': {"
239 " 'prop1': {'type': 'string'}," 277 " 'prop1': {'type': 'string'},"
240 " 'prop2': {'type': 'integer', 'optional': true}" 278 " 'prop2': {'type': 'integer', 'optional': true}"
241 " }" 279 " }"
242 "}"; 280 "}";
243 ArgumentSpec spec(*ValueFromString(kObjectSpec)); 281 ArgumentSpec spec(*ValueFromString(kObjectSpec));
244 ExpectSuccess(spec, "({prop1: 'foo', prop2: 2})", 282 ExpectSuccess(spec, "({prop1: 'foo', prop2: 2})",
245 "{'prop1':'foo','prop2':2}"); 283 "{'prop1':'foo','prop2':2}");
246 ExpectSuccess(spec, "({prop1: 'foo'})", "{'prop1':'foo'}"); 284 ExpectSuccess(spec, "({prop1: 'foo'})", "{'prop1':'foo'}");
247 ExpectSuccess(spec, "({prop1: 'foo', prop2: null})", "{'prop1':'foo'}"); 285 ExpectSuccess(spec, "({prop1: 'foo', prop2: null})", "{'prop1':'foo'}");
248 ExpectSuccess(spec, "x = {}; x.prop1 = 'foo'; x;", "{'prop1':'foo'}"); 286 ExpectSuccess(spec, "x = {}; x.prop1 = 'foo'; x;", "{'prop1':'foo'}");
249 ExpectFailure(spec, "({prop1: 'foo', prop2: 'bar'})"); 287 ExpectFailure(
250 ExpectFailure(spec, "({prop2: 2})"); 288 spec, "({prop1: 'foo', prop2: 'bar'})",
289 GetPropertyError("prop2", invalid_type(kTypeInteger, kTypeString)));
290 ExpectFailure(spec, "({prop2: 2})",
291 GetError(kMissingRequiredProperty, "prop1"));
251 // Unknown properties are not allowed. 292 // Unknown properties are not allowed.
252 ExpectFailure(spec, "({prop1: 'foo', prop2: 2, prop3: 'blah'})"); 293 ExpectFailure(spec, "({prop1: 'foo', prop2: 2, prop3: 'blah'})",
294 GetError(kUnexpectedProperty, "prop3"));
253 // We only consider properties on the object itself, not its prototype 295 // We only consider properties on the object itself, not its prototype
254 // chain. 296 // chain.
255 ExpectFailure(spec, 297 ExpectFailure(spec,
256 "function X() {}\n" 298 "function X() {}\n"
257 "X.prototype = { prop1: 'foo' };\n" 299 "X.prototype = { prop1: 'foo' };\n"
258 "var x = new X();\n" 300 "var x = new X();\n"
259 "x;"); 301 "x;",
302 GetError(kMissingRequiredProperty, "prop1"));
260 ExpectFailure(spec, 303 ExpectFailure(spec,
261 "function X() {}\n" 304 "function X() {}\n"
262 "X.prototype = { prop1: 'foo' };\n" 305 "X.prototype = { prop1: 'foo' };\n"
263 "function Y() { this.__proto__ = X.prototype; }\n" 306 "function Y() { this.__proto__ = X.prototype; }\n"
264 "var z = new Y();\n" 307 "var z = new Y();\n"
265 "z;"); 308 "z;",
309 GetError(kMissingRequiredProperty, "prop1"));
266 // Self-referential fun. Currently we don't have to worry about these much 310 // Self-referential fun. Currently we don't have to worry about these much
267 // because the spec won't match at some point (and V8ValueConverter has 311 // because the spec won't match at some point (and V8ValueConverter has
268 // cycle detection and will fail). 312 // cycle detection and will fail).
269 ExpectFailure(spec, "x = {}; x.prop1 = x; x;"); 313 ExpectFailure(
314 spec, "x = {}; x.prop1 = x; x;",
315 GetPropertyError("prop1", invalid_type(kTypeString, kTypeObject)));
270 ExpectThrow( 316 ExpectThrow(
271 spec, 317 spec,
272 "({ get prop1() { throw new Error('Badness'); }});", 318 "({ get prop1() { throw new Error('Badness'); }});",
273 "Uncaught Error: Badness"); 319 "Uncaught Error: Badness");
274 ExpectThrow(spec, 320 ExpectThrow(spec,
275 "x = {prop1: 'foo'};\n" 321 "x = {prop1: 'foo'};\n"
276 "Object.defineProperty(\n" 322 "Object.defineProperty(\n"
277 " x, 'prop2',\n" 323 " x, 'prop2',\n"
278 " {\n" 324 " {\n"
279 " get: () => { throw new Error('Badness'); },\n" 325 " get: () => { throw new Error('Badness'); },\n"
(...skipping 13 matching lines...) Expand all
293 } 339 }
294 340
295 { 341 {
296 const char kFunctionSpec[] = "{ 'type': 'function' }"; 342 const char kFunctionSpec[] = "{ 'type': 'function' }";
297 ArgumentSpec spec(*ValueFromString(kFunctionSpec)); 343 ArgumentSpec spec(*ValueFromString(kFunctionSpec));
298 // Functions are serialized as empty dictionaries. 344 // Functions are serialized as empty dictionaries.
299 ExpectSuccess(spec, "(function() {})", "{}"); 345 ExpectSuccess(spec, "(function() {})", "{}");
300 ExpectSuccessWithNoConversion(spec, "(function() {})"); 346 ExpectSuccessWithNoConversion(spec, "(function() {})");
301 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })"); 347 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })");
302 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })"); 348 ExpectSuccessWithNoConversion(spec, "(function(a, b) { a(); b(); })");
303 ExpectFailureWithNoConversion(spec, "({a: function() {}})"); 349 ExpectFailureWithNoConversion(spec, "({a: function() {}})",
304 ExpectFailureWithNoConversion(spec, "([function() {}])"); 350 invalid_type(kTypeFunction, kTypeObject));
305 ExpectFailureWithNoConversion(spec, "1"); 351 ExpectFailureWithNoConversion(spec, "([function() {}])",
352 invalid_type(kTypeFunction, kTypeList));
353 ExpectFailureWithNoConversion(spec, "1",
354 invalid_type(kTypeFunction, kTypeInteger));
306 } 355 }
307 356
308 { 357 {
309 const char kBinarySpec[] = "{ 'type': 'binary' }"; 358 const char kBinarySpec[] = "{ 'type': 'binary' }";
310 ArgumentSpec spec(*ValueFromString(kBinarySpec)); 359 ArgumentSpec spec(*ValueFromString(kBinarySpec));
311 // Simple case: empty ArrayBuffer -> empty BinaryValue. 360 // Simple case: empty ArrayBuffer -> empty BinaryValue.
312 ExpectSuccess(spec, "(new ArrayBuffer())", 361 ExpectSuccess(spec, "(new ArrayBuffer())",
313 base::Value(base::Value::Type::BINARY)); 362 base::Value(base::Value::Type::BINARY));
314 { 363 {
315 // A non-empty (but zero-filled) ArrayBufferView. 364 // A non-empty (but zero-filled) ArrayBufferView.
(...skipping 11 matching lines...) Expand all
327 ASSERT_TRUE(expected_value); 376 ASSERT_TRUE(expected_value);
328 ExpectSuccess(spec, 377 ExpectSuccess(spec,
329 "var b = new ArrayBuffer(4);\n" 378 "var b = new ArrayBuffer(4);\n"
330 "var v = new Uint8Array(b);\n" 379 "var v = new Uint8Array(b);\n"
331 "var s = 'ping';\n" 380 "var s = 'ping';\n"
332 "for (var i = 0; i < s.length; ++i)\n" 381 "for (var i = 0; i < s.length; ++i)\n"
333 " v[i] = s.charCodeAt(i);\n" 382 " v[i] = s.charCodeAt(i);\n"
334 "b;", 383 "b;",
335 *expected_value); 384 *expected_value);
336 } 385 }
337 ExpectFailure(spec, "1"); 386 ExpectFailure(spec, "1", invalid_type(kTypeBinary, kTypeInteger));
338 } 387 }
339 { 388 {
340 const char kAnySpec[] = "{ 'type': 'any' }"; 389 const char kAnySpec[] = "{ 'type': 'any' }";
341 ArgumentSpec spec(*ValueFromString(kAnySpec)); 390 ArgumentSpec spec(*ValueFromString(kAnySpec));
342 ExpectSuccess(spec, "42", "42"); 391 ExpectSuccess(spec, "42", "42");
343 ExpectSuccess(spec, "'foo'", "'foo'"); 392 ExpectSuccess(spec, "'foo'", "'foo'");
344 ExpectSuccess(spec, "({prop1:'bar'})", "{'prop1':'bar'}"); 393 ExpectSuccess(spec, "({prop1:'bar'})", "{'prop1':'bar'}");
345 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]"); 394 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]");
346 ExpectSuccess(spec, "[1, 'a']", "[1,'a']"); 395 ExpectSuccess(spec, "[1, 'a']", "[1,'a']");
347 ExpectSuccess(spec, "null", base::Value()); 396 ExpectSuccess(spec, "null", base::Value());
348 ExpectSuccess(spec, "({prop1: 'alpha', prop2: null})", 397 ExpectSuccess(spec, "({prop1: 'alpha', prop2: null})",
349 "{'prop1':'alpha','prop2':null}"); 398 "{'prop1':'alpha','prop2':null}");
350 ExpectSuccess(spec, 399 ExpectSuccess(spec,
351 "x = {alpha: 'alpha'};\n" 400 "x = {alpha: 'alpha'};\n"
352 "y = {beta: 'beta', x: x};\n" 401 "y = {beta: 'beta', x: x};\n"
353 "y;", 402 "y;",
354 "{'beta':'beta','x':{'alpha':'alpha'}}"); 403 "{'beta':'beta','x':{'alpha':'alpha'}}");
355 // We don't serialize undefined. 404 // We don't serialize undefined.
356 // TODO(devlin): This matches current behavior, but should it? Part of the 405 // TODO(devlin): This matches current behavior, but should it? Part of the
357 // problem is that base::Values don't differentiate between undefined and 406 // problem is that base::Values don't differentiate between undefined and
358 // null, which is a potentially important distinction. However, this means 407 // null, which is a potentially important distinction. However, this means
359 // that in serialization of an object {a: 1, foo:undefined}, we lose the 408 // that in serialization of an object {a: 1, foo:undefined}, we lose the
360 // 'foo' property. 409 // 'foo' property.
361 ExpectFailure(spec, "undefined"); 410 ExpectFailure(spec, "undefined", kUnserializableValue);
411
362 ExpectSuccess(spec, "({prop1: 1, prop2: undefined})", "{'prop1':1}"); 412 ExpectSuccess(spec, "({prop1: 1, prop2: undefined})", "{'prop1':1}");
363 } 413 }
364 } 414 }
365 415
366 TEST_F(ArgumentSpecUnitTest, TypeRefsTest) { 416 TEST_F(ArgumentSpecUnitTest, TypeRefsTest) {
417 using namespace api_errors;
367 const char kObjectType[] = 418 const char kObjectType[] =
368 "{" 419 "{"
369 " 'id': 'refObj'," 420 " 'id': 'refObj',"
370 " 'type': 'object'," 421 " 'type': 'object',"
371 " 'properties': {" 422 " 'properties': {"
372 " 'prop1': {'type': 'string'}," 423 " 'prop1': {'type': 'string'},"
373 " 'prop2': {'type': 'integer', 'optional': true}" 424 " 'prop2': {'type': 'integer', 'optional': true}"
374 " }" 425 " }"
375 "}"; 426 "}";
376 const char kEnumType[] = 427 const char kEnumType[] =
377 "{'id': 'refEnum', 'type': 'string', 'enum': ['alpha', 'beta']}"; 428 "{'id': 'refEnum', 'type': 'string', 'enum': ['alpha', 'beta']}";
378 AddTypeRef("refObj", 429 AddTypeRef("refObj",
379 base::MakeUnique<ArgumentSpec>(*ValueFromString(kObjectType))); 430 base::MakeUnique<ArgumentSpec>(*ValueFromString(kObjectType)));
380 AddTypeRef("refEnum", 431 AddTypeRef("refEnum",
381 base::MakeUnique<ArgumentSpec>(*ValueFromString(kEnumType))); 432 base::MakeUnique<ArgumentSpec>(*ValueFromString(kEnumType)));
382 433
383 { 434 {
384 const char kObjectWithRefEnumSpec[] = 435 const char kObjectWithRefEnumSpec[] =
385 "{" 436 "{"
386 " 'name': 'objWithRefEnum'," 437 " 'name': 'objWithRefEnum',"
387 " 'type': 'object'," 438 " 'type': 'object',"
388 " 'properties': {" 439 " 'properties': {"
389 " 'e': {'$ref': 'refEnum'}," 440 " 'e': {'$ref': 'refEnum'},"
390 " 'sub': {'type': 'integer'}" 441 " 'sub': {'type': 'integer'}"
391 " }" 442 " }"
392 "}"; 443 "}";
393 ArgumentSpec spec(*ValueFromString(kObjectWithRefEnumSpec)); 444 ArgumentSpec spec(*ValueFromString(kObjectWithRefEnumSpec));
394 ExpectSuccess(spec, "({e: 'alpha', sub: 1})", "{'e':'alpha','sub':1}"); 445 ExpectSuccess(spec, "({e: 'alpha', sub: 1})", "{'e':'alpha','sub':1}");
395 ExpectSuccess(spec, "({e: 'beta', sub: 1})", "{'e':'beta','sub':1}"); 446 ExpectSuccess(spec, "({e: 'beta', sub: 1})", "{'e':'beta','sub':1}");
396 ExpectFailure(spec, "({e: 'gamma', sub: 1})"); 447 ExpectFailure(
397 ExpectFailure(spec, "({e: 'alpha'})"); 448 spec, "({e: 'gamma', sub: 1})",
449 GetPropertyError("e", GetError(kInvalidEnumValue, "alpha, beta")));
450 ExpectFailure(spec, "({e: 'alpha'})",
451 GetError(kMissingRequiredProperty, "sub"));
398 } 452 }
399 453
400 { 454 {
401 const char kObjectWithRefObjectSpec[] = 455 const char kObjectWithRefObjectSpec[] =
402 "{" 456 "{"
403 " 'name': 'objWithRefObject'," 457 " 'name': 'objWithRefObject',"
404 " 'type': 'object'," 458 " 'type': 'object',"
405 " 'properties': {" 459 " 'properties': {"
406 " 'o': {'$ref': 'refObj'}" 460 " 'o': {'$ref': 'refObj'}"
407 " }" 461 " }"
408 "}"; 462 "}";
409 ArgumentSpec spec(*ValueFromString(kObjectWithRefObjectSpec)); 463 ArgumentSpec spec(*ValueFromString(kObjectWithRefObjectSpec));
410 ExpectSuccess(spec, "({o: {prop1: 'foo'}})", "{'o':{'prop1':'foo'}}"); 464 ExpectSuccess(spec, "({o: {prop1: 'foo'}})", "{'o':{'prop1':'foo'}}");
411 ExpectSuccess(spec, "({o: {prop1: 'foo', prop2: 2}})", 465 ExpectSuccess(spec, "({o: {prop1: 'foo', prop2: 2}})",
412 "{'o':{'prop1':'foo','prop2':2}}"); 466 "{'o':{'prop1':'foo','prop2':2}}");
413 ExpectFailure(spec, "({o: {prop1: 1}})"); 467 ExpectFailure(
468 spec, "({o: {prop1: 1}})",
469 GetPropertyError(
470 "o", GetPropertyError("prop1", GetError(kInvalidType, kTypeString,
471 kTypeInteger))));
414 } 472 }
415 473
416 { 474 {
417 const char kRefEnumListSpec[] = 475 const char kRefEnumListSpec[] =
418 "{'type': 'array', 'items': {'$ref': 'refEnum'}}"; 476 "{'type': 'array', 'items': {'$ref': 'refEnum'}}";
419 ArgumentSpec spec(*ValueFromString(kRefEnumListSpec)); 477 ArgumentSpec spec(*ValueFromString(kRefEnumListSpec));
420 ExpectSuccess(spec, "['alpha']", "['alpha']"); 478 ExpectSuccess(spec, "['alpha']", "['alpha']");
421 ExpectSuccess(spec, "['alpha', 'alpha']", "['alpha','alpha']"); 479 ExpectSuccess(spec, "['alpha', 'alpha']", "['alpha','alpha']");
422 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']"); 480 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']");
423 ExpectFailure(spec, "['alpha', 'beta', 'gamma']"); 481 ExpectFailure(
482 spec, "['alpha', 'beta', 'gamma']",
483 GetIndexError(2u, GetError(kInvalidEnumValue, "alpha, beta")));
424 } 484 }
425 } 485 }
426 486
427 TEST_F(ArgumentSpecUnitTest, TypeChoicesTest) { 487 TEST_F(ArgumentSpecUnitTest, TypeChoicesTest) {
488 using namespace api_errors;
428 { 489 {
429 const char kSimpleChoices[] = 490 const char kSimpleChoices[] =
430 "{'choices': [{'type': 'string'}, {'type': 'integer'}]}"; 491 "{'choices': [{'type': 'string'}, {'type': 'integer'}]}";
431 ArgumentSpec spec(*ValueFromString(kSimpleChoices)); 492 ArgumentSpec spec(*ValueFromString(kSimpleChoices));
432 ExpectSuccess(spec, "'alpha'", "'alpha'"); 493 ExpectSuccess(spec, "'alpha'", "'alpha'");
433 ExpectSuccess(spec, "42", "42"); 494 ExpectSuccess(spec, "42", "42");
434 ExpectFailure(spec, "true"); 495 ExpectFailure(spec, "true", kInvalidChoice);
435 } 496 }
436 497
437 { 498 {
438 const char kComplexChoices[] = 499 const char kComplexChoices[] =
439 "{" 500 "{"
440 " 'choices': [" 501 " 'choices': ["
441 " {'type': 'array', 'items': {'type': 'string'}}," 502 " {'type': 'array', 'items': {'type': 'string'}},"
442 " {'type': 'object', 'properties': {'prop1': {'type': 'string'}}}" 503 " {'type': 'object', 'properties': {'prop1': {'type': 'string'}}}"
443 " ]" 504 " ]"
444 "}"; 505 "}";
445 ArgumentSpec spec(*ValueFromString(kComplexChoices)); 506 ArgumentSpec spec(*ValueFromString(kComplexChoices));
446 ExpectSuccess(spec, "['alpha']", "['alpha']"); 507 ExpectSuccess(spec, "['alpha']", "['alpha']");
447 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']"); 508 ExpectSuccess(spec, "['alpha', 'beta']", "['alpha','beta']");
448 ExpectSuccess(spec, "({prop1: 'alpha'})", "{'prop1':'alpha'}"); 509 ExpectSuccess(spec, "({prop1: 'alpha'})", "{'prop1':'alpha'}");
449 ExpectFailure(spec, "({prop1: 1})"); 510 ExpectFailure(spec, "({prop1: 1})", kInvalidChoice);
450 ExpectFailure(spec, "'alpha'"); 511 ExpectFailure(spec, "'alpha'", kInvalidChoice);
451 ExpectFailure(spec, "42"); 512 ExpectFailure(spec, "42", kInvalidChoice);
452 } 513 }
453 } 514 }
454 515
455 TEST_F(ArgumentSpecUnitTest, AdditionalPropertiesTest) { 516 TEST_F(ArgumentSpecUnitTest, AdditionalPropertiesTest) {
517 using namespace api_errors;
456 { 518 {
457 const char kOnlyAnyAdditionalProperties[] = 519 const char kOnlyAnyAdditionalProperties[] =
458 "{" 520 "{"
459 " 'type': 'object'," 521 " 'type': 'object',"
460 " 'additionalProperties': {'type': 'any'}" 522 " 'additionalProperties': {'type': 'any'}"
461 "}"; 523 "}";
462 ArgumentSpec spec(*ValueFromString(kOnlyAnyAdditionalProperties)); 524 ArgumentSpec spec(*ValueFromString(kOnlyAnyAdditionalProperties));
463 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 42, prop3: {foo: 'bar'}})", 525 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 42, prop3: {foo: 'bar'}})",
464 "{'prop1':'alpha','prop2':42,'prop3':{'foo':'bar'}}"); 526 "{'prop1':'alpha','prop2':42,'prop3':{'foo':'bar'}}");
465 ExpectSuccess(spec, "({})", "{}"); 527 ExpectSuccess(spec, "({})", "{}");
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 " 'properties': {" 588 " 'properties': {"
527 " 'prop1': {'type': 'string'}" 589 " 'prop1': {'type': 'string'}"
528 " }," 590 " },"
529 " 'additionalProperties': {'type': 'any'}" 591 " 'additionalProperties': {'type': 'any'}"
530 "}"; 592 "}";
531 ArgumentSpec spec(*ValueFromString(kPropertiesAndAnyAdditionalProperties)); 593 ArgumentSpec spec(*ValueFromString(kPropertiesAndAnyAdditionalProperties));
532 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 42, prop3: {foo: 'bar'}})", 594 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 42, prop3: {foo: 'bar'}})",
533 "{'prop1':'alpha','prop2':42,'prop3':{'foo':'bar'}}"); 595 "{'prop1':'alpha','prop2':42,'prop3':{'foo':'bar'}}");
534 // Additional properties are optional. 596 // Additional properties are optional.
535 ExpectSuccess(spec, "({prop1: 'foo'})", "{'prop1':'foo'}"); 597 ExpectSuccess(spec, "({prop1: 'foo'})", "{'prop1':'foo'}");
536 ExpectFailure(spec, "({prop2: 42, prop3: {foo: 'bar'}})"); 598 ExpectFailure(spec, "({prop2: 42, prop3: {foo: 'bar'}})",
537 ExpectFailure(spec, "({prop1: 42})"); 599 GetError(kMissingRequiredProperty, "prop1"));
600 ExpectFailure(spec, "({prop1: 42})",
601 GetPropertyError("prop1", GetError(kInvalidType, kTypeString,
602 kTypeInteger)));
538 } 603 }
539 { 604 {
540 const char kTypedAdditionalProperties[] = 605 const char kTypedAdditionalProperties[] =
541 "{" 606 "{"
542 " 'type': 'object'," 607 " 'type': 'object',"
543 " 'additionalProperties': {'type': 'string'}" 608 " 'additionalProperties': {'type': 'string'}"
544 "}"; 609 "}";
545 ArgumentSpec spec(*ValueFromString(kTypedAdditionalProperties)); 610 ArgumentSpec spec(*ValueFromString(kTypedAdditionalProperties));
546 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 'beta', prop3: 'gamma'})", 611 ExpectSuccess(spec, "({prop1: 'alpha', prop2: 'beta', prop3: 'gamma'})",
547 "{'prop1':'alpha','prop2':'beta','prop3':'gamma'}"); 612 "{'prop1':'alpha','prop2':'beta','prop3':'gamma'}");
548 ExpectFailure(spec, "({prop1: 'alpha', prop2: 42})"); 613 ExpectFailure(spec, "({prop1: 'alpha', prop2: 42})",
614 GetPropertyError("prop2", GetError(kInvalidType, kTypeString,
615 kTypeInteger)));
549 } 616 }
550 } 617 }
551 618
552 TEST_F(ArgumentSpecUnitTest, InstanceOfTest) { 619 TEST_F(ArgumentSpecUnitTest, InstanceOfTest) {
620 using namespace api_errors;
553 { 621 {
554 const char kInstanceOfRegExp[] = 622 const char kInstanceOfRegExp[] =
555 "{" 623 "{"
556 " 'type': 'object'," 624 " 'type': 'object',"
557 " 'isInstanceOf': 'RegExp'" 625 " 'isInstanceOf': 'RegExp'"
558 "}"; 626 "}";
559 ArgumentSpec spec(*ValueFromString(kInstanceOfRegExp)); 627 ArgumentSpec spec(*ValueFromString(kInstanceOfRegExp));
560 ExpectSuccess(spec, "(new RegExp())", "{}"); 628 ExpectSuccess(spec, "(new RegExp())", "{}");
561 ExpectSuccess(spec, "({ __proto__: RegExp.prototype })", "{}"); 629 ExpectSuccess(spec, "({ __proto__: RegExp.prototype })", "{}");
562 ExpectSuccess(spec, 630 ExpectSuccess(spec,
563 "(function() {\n" 631 "(function() {\n"
564 " function subRegExp() {}\n" 632 " function subRegExp() {}\n"
565 " subRegExp.prototype = { __proto__: RegExp.prototype };\n" 633 " subRegExp.prototype = { __proto__: RegExp.prototype };\n"
566 " return new subRegExp();\n" 634 " return new subRegExp();\n"
567 "})()", 635 "})()",
568 "{}"); 636 "{}");
569 ExpectSuccess(spec, 637 ExpectSuccess(spec,
570 "(function() {\n" 638 "(function() {\n"
571 " function RegExp() {}\n" 639 " function RegExp() {}\n"
572 " return new RegExp();\n" 640 " return new RegExp();\n"
573 "})()", 641 "})()",
574 "{}"); 642 "{}");
575 ExpectFailure(spec, "({})"); 643 ExpectFailure(spec, "({})", GetError(kNotAnInstance, "RegExp"));
576 ExpectFailure(spec, "('')"); 644 ExpectFailure(spec, "('')", GetError(kInvalidType, "RegExp", kTypeString));
577 ExpectFailure(spec, "('.*')"); 645 ExpectFailure(spec, "('.*')",
578 ExpectFailure(spec, "({ __proto__: Date.prototype })"); 646 GetError(kInvalidType, "RegExp", kTypeString));
647 ExpectFailure(spec, "({ __proto__: Date.prototype })",
648 GetError(kNotAnInstance, "RegExp"));
579 } 649 }
580 650
581 { 651 {
582 const char kInstanceOfCustomClass[] = 652 const char kInstanceOfCustomClass[] =
583 "{" 653 "{"
584 " 'type': 'object'," 654 " 'type': 'object',"
585 " 'isInstanceOf': 'customClass'" 655 " 'isInstanceOf': 'customClass'"
586 "}"; 656 "}";
587 ArgumentSpec spec(*ValueFromString(kInstanceOfCustomClass)); 657 ArgumentSpec spec(*ValueFromString(kInstanceOfCustomClass));
588 ExpectSuccess(spec, 658 ExpectSuccess(spec,
589 "(function() {\n" 659 "(function() {\n"
590 " function customClass() {}\n" 660 " function customClass() {}\n"
591 " return new customClass();\n" 661 " return new customClass();\n"
592 "})()", 662 "})()",
593 "{}"); 663 "{}");
594 ExpectSuccess(spec, 664 ExpectSuccess(spec,
595 "(function() {\n" 665 "(function() {\n"
596 " function customClass() {}\n" 666 " function customClass() {}\n"
597 " function otherClass() {}\n" 667 " function otherClass() {}\n"
598 " otherClass.prototype = \n" 668 " otherClass.prototype = \n"
599 " { __proto__: customClass.prototype };\n" 669 " { __proto__: customClass.prototype };\n"
600 " return new otherClass();\n" 670 " return new otherClass();\n"
601 "})()", 671 "})()",
602 "{}"); 672 "{}");
603 ExpectFailure(spec, "({})"); 673 ExpectFailure(spec, "({})", GetError(kNotAnInstance, "customClass"));
604 ExpectFailure(spec, 674 ExpectFailure(spec,
605 "(function() {\n" 675 "(function() {\n"
606 " function otherClass() {}\n" 676 " function otherClass() {}\n"
607 " return new otherClass();\n" 677 " return new otherClass();\n"
608 "})()"); 678 "})()",
679 GetError(kNotAnInstance, "customClass"));
609 } 680 }
610 } 681 }
611 682
612 TEST_F(ArgumentSpecUnitTest, MinAndMaxLengths) { 683 TEST_F(ArgumentSpecUnitTest, MinAndMaxLengths) {
684 using namespace api_errors;
613 { 685 {
614 const char kMinLengthString[] = "{'type': 'string', 'minLength': 3}"; 686 const char kMinLengthString[] = "{'type': 'string', 'minLength': 3}";
615 ArgumentSpec spec(*ValueFromString(kMinLengthString)); 687 ArgumentSpec spec(*ValueFromString(kMinLengthString));
616 ExpectSuccess(spec, "'aaa'", "'aaa'"); 688 ExpectSuccess(spec, "'aaa'", "'aaa'");
617 ExpectSuccess(spec, "'aaaa'", "'aaaa'"); 689 ExpectSuccess(spec, "'aaaa'", "'aaaa'");
618 ExpectFailure(spec, "'aa'"); 690 ExpectFailure(spec, "'aa'", GetError(kTooFewStringChars, 3));
619 ExpectFailure(spec, "''"); 691 ExpectFailure(spec, "''", GetError(kTooFewStringChars, 3));
620 } 692 }
621 693
622 { 694 {
623 const char kMaxLengthString[] = "{'type': 'string', 'maxLength': 3}"; 695 const char kMaxLengthString[] = "{'type': 'string', 'maxLength': 3}";
624 ArgumentSpec spec(*ValueFromString(kMaxLengthString)); 696 ArgumentSpec spec(*ValueFromString(kMaxLengthString));
625 ExpectSuccess(spec, "'aaa'", "'aaa'"); 697 ExpectSuccess(spec, "'aaa'", "'aaa'");
626 ExpectSuccess(spec, "'aa'", "'aa'"); 698 ExpectSuccess(spec, "'aa'", "'aa'");
627 ExpectSuccess(spec, "''", "''"); 699 ExpectSuccess(spec, "''", "''");
628 ExpectFailure(spec, "'aaaa'"); 700 ExpectFailure(spec, "'aaaa'", GetError(kTooManyStringChars, 3));
629 } 701 }
630 702
631 { 703 {
632 const char kMinLengthArray[] = 704 const char kMinLengthArray[] =
633 "{'type': 'array', 'items': {'type': 'integer'}, 'minItems': 3}"; 705 "{'type': 'array', 'items': {'type': 'integer'}, 'minItems': 3}";
634 ArgumentSpec spec(*ValueFromString(kMinLengthArray)); 706 ArgumentSpec spec(*ValueFromString(kMinLengthArray));
635 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]"); 707 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]");
636 ExpectSuccess(spec, "[1, 2, 3, 4]", "[1,2,3,4]"); 708 ExpectSuccess(spec, "[1, 2, 3, 4]", "[1,2,3,4]");
637 ExpectFailure(spec, "[1, 2]"); 709 ExpectFailure(spec, "[1, 2]", GetError(kTooFewArrayItems, 3));
638 ExpectFailure(spec, "[]"); 710 ExpectFailure(spec, "[]", GetError(kTooFewArrayItems, 3));
639 } 711 }
640 712
641 { 713 {
642 const char kMaxLengthArray[] = 714 const char kMaxLengthArray[] =
643 "{'type': 'array', 'items': {'type': 'integer'}, 'maxItems': 3}"; 715 "{'type': 'array', 'items': {'type': 'integer'}, 'maxItems': 3}";
644 ArgumentSpec spec(*ValueFromString(kMaxLengthArray)); 716 ArgumentSpec spec(*ValueFromString(kMaxLengthArray));
645 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]"); 717 ExpectSuccess(spec, "[1, 2, 3]", "[1,2,3]");
646 ExpectSuccess(spec, "[1, 2]", "[1,2]"); 718 ExpectSuccess(spec, "[1, 2]", "[1,2]");
647 ExpectSuccess(spec, "[]", "[]"); 719 ExpectSuccess(spec, "[]", "[]");
648 ExpectFailure(spec, "[1, 2, 3, 4]"); 720 ExpectFailure(spec, "[1, 2, 3, 4]", GetError(kTooManyArrayItems, 3));
649 } 721 }
650 } 722 }
651 723
652 } // namespace extensions 724 } // namespace extensions
OLDNEW
« extensions/renderer/argument_spec.cc ('K') | « extensions/renderer/argument_spec.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698