| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "gin/arguments.h" | 6 #include "gin/arguments.h" |
| 7 #include "gin/handle.h" | 7 #include "gin/handle.h" |
| 8 #include "gin/object_template_builder.h" | 8 #include "gin/object_template_builder.h" |
| 9 #include "gin/per_isolate_data.h" | 9 #include "gin/per_isolate_data.h" |
| 10 #include "gin/public/isolate_holder.h" | 10 #include "gin/public/isolate_holder.h" |
| 11 #include "gin/test/v8_test.h" | 11 #include "gin/test/v8_test.h" |
| 12 #include "gin/try_catch.h" | 12 #include "gin/try_catch.h" |
| 13 #include "gin/wrappable.h" | 13 #include "gin/wrappable.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 namespace gin { | 16 namespace gin { |
| 17 | 17 |
| 18 class MyObject : public Wrappable<MyObject> { | 18 class MyObject : public Wrappable<MyObject> { |
| 19 public: | 19 public: |
| 20 static WrapperInfo kWrapperInfo; | 20 static WrapperInfo kWrapperInfo; |
| 21 | 21 |
| 22 static v8::Local<v8::ObjectTemplate> GetObjectTemplate(v8::Isolate* isolate); |
| 23 |
| 22 static gin::Handle<MyObject> Create(v8::Isolate* isolate) { | 24 static gin::Handle<MyObject> Create(v8::Isolate* isolate) { |
| 23 return CreateHandle(isolate, new MyObject()); | 25 return CreateHandle(isolate, new MyObject()); |
| 24 } | 26 } |
| 25 | 27 |
| 26 int value() const { return value_; } | 28 int value() const { return value_; } |
| 27 void set_value(int value) { value_ = value; } | 29 void set_value(int value) { value_ = value; } |
| 28 | 30 |
| 29 private: | 31 private: |
| 30 MyObject() : value_(0) {} | 32 MyObject() : value_(0) {} |
| 31 virtual ~MyObject() {} | 33 virtual ~MyObject() {} |
| 32 | 34 |
| 33 int value_; | 35 int value_; |
| 34 }; | 36 }; |
| 35 | 37 |
| 36 class MyObject2 : public Wrappable<MyObject2> { | 38 class MyObject2 : public Wrappable<MyObject2> { |
| 37 public: | 39 public: |
| 38 static WrapperInfo kWrapperInfo; | 40 static WrapperInfo kWrapperInfo; |
| 39 }; | 41 }; |
| 40 | 42 |
| 41 class MyObjectBlink : public Wrappable<MyObjectBlink> { | 43 class MyObjectBlink : public Wrappable<MyObjectBlink> { |
| 42 public: | 44 public: |
| 43 static WrapperInfo kWrapperInfo; | 45 static WrapperInfo kWrapperInfo; |
| 44 }; | 46 }; |
| 45 | 47 |
| 46 WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin }; | 48 WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin }; |
| 49 v8::Local<v8::ObjectTemplate> MyObject::GetObjectTemplate( |
| 50 v8::Isolate* isolate) { |
| 51 return ObjectTemplateBuilder(isolate) |
| 52 .SetProperty("value", &MyObject::value, &MyObject::set_value) |
| 53 .Build(); |
| 54 } |
| 55 |
| 47 WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin }; | 56 WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin }; |
| 48 WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin }; | 57 WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin }; |
| 49 | 58 |
| 50 void RegisterTemplates(v8::Isolate* isolate) { | |
| 51 PerIsolateData* data = PerIsolateData::From(isolate); | |
| 52 DCHECK(data->GetObjectTemplate(&MyObject::kWrapperInfo).IsEmpty()); | |
| 53 | |
| 54 v8::Handle<v8::ObjectTemplate> templ = ObjectTemplateBuilder(isolate) | |
| 55 .SetProperty("value", &MyObject::value, &MyObject::set_value) | |
| 56 .Build(); | |
| 57 templ->SetInternalFieldCount(kNumberOfInternalFields); | |
| 58 data->SetObjectTemplate(&MyObject::kWrapperInfo, templ); | |
| 59 | |
| 60 templ = v8::ObjectTemplate::New(isolate); | |
| 61 templ->SetInternalFieldCount(kNumberOfInternalFields); | |
| 62 data->SetObjectTemplate(&MyObject2::kWrapperInfo, templ); | |
| 63 | |
| 64 templ = v8::ObjectTemplate::New(isolate); | |
| 65 templ->SetInternalFieldCount(kNumberOfInternalFields); | |
| 66 data->SetObjectTemplate(&MyObjectBlink::kWrapperInfo, templ); | |
| 67 } | |
| 68 | |
| 69 typedef V8Test WrappableTest; | 59 typedef V8Test WrappableTest; |
| 70 | 60 |
| 71 TEST_F(WrappableTest, WrapAndUnwrap) { | 61 TEST_F(WrappableTest, WrapAndUnwrap) { |
| 72 v8::Isolate* isolate = instance_->isolate(); | 62 v8::Isolate* isolate = instance_->isolate(); |
| 73 v8::HandleScope handle_scope(isolate); | 63 v8::HandleScope handle_scope(isolate); |
| 74 | 64 |
| 75 RegisterTemplates(isolate); | |
| 76 Handle<MyObject> obj = MyObject::Create(isolate); | 65 Handle<MyObject> obj = MyObject::Create(isolate); |
| 77 | 66 |
| 78 v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, obj.get()); | 67 v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, obj.get()); |
| 79 EXPECT_FALSE(wrapper.IsEmpty()); | 68 EXPECT_FALSE(wrapper.IsEmpty()); |
| 80 | 69 |
| 81 MyObject* unwrapped = NULL; | 70 MyObject* unwrapped = NULL; |
| 82 EXPECT_TRUE(ConvertFromV8(isolate, wrapper, &unwrapped)); | 71 EXPECT_TRUE(ConvertFromV8(isolate, wrapper, &unwrapped)); |
| 83 EXPECT_EQ(obj.get(), unwrapped); | 72 EXPECT_EQ(obj.get(), unwrapped); |
| 84 } | 73 } |
| 85 | 74 |
| 86 TEST_F(WrappableTest, UnwrapFailures) { | 75 TEST_F(WrappableTest, UnwrapFailures) { |
| 87 v8::Isolate* isolate = instance_->isolate(); | 76 v8::Isolate* isolate = instance_->isolate(); |
| 88 v8::HandleScope handle_scope(isolate); | 77 v8::HandleScope handle_scope(isolate); |
| 89 | 78 |
| 90 RegisterTemplates(isolate); | |
| 91 | |
| 92 // Something that isn't an object. | 79 // Something that isn't an object. |
| 93 v8::Handle<v8::Value> thing = v8::Number::New(42); | 80 v8::Handle<v8::Value> thing = v8::Number::New(42); |
| 94 MyObject* unwrapped = NULL; | 81 MyObject* unwrapped = NULL; |
| 95 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); | 82 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| 96 EXPECT_FALSE(unwrapped); | 83 EXPECT_FALSE(unwrapped); |
| 97 | 84 |
| 98 // An object that's not wrapping anything. | 85 // An object that's not wrapping anything. |
| 99 thing = v8::Object::New(isolate); | 86 thing = v8::Object::New(isolate); |
| 100 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); | 87 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| 101 EXPECT_FALSE(unwrapped); | 88 EXPECT_FALSE(unwrapped); |
| 102 | 89 |
| 103 // An object that's wrapping a C++ object from Blink. | 90 // An object that's wrapping a C++ object from Blink. |
| 104 thing.Clear(); | 91 thing.Clear(); |
| 105 thing = ConvertToV8(isolate, new MyObjectBlink()); | 92 thing = ConvertToV8(isolate, new MyObjectBlink()); |
| 106 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); | 93 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| 107 EXPECT_FALSE(unwrapped); | 94 EXPECT_FALSE(unwrapped); |
| 108 | 95 |
| 109 // An object that's wrapping a C++ object of the wrong type. | 96 // An object that's wrapping a C++ object of the wrong type. |
| 110 thing.Clear(); | 97 thing.Clear(); |
| 111 thing = ConvertToV8(isolate, new MyObject2()); | 98 thing = ConvertToV8(isolate, new MyObject2()); |
| 112 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); | 99 EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); |
| 113 EXPECT_FALSE(unwrapped); | 100 EXPECT_FALSE(unwrapped); |
| 114 } | 101 } |
| 115 | 102 |
| 116 TEST_F(WrappableTest, GetAndSetProperty) { | 103 TEST_F(WrappableTest, GetAndSetProperty) { |
| 117 v8::Isolate* isolate = instance_->isolate(); | 104 v8::Isolate* isolate = instance_->isolate(); |
| 118 v8::HandleScope handle_scope(isolate); | 105 v8::HandleScope handle_scope(isolate); |
| 119 | 106 |
| 120 RegisterTemplates(isolate); | |
| 121 gin::Handle<MyObject> obj = MyObject::Create(isolate); | 107 gin::Handle<MyObject> obj = MyObject::Create(isolate); |
| 122 | 108 |
| 123 obj->set_value(42); | 109 obj->set_value(42); |
| 124 EXPECT_EQ(42, obj->value()); | 110 EXPECT_EQ(42, obj->value()); |
| 125 | 111 |
| 126 v8::Handle<v8::String> source = StringToV8(isolate, | 112 v8::Handle<v8::String> source = StringToV8(isolate, |
| 127 "(function (obj) {" | 113 "(function (obj) {" |
| 128 " if (obj.value !== 42) throw 'FAIL';" | 114 " if (obj.value !== 42) throw 'FAIL';" |
| 129 " else obj.value = 191; })"); | 115 " else obj.value = 191; })"); |
| 130 EXPECT_FALSE(source.IsEmpty()); | 116 EXPECT_FALSE(source.IsEmpty()); |
| 131 | 117 |
| 132 gin::TryCatch try_catch; | 118 gin::TryCatch try_catch; |
| 133 v8::Handle<v8::Script> script = v8::Script::New(source); | 119 v8::Handle<v8::Script> script = v8::Script::New(source); |
| 134 EXPECT_FALSE(script.IsEmpty()); | 120 EXPECT_FALSE(script.IsEmpty()); |
| 135 v8::Handle<v8::Value> val = script->Run(); | 121 v8::Handle<v8::Value> val = script->Run(); |
| 136 EXPECT_FALSE(val.IsEmpty()); | 122 EXPECT_FALSE(val.IsEmpty()); |
| 137 v8::Handle<v8::Function> func; | 123 v8::Handle<v8::Function> func; |
| 138 EXPECT_TRUE(ConvertFromV8(isolate, val, &func)); | 124 EXPECT_TRUE(ConvertFromV8(isolate, val, &func)); |
| 139 v8::Handle<v8::Value> argv[] = { | 125 v8::Handle<v8::Value> argv[] = { |
| 140 ConvertToV8(isolate, obj.get()), | 126 ConvertToV8(isolate, obj.get()), |
| 141 }; | 127 }; |
| 142 func->Call(v8::Undefined(isolate), 1, argv); | 128 func->Call(v8::Undefined(isolate), 1, argv); |
| 143 EXPECT_FALSE(try_catch.HasCaught()); | 129 EXPECT_FALSE(try_catch.HasCaught()); |
| 144 EXPECT_EQ("", try_catch.GetStackTrace()); | 130 EXPECT_EQ("", try_catch.GetStackTrace()); |
| 145 | 131 |
| 146 EXPECT_EQ(191, obj->value()); | 132 EXPECT_EQ(191, obj->value()); |
| 147 } | 133 } |
| 148 | 134 |
| 149 } // namespace gin | 135 } // namespace gin |
| OLD | NEW |