summaryrefslogtreecommitdiffstats
path: root/content/renderer/v8_value_converter_impl_unittest.cc
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-16 21:57:37 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-16 21:57:37 +0000
commit217d956794a8a5fb28cf6de2232c07db3de1eb91 (patch)
tree7de12e48f93401ab723203c5ebfeccdfda95bab6 /content/renderer/v8_value_converter_impl_unittest.cc
parent70d19da03e8edc5610bc5c8fff5cc1fbca5e37c8 (diff)
downloadchromium_src-217d956794a8a5fb28cf6de2232c07db3de1eb91.zip
chromium_src-217d956794a8a5fb28cf6de2232c07db3de1eb91.tar.gz
chromium_src-217d956794a8a5fb28cf6de2232c07db3de1eb91.tar.bz2
Revert 146891 - Revert 146852 - Forces V8ValueConverter to switch context when converting objects.
[The speculative revert was WRONG; test was just flaky.] Objects passed into the V8ValueConverter may have fields that reference objects in a v8::Context different than the one that was passed in. This is very common for objects that were created in an isolated world and reference globals in that world (such as window). This fix will check to see if the current v8::Context is the same as the converting objects CreationContext(). If they are different, they will be swaped during the object's conversion. In addition, the V8ValueConverter has been expanded to have the ability to omit duplicate fileds in an object. This is very important when something with a graph structure (like a DOM node) is converted. Extra checks for integer/string fields have been added as in respone to Jakob's observation: https://code.google.com/p/chromium/issues/detail?id=134661#c5 BUG=134661, 135104 TEST=content_unittests::V8ValueConverterImplTest.RecursiveObject Review URL: https://chromiumcodereview.appspot.com/10704030 TBR=eaugusti@chromium.org Review URL: https://chromiumcodereview.appspot.com/10789024 TBR=erg@google.com Review URL: https://chromiumcodereview.appspot.com/10794002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146903 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/v8_value_converter_impl_unittest.cc')
-rw-r--r--content/renderer/v8_value_converter_impl_unittest.cc72
1 files changed, 72 insertions, 0 deletions
diff --git a/content/renderer/v8_value_converter_impl_unittest.cc b/content/renderer/v8_value_converter_impl_unittest.cc
index a56941a..a4e461f 100644
--- a/content/renderer/v8_value_converter_impl_unittest.cc
+++ b/content/renderer/v8_value_converter_impl_unittest.cc
@@ -113,6 +113,7 @@ class V8ValueConverterImplTest : public testing::Test {
static_cast<DictionaryValue*>(
converter.FromV8Value(object, context_)));
ASSERT_TRUE(dictionary.get());
+
Value* temp = NULL;
ASSERT_TRUE(dictionary->Get("test", &temp));
EXPECT_EQ(expected_type, temp->GetType());
@@ -346,3 +347,74 @@ TEST_F(V8ValueConverterImplTest, StripNullFromObjects) {
ASSERT_TRUE(result.get());
EXPECT_EQ(0u, result->size());
}
+
+TEST_F(V8ValueConverterImplTest, RecursiveObjects) {
+ v8::Context::Scope context_scope(context_);
+ v8::HandleScope handle_scope;
+
+ V8ValueConverterImpl converter;
+
+ v8::Handle<v8::Object> object = v8::Object::New().As<v8::Object>();
+ ASSERT_FALSE(object.IsEmpty());
+ object->Set(v8::String::New("foo"), v8::String::New("bar"));
+ object->Set(v8::String::New("obj"), object);
+
+ scoped_ptr<DictionaryValue> object_result(
+ static_cast<DictionaryValue*>(converter.FromV8Value(object, context_)));
+ ASSERT_TRUE(object_result.get());
+ EXPECT_EQ(2u, object_result->size());
+ EXPECT_TRUE(IsNull(object_result.get(), "obj"));
+
+ v8::Handle<v8::Array> array = v8::Array::New().As<v8::Array>();
+ ASSERT_FALSE(array.IsEmpty());
+ array->Set(0, v8::String::New("1"));
+ array->Set(1, array);
+
+ scoped_ptr<ListValue> list_result(
+ static_cast<ListValue*>(converter.FromV8Value(array, context_)));
+ ASSERT_TRUE(list_result.get());
+ EXPECT_EQ(2u, list_result->GetSize());
+ EXPECT_TRUE(IsNull(list_result.get(), 1));
+}
+
+TEST_F(V8ValueConverterImplTest, ObjectGetters) {
+ v8::Context::Scope context_scope(context_);
+ v8::HandleScope handle_scope;
+
+ const char* source = "(function() {"
+ "var a = {};"
+ "a.__defineGetter__('foo', function() { return 'bar'; });"
+ "return a;"
+ "})();";
+
+ v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source)));
+ v8::Handle<v8::Object> object = script->Run().As<v8::Object>();
+ ASSERT_FALSE(object.IsEmpty());
+
+ V8ValueConverterImpl converter;
+ scoped_ptr<DictionaryValue> result(
+ static_cast<DictionaryValue*>(converter.FromV8Value(object, context_)));
+ ASSERT_TRUE(result.get());
+ EXPECT_EQ(1u, result->size());
+}
+
+TEST_F(V8ValueConverterImplTest, ArrayGetters) {
+ v8::Context::Scope context_scope(context_);
+ v8::HandleScope handle_scope;
+
+ const char* source = "(function() {"
+ "var a = [0];"
+ "a.__defineGetter__(1, function() { return 'bar'; });"
+ "return a;"
+ "})();";
+
+ v8::Handle<v8::Script> script(v8::Script::New(v8::String::New(source)));
+ v8::Handle<v8::Array> array = script->Run().As<v8::Array>();
+ ASSERT_FALSE(array.IsEmpty());
+
+ V8ValueConverterImpl converter;
+ scoped_ptr<ListValue> result(
+ static_cast<ListValue*>(converter.FromV8Value(array, context_)));
+ ASSERT_TRUE(result.get());
+ EXPECT_EQ(2u, result->GetSize());
+}