OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <cmath> | 5 #include <cmath> |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/test/values_test_util.h" | |
8 #include "base/values.h" | 9 #include "base/values.h" |
9 #include "content/renderer/v8_value_converter_impl.h" | 10 #include "content/renderer/v8_value_converter_impl.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
11 #include "v8/include/v8.h" | 12 #include "v8/include/v8.h" |
12 | 13 |
13 namespace content { | 14 namespace content { |
14 | 15 |
15 namespace { | 16 namespace { |
16 | 17 |
17 // A dumb getter for an object's named callback. | 18 // A dumb getter for an object's named callback. |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
157 ASSERT_TRUE(list->Get(0, &temp)); | 158 ASSERT_TRUE(list->Get(0, &temp)); |
158 EXPECT_EQ(Value::TYPE_NULL, temp->GetType()); | 159 EXPECT_EQ(Value::TYPE_NULL, temp->GetType()); |
159 } | 160 } |
160 } | 161 } |
161 | 162 |
162 // Context for the JavaScript in the test. | 163 // Context for the JavaScript in the test. |
163 v8::Persistent<v8::Context> context_; | 164 v8::Persistent<v8::Context> context_; |
164 }; | 165 }; |
165 | 166 |
166 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { | 167 TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { |
167 DictionaryValue original_root; | 168 scoped_ptr<Value> original_root = base::test::ParseJson( |
168 original_root.Set("null", Value::CreateNullValue()); | 169 "{ \n" |
169 original_root.Set("true", Value::CreateBooleanValue(true)); | 170 " \"null\": null, \n" |
170 original_root.Set("false", Value::CreateBooleanValue(false)); | 171 " \"true\": true, \n" |
171 original_root.Set("positive-int", Value::CreateIntegerValue(42)); | 172 " \"false\": false, \n" |
172 original_root.Set("negative-int", Value::CreateIntegerValue(-42)); | 173 " \"positive-int\": 42, \n" |
173 original_root.Set("zero", Value::CreateIntegerValue(0)); | 174 " \"negative-int\": -42, \n" |
174 original_root.Set("double", Value::CreateDoubleValue(88.8)); | 175 " \"zero\": 0, \n" |
175 original_root.Set("big-integral-double", | 176 " \"double\": 88.8, \n" |
176 Value::CreateDoubleValue(pow(2.0, 53))); | 177 " \"big-integral-double\": 9007199254740992.0, \n" // 2.0^53 |
177 original_root.Set("string", Value::CreateStringValue("foobar")); | 178 " \"string\": \"foobar\", \n" |
178 original_root.Set("empty-string", Value::CreateStringValue("")); | 179 " \"empty-string\": \"\", \n" |
179 | 180 " \"dictionary\": { \n" |
180 DictionaryValue* original_sub1 = new DictionaryValue(); | 181 " \"foo\": \"bar\",\n" |
181 original_sub1->Set("foo", Value::CreateStringValue("bar")); | 182 " \"hot\": \"dog\",\n" |
182 original_sub1->Set("hot", Value::CreateStringValue("dog")); | 183 " }, \n" |
183 original_root.Set("dictionary", original_sub1); | 184 " \"empty-dictionary\": {}, \n" |
184 original_root.Set("empty-dictionary", new DictionaryValue()); | 185 " \"list\": [ \"monkey\", \"balls\" ], \n" |
185 | 186 " \"empty-list\": [], \n" |
186 ListValue* original_sub2 = new ListValue(); | 187 "}"); |
187 original_sub2->Append(Value::CreateStringValue("monkey")); | |
188 original_sub2->Append(Value::CreateStringValue("balls")); | |
189 original_root.Set("list", original_sub2); | |
190 original_root.Set("empty-list", new ListValue()); | |
191 | 188 |
192 v8::Context::Scope context_scope(context_); | 189 v8::Context::Scope context_scope(context_); |
193 v8::HandleScope handle_scope; | 190 v8::HandleScope handle_scope; |
194 | 191 |
195 V8ValueConverterImpl converter; | 192 V8ValueConverterImpl converter; |
196 v8::Handle<v8::Object> v8_object = | 193 v8::Handle<v8::Object> v8_object = |
197 converter.ToV8Value(&original_root, context_).As<v8::Object>(); | 194 converter.ToV8Value(original_root.get(), context_).As<v8::Object>(); |
198 ASSERT_FALSE(v8_object.IsEmpty()); | 195 ASSERT_FALSE(v8_object.IsEmpty()); |
199 | 196 |
200 EXPECT_EQ(original_root.size(), v8_object->GetPropertyNames()->Length()); | 197 EXPECT_EQ(static_cast<const DictionaryValue&>(*original_root).size(), |
198 v8_object->GetPropertyNames()->Length()); | |
201 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); | 199 EXPECT_TRUE(v8_object->Get(v8::String::New("null"))->IsNull()); |
202 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); | 200 EXPECT_TRUE(v8_object->Get(v8::String::New("true"))->IsTrue()); |
203 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); | 201 EXPECT_TRUE(v8_object->Get(v8::String::New("false"))->IsFalse()); |
204 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); | 202 EXPECT_TRUE(v8_object->Get(v8::String::New("positive-int"))->IsInt32()); |
205 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); | 203 EXPECT_TRUE(v8_object->Get(v8::String::New("negative-int"))->IsInt32()); |
206 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); | 204 EXPECT_TRUE(v8_object->Get(v8::String::New("zero"))->IsInt32()); |
207 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); | 205 EXPECT_TRUE(v8_object->Get(v8::String::New("double"))->IsNumber()); |
208 EXPECT_TRUE( | 206 EXPECT_TRUE( |
209 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); | 207 v8_object->Get(v8::String::New("big-integral-double"))->IsNumber()); |
210 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); | 208 EXPECT_TRUE(v8_object->Get(v8::String::New("string"))->IsString()); |
211 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); | 209 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-string"))->IsString()); |
212 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); | 210 EXPECT_TRUE(v8_object->Get(v8::String::New("dictionary"))->IsObject()); |
213 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); | 211 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-dictionary"))->IsObject()); |
214 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); | 212 EXPECT_TRUE(v8_object->Get(v8::String::New("list"))->IsArray()); |
215 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); | 213 EXPECT_TRUE(v8_object->Get(v8::String::New("empty-list"))->IsArray()); |
216 | 214 |
217 scoped_ptr<Value> new_root(converter.FromV8Value(v8_object, context_)); | 215 scoped_ptr<Value> new_root(converter.FromV8Value(v8_object, context_)); |
218 EXPECT_NE(&original_root, new_root.get()); | 216 EXPECT_NE(original_root.get(), new_root.get()); |
219 EXPECT_TRUE(original_root.Equals(new_root.get())); | 217 EXPECT_TRUE(original_root->Equals(new_root.get())); |
220 } | 218 } |
221 | 219 |
222 TEST_F(V8ValueConverterImplTest, KeysWithDots) { | 220 TEST_F(V8ValueConverterImplTest, KeysWithDots) { |
223 DictionaryValue original; | 221 scoped_ptr<Value> original = |
224 original.SetWithoutPathExpansion("foo.bar", Value::CreateStringValue("baz")); | 222 base::test::ParseJson("{ \"foo.bar\": \"baz\" }"); |
225 | 223 |
226 v8::Context::Scope context_scope(context_); | 224 v8::Context::Scope context_scope(context_); |
227 v8::HandleScope handle_scope; | 225 v8::HandleScope handle_scope; |
228 | 226 |
229 V8ValueConverterImpl converter; | 227 V8ValueConverterImpl converter; |
230 scoped_ptr<Value> copy( | 228 scoped_ptr<Value> copy( |
231 converter.FromV8Value( | 229 converter.FromV8Value( |
232 converter.ToV8Value(&original, context_), context_)); | 230 converter.ToV8Value(original.get(), context_), context_)); |
233 | 231 |
234 EXPECT_TRUE(original.Equals(copy.get())); | 232 EXPECT_TRUE(original->Equals(copy.get())); |
235 } | 233 } |
236 | 234 |
237 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { | 235 TEST_F(V8ValueConverterImplTest, ObjectExceptions) { |
238 v8::Context::Scope context_scope(context_); | 236 v8::Context::Scope context_scope(context_); |
239 v8::HandleScope handle_scope; | 237 v8::HandleScope handle_scope; |
240 | 238 |
241 // Set up objects to throw when reading or writing 'foo'. | 239 // Set up objects to throw when reading or writing 'foo'. |
242 const char* source = | 240 const char* source = |
243 "Object.prototype.__defineSetter__('foo', " | 241 "Object.prototype.__defineSetter__('foo', " |
244 " function() { throw new Error('muah!'); });" | 242 " function() { throw new Error('muah!'); });" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 // Converting from v8 value should replace the first item with null. | 290 // Converting from v8 value should replace the first item with null. |
293 V8ValueConverterImpl converter; | 291 V8ValueConverterImpl converter; |
294 scoped_ptr<ListValue> converted(static_cast<ListValue*>( | 292 scoped_ptr<ListValue> converted(static_cast<ListValue*>( |
295 converter.FromV8Value(array, context_))); | 293 converter.FromV8Value(array, context_))); |
296 ASSERT_TRUE(converted.get()); | 294 ASSERT_TRUE(converted.get()); |
297 // http://code.google.com/p/v8/issues/detail?id=1342 | 295 // http://code.google.com/p/v8/issues/detail?id=1342 |
298 EXPECT_EQ(2u, converted->GetSize()); | 296 EXPECT_EQ(2u, converted->GetSize()); |
299 EXPECT_TRUE(IsNull(converted.get(), 0)); | 297 EXPECT_TRUE(IsNull(converted.get(), 0)); |
300 | 298 |
301 // Converting to v8 value should drop the first item and leave a hole. | 299 // Converting to v8 value should drop the first item and leave a hole. |
302 converted.reset(new ListValue()); | 300 converted.reset(static_cast<ListValue*>( |
303 converted->Append(Value::CreateStringValue("foo")); | 301 base::test::ParseJson("[ \"foo\", \"bar\" ]").release())); |
304 converted->Append(Value::CreateStringValue("bar")); | |
305 v8::Handle<v8::Array> copy = | 302 v8::Handle<v8::Array> copy = |
306 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); | 303 converter.ToV8Value(converted.get(), context_).As<v8::Array>(); |
307 ASSERT_FALSE(copy.IsEmpty()); | 304 ASSERT_FALSE(copy.IsEmpty()); |
308 EXPECT_EQ(2u, copy->Length()); | 305 EXPECT_EQ(2u, copy->Length()); |
309 EXPECT_EQ("bar", GetString(copy, 1)); | 306 EXPECT_EQ("bar", GetString(copy, 1)); |
310 } | 307 } |
311 | 308 |
312 TEST_F(V8ValueConverterImplTest, WeirdTypes) { | 309 TEST_F(V8ValueConverterImplTest, WeirdTypes) { |
313 v8::Context::Scope context_scope(context_); | 310 v8::Context::Scope context_scope(context_); |
314 v8::HandleScope handle_scope; | 311 v8::HandleScope handle_scope; |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 "};" | 466 "};" |
470 "})();"; | 467 "})();"; |
471 | 468 |
472 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 469 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
473 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); | 470 v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); |
474 ASSERT_FALSE(object.IsEmpty()); | 471 ASSERT_FALSE(object.IsEmpty()); |
475 | 472 |
476 V8ValueConverterImpl converter; | 473 V8ValueConverterImpl converter; |
477 scoped_ptr<Value> actual(converter.FromV8Value(object, context_)); | 474 scoped_ptr<Value> actual(converter.FromV8Value(object, context_)); |
478 | 475 |
479 DictionaryValue expected; | 476 scoped_ptr<Value> expected = base::test::ParseJson( |
480 expected.SetString("1", "foo"); | 477 "{ \n" |
481 expected.SetString("2", "bar"); | 478 " \"1\": \"foo\", \n" |
482 expected.SetString("true", "baz"); | 479 " \"2\": \"bar\", \n" |
483 expected.SetString("false", "qux"); | 480 " \"true\": \"baz\", \n" |
484 expected.SetString("null", "quux"); | 481 " \"false\": \"qux\", \n" |
485 expected.SetString("undefined", "oops"); | 482 " \"null\": \"quux\", \n" |
483 " \"undefined\": \"oops\", \n" | |
484 "}"); | |
486 | 485 |
487 EXPECT_TRUE(expected.Equals(actual.get())); | 486 EXPECT_TRUE(expected->Equals(actual.get())); |
488 } | 487 } |
489 | 488 |
490 TEST_F(V8ValueConverterImplTest, ArrayGetters) { | 489 TEST_F(V8ValueConverterImplTest, ArrayGetters) { |
491 v8::Context::Scope context_scope(context_); | 490 v8::Context::Scope context_scope(context_); |
492 v8::HandleScope handle_scope; | 491 v8::HandleScope handle_scope; |
493 | 492 |
494 const char* source = "(function() {" | 493 const char* source = "(function() {" |
495 "var a = [0];" | 494 "var a = [0];" |
496 "a.__defineGetter__(1, function() { return 'bar'; });" | 495 "a.__defineGetter__(1, function() { return 'bar'; });" |
497 "return a;" | 496 "return a;" |
(...skipping 29 matching lines...) Expand all Loading... | |
527 const char* source = "(function() {" | 526 const char* source = "(function() {" |
528 "return [ undefined, null, function(){} ];" | 527 "return [ undefined, null, function(){} ];" |
529 "})();"; | 528 "})();"; |
530 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); | 529 v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source))); |
531 array = script->Run().As<v8::Array>(); | 530 array = script->Run().As<v8::Array>(); |
532 ASSERT_FALSE(array.IsEmpty()); | 531 ASSERT_FALSE(array.IsEmpty()); |
533 } | 532 } |
534 | 533 |
535 V8ValueConverterImpl converter; | 534 V8ValueConverterImpl converter; |
536 | 535 |
537 DictionaryValue expected_object; | |
538 expected_object.Set("bar", Value::CreateNullValue()); | |
539 scoped_ptr<Value> actual_object(converter.FromV8Value(object, context_)); | 536 scoped_ptr<Value> actual_object(converter.FromV8Value(object, context_)); |
540 EXPECT_TRUE(Value::Equals(&expected_object, actual_object.get())); | 537 EXPECT_TRUE(Value::Equals(base::test::ParseJson("{ \"bar\": null }").get(), |
battre
2012/12/17 09:36:49
Is this one guaranteed to be correct? I can see th
Jeffrey Yasskin
2012/12/17 18:09:27
The scoped_ptr is destroyed, destroying the Value,
| |
538 actual_object.get())); | |
541 | 539 |
542 ListValue expected_array; | |
543 // Everything is null because JSON stringification preserves array length. | 540 // Everything is null because JSON stringification preserves array length. |
544 expected_array.Append(Value::CreateNullValue()); | |
545 expected_array.Append(Value::CreateNullValue()); | |
546 expected_array.Append(Value::CreateNullValue()); | |
547 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); | 541 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); |
548 EXPECT_TRUE(Value::Equals(&expected_array, actual_array.get())); | 542 EXPECT_TRUE(Value::Equals(base::test::ParseJson("[ null, null, null ]").get(), |
battre
2012/12/17 09:36:49
same here.
Jeffrey Yasskin
2012/12/17 18:09:27
same here. :)
| |
543 actual_array.get())); | |
549 } | 544 } |
550 | 545 |
551 } // namespace content | 546 } // namespace content |
OLD | NEW |