Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(924)

Side by Side Diff: content/renderer/v8_value_converter_impl_unittest.cc

Issue 12633013: Improve the v8::Object uniqueness check in V8ValueConverterImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments addressed + unit tests added Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « content/renderer/v8_value_converter_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/stl_util.h"
8 #include "base/test/values_test_util.h" 9 #include "base/test/values_test_util.h"
9 #include "base/values.h" 10 #include "base/values.h"
10 #include "content/renderer/v8_value_converter_impl.h" 11 #include "content/renderer/v8_value_converter_impl.h"
11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
12 #include "v8/include/v8.h" 13 #include "v8/include/v8.h"
13 14
14 namespace content { 15 namespace content {
15 16
17 // To improve the performance of
18 // V8ValueConverterImpl::UpdateAndCheckUniqueness, identity hashes of objects
19 // are used during checking for duplicates. For testing purposes we need to
20 // ignore the hash sometimes. Create this helper object to avoid using identity
21 // hashes for the lifetime of the helper.
22 class ScopedAvoidIdentityHashForTesting {
vabr (Chromium) 2013/03/15 14:37:45 This class cannot be in the anonymous namespace, b
23 public:
24 // The hashes will be ignored in |converter|, which must not be NULL and it
25 // must outlive the created instance of this helper.
26 explicit ScopedAvoidIdentityHashForTesting(
27 content::V8ValueConverterImpl* converter);
28 ~ScopedAvoidIdentityHashForTesting();
29
30 private:
31 content::V8ValueConverterImpl* converter_;
32
33 DISALLOW_COPY_AND_ASSIGN(ScopedAvoidIdentityHashForTesting);
34 };
35
36 ScopedAvoidIdentityHashForTesting::ScopedAvoidIdentityHashForTesting(
37 content::V8ValueConverterImpl* converter)
38 : converter_(converter) {
39 CHECK(converter_);
40 converter_->avoid_identity_hash_for_testing_ = true;
41 }
42
43 ScopedAvoidIdentityHashForTesting::~ScopedAvoidIdentityHashForTesting() {
44 converter_->avoid_identity_hash_for_testing_ = false;
45 }
46
16 namespace { 47 namespace {
17 48
18 // A dumb getter for an object's named callback. 49 // A dumb getter for an object's named callback.
19 v8::Handle<v8::Value> NamedCallbackGetter(v8::Local<v8::String> name, 50 v8::Handle<v8::Value> NamedCallbackGetter(v8::Local<v8::String> name,
20 const v8::AccessorInfo& info) { 51 const v8::AccessorInfo& info) {
21 return v8::String::New("bar"); 52 return v8::String::New("bar");
22 } 53 }
23 54
24 } // namespace 55 } // namespace
25 56
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 converter.FromV8Value(object, context_)); 573 converter.FromV8Value(object, context_));
543 EXPECT_TRUE(base::Value::Equals( 574 EXPECT_TRUE(base::Value::Equals(
544 base::test::ParseJson("{ \"bar\": null }").get(), actual_object.get())); 575 base::test::ParseJson("{ \"bar\": null }").get(), actual_object.get()));
545 576
546 // Everything is null because JSON stringification preserves array length. 577 // Everything is null because JSON stringification preserves array length.
547 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_)); 578 scoped_ptr<Value> actual_array(converter.FromV8Value(array, context_));
548 EXPECT_TRUE(base::Value::Equals( 579 EXPECT_TRUE(base::Value::Equals(
549 base::test::ParseJson("[ null, null, null ]").get(), actual_array.get())); 580 base::test::ParseJson("[ null, null, null ]").get(), actual_array.get()));
550 } 581 }
551 582
583 TEST_F(V8ValueConverterImplTest, ObjectsWithClashingIdentityHash) {
584 v8::Context::Scope context_scope(context_);
585 v8::HandleScope handle_scope;
586 V8ValueConverterImpl converter;
587
588 // We check that the converter checks identity correctly by disabling the
589 // optimization of using identity hashes.
590 ScopedAvoidIdentityHashForTesting scoped_hash_avoider(&converter);
591
592 // Create the v8::Object to be converted.
593 v8::Handle<v8::Array> root(v8::Array::New(4));
594 root->Set(0, v8::Handle<v8::Object>(v8::Object::New()));
595 root->Set(1, v8::Handle<v8::Object>(v8::Object::New()));
596 root->Set(2, v8::Handle<v8::Object>(v8::Array::New(0)));
597 root->Set(3, v8::Handle<v8::Object>(v8::Array::New(0)));
598
599 // The expected base::Value result.
600 scoped_ptr<base::Value> expected = base::test::ParseJson("[{},{},[],[]]");
601 ASSERT_TRUE(expected.get());
602
603 // The actual result.
604 scoped_ptr<base::Value> value(converter.FromV8Value(root, context_));
605 ASSERT_TRUE(value.get());
606
607 EXPECT_TRUE(expected->Equals(value.get()));
608 }
609
610 TEST_F(V8ValueConverterImplTest, DetectCycles) {
vabr (Chromium) 2013/03/15 14:37:45 If this test does not succeed, it will most likely
611 v8::Context::Scope context_scope(context_);
612 v8::HandleScope handle_scope;
613 V8ValueConverterImpl converter;
614
615 // Create a recursive array.
616 v8::Handle<v8::Array> recursive_array(v8::Array::New(1));
617 recursive_array->Set(0, recursive_array);
618
619 // The first repetition should be trimmed and replaced by a null value.
620 base::ListValue expected_list;
621 expected_list.Append(base::Value::CreateNullValue());
622
623 // The actual result.
624 scoped_ptr<base::Value> actual_list(
625 converter.FromV8Value(recursive_array, context_));
626 ASSERT_TRUE(actual_list.get());
627
628 EXPECT_TRUE(expected_list.Equals(actual_list.get()));
629
630 // Now create a recursive object
631 const std::string key("key");
632 v8::Handle<v8::Object> recursive_object(v8::Object::New());
633 v8::TryCatch try_catch;
634 recursive_object->Set(v8::String::New(key.c_str(), key.length()),
635 recursive_object);
636 ASSERT_FALSE(try_catch.HasCaught());
637
638 // The first repetition should be trimmed and replaced by a null value.
639 base::DictionaryValue expected_dictionary;
640 expected_dictionary.Set(key, base::Value::CreateNullValue());
641
642 // The actual result.
643 scoped_ptr<base::Value> actual_dictionary(
644 converter.FromV8Value(recursive_object, context_));
645 ASSERT_TRUE(actual_dictionary.get());
646
647 EXPECT_TRUE(expected_dictionary.Equals(actual_dictionary.get()));
648 }
649
552 } // namespace content 650 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/v8_value_converter_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698