15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/test/values_test_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/v8_value_converter_impl.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "v8/include/v8.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To improve the performance of 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// V8ValueConverterImpl::UpdateAndCheckUniqueness, identity hashes of objects 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// are used during checking for duplicates. For testing purposes we need to 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ignore the hash sometimes. Create this helper object to avoid using identity 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// hashes for the lifetime of the helper. 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ScopedAvoidIdentityHashForTesting { 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The hashes will be ignored in |converter|, which must not be NULL and it 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // must outlive the created instance of this helper. 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit ScopedAvoidIdentityHashForTesting( 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::V8ValueConverterImpl* converter); 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~ScopedAvoidIdentityHashForTesting(); 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::V8ValueConverterImpl* converter_; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ScopedAvoidIdentityHashForTesting); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedAvoidIdentityHashForTesting::ScopedAvoidIdentityHashForTesting( 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::V8ValueConverterImpl* converter) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : converter_(converter) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(converter_); 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) converter_->avoid_identity_hash_for_testing_ = true; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ScopedAvoidIdentityHashForTesting::~ScopedAvoidIdentityHashForTesting() { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) converter_->avoid_identity_hash_for_testing_ = false; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class V8ValueConverterImplTest : public testing::Test { 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) V8ValueConverterImplTest() 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : isolate_(v8::Isolate::GetCurrent()) { 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_); 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) context_.Reset(isolate_, v8::Context::New(isolate_, NULL, global)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) context_.Reset(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string GetString(base::DictionaryValue* value, const std::string& key) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string temp; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->GetString(key, &temp)) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return temp; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetString(v8::Handle<v8::Object> value, const std::string& key) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::String> temp = 75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value->Get(v8::String::NewFromUtf8(isolate_, key.c_str())) 76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) .As<v8::String>(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp.IsEmpty()) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::String::Utf8Value utf8(temp); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(*utf8, utf8.length()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string GetString(base::ListValue* value, uint32 index) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string temp; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->GetString(static_cast<size_t>(index), &temp)) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return temp; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string GetString(v8::Handle<v8::Array> value, uint32 index) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::String> temp = value->Get(index).As<v8::String>(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (temp.IsEmpty()) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return std::string(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::String::Utf8Value utf8(temp); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(*utf8, utf8.length()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsNull(base::DictionaryValue* value, const std::string& key) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* child = NULL; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->Get(key, &child)) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return child->GetType() == base::Value::TYPE_NULL; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsNull(v8::Handle<v8::Object> value, const std::string& key) { 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Value> child = 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) value->Get(v8::String::NewFromUtf8(isolate_, key.c_str())); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child.IsEmpty()) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return child->IsNull(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool IsNull(base::ListValue* value, uint32 index) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* child = NULL; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!value->Get(static_cast<size_t>(index), &child)) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return child->GetType() == base::Value::TYPE_NULL; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsNull(v8::Handle<v8::Array> value, uint32 index) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Value> child = value->Get(index); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (child.IsEmpty()) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ADD_FAILURE(); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return child->IsNull(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestWeirdType(const V8ValueConverterImpl& converter, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Value> val, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Value::Type expected_type, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> expected_value) { 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> raw(converter.FromV8Value(val, context)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (expected_value) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(raw.get()); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(expected_value->Equals(raw.get())); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_type, raw->GetType()); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(raw.get()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::Object> object(v8::Object::New(isolate_)); 158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) object->Set(v8::String::NewFromUtf8(isolate_, "test"), val); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> dictionary( 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<base::DictionaryValue*>( 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context))); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dictionary.get()); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (expected_value) { 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* temp = NULL; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(dictionary->Get("test", &temp)); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_type, temp->GetType()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(expected_value->Equals(temp)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(dictionary->HasKey("test")); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Array> array(v8::Array::New(isolate_)); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array->Set(0, val); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> list( 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<base::ListValue*>(converter.FromV8Value(array, context))); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(list.get()); 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (expected_value) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* temp = NULL; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(list->Get(0, &temp)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(expected_type, temp->GetType()); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(expected_value->Equals(temp)); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Arrays should preserve their length, and convert unconvertible 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // types into null. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value* temp = NULL; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(list->Get(0, &temp)); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(base::Value::TYPE_NULL, temp->GetType()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Isolate* isolate_; 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Context for the JavaScript in the test. 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Persistent<v8::Context> context_; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, BasicRoundTrip) { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> original_root = base::test::ParseJson( 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "{ \n" 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"null\": null, \n" 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"true\": true, \n" 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"false\": false, \n" 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"positive-int\": 42, \n" 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"negative-int\": -42, \n" 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"zero\": 0, \n" 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"double\": 88.8, \n" 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"big-integral-double\": 9007199254740992.0, \n" // 2.0^53 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"string\": \"foobar\", \n" 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"empty-string\": \"\", \n" 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"dictionary\": { \n" 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"foo\": \"bar\",\n" 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"hot\": \"dog\",\n" 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " }, \n" 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"empty-dictionary\": {}, \n" 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"list\": [ \"monkey\", \"balls\" ], \n" 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"empty-list\": [], \n" 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "}"); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> v8_object = 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.ToV8Value(original_root.get(), context).As<v8::Object>(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(v8_object.IsEmpty()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(static_cast<const base::DictionaryValue&>(*original_root).size(), 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v8_object->GetPropertyNames()->Length()); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE( 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "null"))->IsNull()); 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "true"))->IsTrue()); 236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "false"))->IsFalse()); 238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "positive-int")) 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->IsInt32()); 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "negative-int")) 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->IsInt32()); 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "zero"))->IsInt32()); 244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "double"))->IsNumber()); 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8( 247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) isolate_, "big-integral-double"))->IsNumber()); 248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "string"))->IsString()); 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty-string")) 251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->IsString()); 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "dictionary")) 253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->IsObject()); 254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8( 255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) isolate_, "empty-dictionary"))->IsObject()); 256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE( 257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8_object->Get(v8::String::NewFromUtf8(isolate_, "list"))->IsArray()); 258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) EXPECT_TRUE(v8_object->Get(v8::String::NewFromUtf8(isolate_, "empty-list")) 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->IsArray()); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> new_root(converter.FromV8Value(v8_object, context)); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_NE(original_root.get(), new_root.get()); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(original_root->Equals(new_root.get())); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, KeysWithDots) { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> original = 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::test::ParseJson("{ \"foo.bar\": \"baz\" }"); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> copy( 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converter.FromV8Value( 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.ToV8Value(original.get(), context), context)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(original->Equals(copy.get())); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, ObjectExceptions) { 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up objects to throw when reading or writing 'foo'. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Object.prototype.__defineSetter__('foo', " 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " function() { throw new Error('muah!'); });" 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Object.prototype.__defineGetter__('foo', " 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " function() { throw new Error('muah!'); });"; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 297a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) script->Run(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Object> object(v8::Object::New(isolate_)); 301a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) object->Set(v8::String::NewFromUtf8(isolate_, "bar"), 302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::String::NewFromUtf8(isolate_, "bar")); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converting from v8 value should replace the foo property with null. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> converted( 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<base::DictionaryValue*>( 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context))); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(converted.get()); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/v8/issues/detail?id=1342 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_EQ(2u, converted->size()); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EXPECT_TRUE(IsNull(converted.get(), "foo")); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1u, converted->size()); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("bar", GetString(converted.get(), "bar")); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converting to v8 value should drop the foo property. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converted->SetString("foo", "foo"); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> copy = 319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.ToV8Value(converted.get(), context).As<v8::Object>(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(copy.IsEmpty()); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, copy->GetPropertyNames()->Length()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("bar", GetString(copy, "bar")); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, ArrayExceptions) { 326868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 328868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var arr = [];" 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "arr.__defineSetter__(0, " 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " function() { throw new Error('muah!'); });" 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "arr.__defineGetter__(0, " 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " function() { throw new Error('muah!'); });" 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "arr[1] = 'bar';" 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return arr;" 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(array.IsEmpty()); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converting from v8 value should replace the first item with null. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> converted(static_cast<base::ListValue*>( 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(array, context))); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(converted.get()); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://code.google.com/p/v8/issues/detail?id=1342 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, converted->GetSize()); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsNull(converted.get(), 0)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Converting to v8 value should drop the first item and leave a hole. 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) converted.reset(static_cast<base::ListValue*>( 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::test::ParseJson("[ \"foo\", \"bar\" ]").release())); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Array> copy = 359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.ToV8Value(converted.get(), context).As<v8::Array>(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(copy.IsEmpty()); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, copy->Length()); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("bar", GetString(copy, 1)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, WeirdTypes) { 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 367a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Local<v8::Context> context = 368a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 369a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 371a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::RegExp> regex(v8::RegExp::New( 372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::String::NewFromUtf8(isolate_, "."), v8::RegExp::kNone)); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWeirdType(converter, 376a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Undefined(isolate_), 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_NULL, // Arbitrary type, result is NULL. 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_ptr<base::Value>()); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWeirdType(converter, 380a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Date::New(isolate_, 1000), 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_DICTIONARY, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>(new base::DictionaryValue())); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWeirdType(converter, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regex, 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_DICTIONARY, 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>(new base::DictionaryValue())); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converter.SetDateAllowed(true); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWeirdType(converter, 390a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Date::New(isolate_, 1000), 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_DOUBLE, 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>(new base::FundamentalValue(1.0))); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converter.SetRegExpAllowed(true); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestWeirdType(converter, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) regex, 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Value::TYPE_STRING, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>(new base::StringValue("/./"))); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, Prototype) { 402868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 403868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 405a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Object.prototype.foo = 'foo';" 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return {};" 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(object.IsEmpty()); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result( 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<base::DictionaryValue*>( 420868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context))); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result.get()); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, result->size()); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, StripNullFromObjects) { 426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 427868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 429a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return { foo: undefined, bar: null };" 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 436a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(object.IsEmpty()); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) converter.SetStripNullFromObjects(true); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> result( 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<base::DictionaryValue*>( 445868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context))); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result.get()); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0u, result->size()); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, RecursiveObjects) { 451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 452868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 453868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::Object> object = v8::Object::New(isolate_).As<v8::Object>(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(object.IsEmpty()); 460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) object->Set(v8::String::NewFromUtf8(isolate_, "foo"), 461a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::String::NewFromUtf8(isolate_, "bar")); 462a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) object->Set(v8::String::NewFromUtf8(isolate_, "obj"), object); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::DictionaryValue> object_result( 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<base::DictionaryValue*>( 466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context))); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(object_result.get()); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, object_result->size()); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsNull(object_result.get(), "obj")); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Array> array = v8::Array::New(isolate_).As<v8::Array>(); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(array.IsEmpty()); 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) array->Set(0, v8::String::NewFromUtf8(isolate_, "1")); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array->Set(1, array); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> list_result( 477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<base::ListValue*>(converter.FromV8Value(array, context))); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(list_result.get()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, list_result->GetSize()); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsNull(list_result.get(), 1)); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, WeirdProperties) { 484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 485868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 486868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return {" 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "1: 'foo'," 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "'2': 'bar'," 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "true: 'baz'," 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "false: 'qux'," 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "null: 'quux'," 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "undefined: 'oops'" 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "};" 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 500a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> object = script->Run().As<v8::Object>(); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(object.IsEmpty()); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> actual(converter.FromV8Value(object, context)); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> expected = base::test::ParseJson( 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "{ \n" 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"1\": \"foo\", \n" 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"2\": \"bar\", \n" 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"true\": \"baz\", \n" 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"false\": \"qux\", \n" 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"null\": \"quux\", \n" 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) " \"undefined\": \"oops\", \n" 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "}"); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(expected->Equals(actual.get())); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, ArrayGetters) { 522868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 523868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 524868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 525a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "var a = [0];" 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "a.__defineGetter__(1, function() { return 'bar'; });" 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return a;" 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 533a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 534a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Array> array = script->Run().As<v8::Array>(); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(array.IsEmpty()); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::ListValue> result( 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) static_cast<base::ListValue*>(converter.FromV8Value(array, context))); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(result.get()); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(2u, result->GetSize()); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, UndefinedValueBehavior) { 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 547868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 549a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Object> object; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return { foo: undefined, bar: null, baz: function(){} };" 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 556a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 557a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object = script->Run().As<v8::Object>(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(object.IsEmpty()); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v8::Handle<v8::Array> array; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* source = "(function() {" 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "return [ undefined, null, function(){} ];" 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "})();"; 567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Script> script( 568a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array = script->Run().As<v8::Array>(); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(array.IsEmpty()); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch v8::Handle<v8::Array> sparse_array; 5740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch { 5750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const char* source = "(function() {" 5760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "return new Array(3);" 5770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "})();"; 5780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch v8::Handle<v8::Script> script( 5790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch v8::Script::Compile(v8::String::NewFromUtf8(isolate_, source))); 5800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sparse_array = script->Run().As<v8::Array>(); 5810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ASSERT_FALSE(sparse_array.IsEmpty()); 5820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 5830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) V8ValueConverterImpl converter; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> actual_object( 587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(object, context)); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(base::Value::Equals( 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::test::ParseJson("{ \"bar\": null }").get(), actual_object.get())); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Everything is null because JSON stringification preserves array length. 5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<base::Value> actual_array(converter.FromV8Value(array, context)); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(base::Value::Equals( 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::test::ParseJson("[ null, null, null ]").get(), actual_array.get())); 5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 5960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch scoped_ptr<base::Value> actual_sparse_array( 5970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch converter.FromV8Value(sparse_array, context)); 5980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EXPECT_TRUE( 5990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Value::Equals(base::test::ParseJson("[ null, null, null ]").get(), 6000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch actual_sparse_array.get())); 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(V8ValueConverterImplTest, ObjectsWithClashingIdentityHash) { 604868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) V8ValueConverterImpl converter; 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We check that the converter checks identity correctly by disabling the 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // optimization of using identity hashes. 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedAvoidIdentityHashForTesting scoped_hash_avoider(&converter); 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create the v8::Object to be converted. 615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Array> root(v8::Array::New(isolate_, 4)); 616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root->Set(0, v8::Handle<v8::Object>(v8::Object::New(isolate_))); 617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root->Set(1, v8::Handle<v8::Object>(v8::Object::New(isolate_))); 618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root->Set(2, v8::Handle<v8::Object>(v8::Array::New(isolate_, 0))); 619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) root->Set(3, v8::Handle<v8::Object>(v8::Array::New(isolate_, 0))); 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The expected base::Value result. 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> expected = base::test::ParseJson("[{},{},[],[]]"); 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(expected.get()); 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The actual result. 626868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> value(converter.FromV8Value(root, context)); 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(value.get()); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(expected->Equals(value.get())); 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(V8ValueConverterImplTest, DetectCycles) { 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 635868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) V8ValueConverterImpl converter; 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a recursive array. 640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Handle<v8::Array> recursive_array(v8::Array::New(isolate_, 1)); 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) recursive_array->Set(0, recursive_array); 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The first repetition should be trimmed and replaced by a null value. 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue expected_list; 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_list.Append(base::Value::CreateNullValue()); 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The actual result. 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> actual_list( 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(recursive_array, context)); 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(actual_list.get()); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(expected_list.Equals(actual_list.get())); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now create a recursive object 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string key("key"); 6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::Object> recursive_object(v8::Object::New(isolate_)); 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) v8::TryCatch try_catch; 658a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) recursive_object->Set( 659a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::String::NewFromUtf8( 660a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) isolate_, key.c_str(), v8::String::kNormalString, key.length()), 661a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) recursive_object); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_FALSE(try_catch.HasCaught()); 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The first repetition should be trimmed and replaced by a null value. 6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::DictionaryValue expected_dictionary; 6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expected_dictionary.Set(key, base::Value::CreateNullValue()); 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The actual result. 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> actual_dictionary( 670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) converter.FromV8Value(recursive_object, context)); 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(actual_dictionary.get()); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(expected_dictionary.Equals(actual_dictionary.get())); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 676868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)TEST_F(V8ValueConverterImplTest, MaxRecursionDepth) { 677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::HandleScope handle_scope(isolate_); 678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context> context = 679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Context>::New(isolate_, context_); 680a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) v8::Context::Scope context_scope(context); 681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Must larger than kMaxRecursionDepth in v8_value_converter_impl.cc. 683d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int kDepth = 1000; 684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const char kKey[] = "key"; 685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Local<v8::Object> deep_object = v8::Object::New(isolate_); 687868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) v8::Local<v8::Object> leaf = deep_object; 689868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (int i = 0; i < kDepth; ++i) { 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Local<v8::Object> new_object = v8::Object::New(isolate_); 691a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) leaf->Set(v8::String::NewFromUtf8(isolate_, kKey), new_object); 692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) leaf = new_object; 693868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 695868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) V8ValueConverterImpl converter; 696868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::Value> value(converter.FromV8Value(deep_object, context)); 697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(value); 698868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 699868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Expected depth is kMaxRecursionDepth in v8_value_converter_impl.cc. 700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int kExpectedDepth = 100; 701868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Value* current = value.get(); 703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (int i = 1; i < kExpectedDepth; ++i) { 704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::DictionaryValue* current_as_object = NULL; 705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(current->GetAsDictionary(¤t_as_object)) << i; 706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ASSERT_TRUE(current_as_object->Get(kKey, ¤t)) << i; 707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 708868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // The leaf node shouldn't have any properties. 710868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::DictionaryValue empty; 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_TRUE(base::Value::Equals(&empty, current)) << *current; 712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 713868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass V8ValueConverterOverridingStrategyForTesting 7155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : public V8ValueConverter::Strategy { 7165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 7175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu V8ValueConverterOverridingStrategyForTesting() 7185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : reference_value_(NewReferenceValue()) {} 7195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Object( 7205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Object> value, 7215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out, 7225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Isolate* isolate, 7235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const FromV8ValueCallback& callback) const OVERRIDE { 7245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = NewReferenceValue(); 7255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Array(v8::Handle<v8::Array> value, 7285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out, 7295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Isolate* isolate, 7305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const FromV8ValueCallback& callback) const OVERRIDE { 7315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = NewReferenceValue(); 7325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8ArrayBuffer(v8::Handle<v8::Object> value, 735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Value** out, 736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) v8::Isolate* isolate) const OVERRIDE { 7375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = NewReferenceValue(); 7385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Number(v8::Handle<v8::Number> value, 7415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out) const OVERRIDE { 7425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = NewReferenceValue(); 7435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Undefined(base::Value** out) const OVERRIDE { 7465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *out = NewReferenceValue(); 7475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 7485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value* reference_value() const { return reference_value_.get(); } 7505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private: 7525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu static base::Value* NewReferenceValue() { 7535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return new base::StringValue("strategy"); 7545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 7555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> reference_value_; 7565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 7575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(V8ValueConverterImplTest, StrategyOverrides) { 7595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::HandleScope handle_scope(isolate_); 7605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Local<v8::Context> context = 7615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Local<v8::Context>::New(isolate_, context_); 7625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Context::Scope context_scope(context); 7635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu V8ValueConverterImpl converter; 7655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu V8ValueConverterOverridingStrategyForTesting strategy; 7665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.SetStrategy(&strategy); 7675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Object> object(v8::Object::New(isolate_)); 7695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> object_value(converter.FromV8Value(object, context)); 7705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(object_value); 7715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 7725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(strategy.reference_value(), object_value.get())); 7735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Array> array(v8::Array::New(isolate_)); 7755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> array_value(converter.FromV8Value(array, context)); 7765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(array_value); 7775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 7785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(strategy.reference_value(), array_value.get())); 7795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::ArrayBuffer> array_buffer(v8::ArrayBuffer::New(isolate_, 0)); 7815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> array_buffer_value( 7825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.FromV8Value(array_buffer, context)); 7835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(array_buffer_value); 7845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(base::Value::Equals(strategy.reference_value(), 7855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu array_buffer_value.get())); 7865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::ArrayBufferView> array_buffer_view( 7885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Uint8Array::New(array_buffer, 0, 0)); 7895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> array_buffer_view_value( 7905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.FromV8Value(array_buffer_view, context)); 7915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(array_buffer_view_value); 7925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE(base::Value::Equals(strategy.reference_value(), 7935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu array_buffer_view_value.get())); 7945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 7955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Number> number(v8::Number::New(isolate_, 0.0)); 7965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> number_value(converter.FromV8Value(number, context)); 7975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(number_value); 7985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 7995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(strategy.reference_value(), number_value.get())); 8005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Primitive> undefined(v8::Undefined(isolate_)); 8025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> undefined_value( 8035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.FromV8Value(undefined, context)); 8045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(undefined_value); 8055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 8065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(strategy.reference_value(), undefined_value.get())); 8075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 8085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass V8ValueConverterBypassStrategyForTesting 8105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : public V8ValueConverter::Strategy { 8115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public: 8125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Object( 8135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Object> value, 8145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out, 8155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Isolate* isolate, 8165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const FromV8ValueCallback& callback) const OVERRIDE { 8175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Array(v8::Handle<v8::Array> value, 8205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out, 8215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Isolate* isolate, 8225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const FromV8ValueCallback& callback) const OVERRIDE { 8235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8ArrayBuffer(v8::Handle<v8::Object> value, 826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Value** out, 827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) v8::Isolate* isolate) const OVERRIDE { 8285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Number(v8::Handle<v8::Number> value, 8315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value** out) const OVERRIDE { 8325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool FromV8Undefined(base::Value** out) const OVERRIDE { 8355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 8365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 8375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 8385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Verify that having a strategy that fallbacks to default behaviour 8405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// actually preserves it. 8415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_F(V8ValueConverterImplTest, StrategyBypass) { 8425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::HandleScope handle_scope(isolate_); 8435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Local<v8::Context> context = 8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Local<v8::Context>::New(isolate_, context_); 8455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Context::Scope context_scope(context); 8465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu V8ValueConverterImpl converter; 8485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu V8ValueConverterBypassStrategyForTesting strategy; 8495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.SetStrategy(&strategy); 8505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Object> object(v8::Object::New(isolate_)); 8525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> object_value(converter.FromV8Value(object, context)); 8535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(object_value); 8545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> reference_object_value(base::test::ParseJson("{}")); 8555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 8565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(reference_object_value.get(), object_value.get())); 8575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Array> array(v8::Array::New(isolate_)); 8595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> array_value(converter.FromV8Value(array, context)); 8605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(array_value); 8615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> reference_array_value(base::test::ParseJson("[]")); 8625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 8635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(reference_array_value.get(), array_value.get())); 8645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Not testing ArrayBuffers as V8ValueConverter uses blink helpers and 8665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // this requires having blink to be initialized. 8675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Number> number(v8::Number::New(isolate_, 0.0)); 8695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> number_value(converter.FromV8Value(number, context)); 8705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ASSERT_TRUE(number_value); 8715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> reference_number_value(base::test::ParseJson("0")); 8725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_TRUE( 8735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::Value::Equals(reference_number_value.get(), number_value.get())); 8745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu v8::Handle<v8::Primitive> undefined(v8::Undefined(isolate_)); 8765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu scoped_ptr<base::Value> undefined_value( 8775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu converter.FromV8Value(undefined, context)); 8785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu EXPECT_FALSE(undefined_value); 8795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 8805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 882