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
3 // found in the LICENSE file.
5 #include "base/logging.h"
6 #include "gin/arguments.h"
7 #include "gin/per_isolate_data.h"
8 #include "gin/public/isolate_holder.h"
9 #include "gin/test/v8_test.h"
10 #include "gin/wrappable.h"
11 #include "testing/gtest/include/gtest/gtest.h"
16 class MyObject
: public Wrappable
{
18 static scoped_refptr
<MyObject
> Create();
20 int value() const { return value_
; }
21 void set_value(int value
) { value_
= value
; }
23 static WrapperInfo kWrapperInfo
;
24 virtual WrapperInfo
* GetWrapperInfo() OVERRIDE
;
27 MyObject() : value_(0) {}
28 virtual ~MyObject() {}
33 WrapperInfo
MyObject::kWrapperInfo
= { kEmbedderNativeGin
};
35 scoped_refptr
<MyObject
> MyObject::Create() {
36 return make_scoped_refptr(new MyObject());
39 WrapperInfo
* MyObject::GetWrapperInfo() {
46 struct Converter
<MyObject
*> : public WrappableConverter
<MyObject
> {};
50 // TODO(abarth): This is too much typing.
52 void MyObjectGetValue(const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
56 CHECK(args
.Holder(&obj
));
58 args
.Return(obj
->value());
61 void MyObjectSetValue(const v8::FunctionCallbackInfo
<v8::Value
>& info
) {
65 CHECK(args
.Holder(&obj
));
68 if (!args
.GetNext(&val
))
69 return args
.ThrowError();
74 void RegisterTemplate(v8::Isolate
* isolate
) {
75 PerIsolateData
* data
= PerIsolateData::From(isolate
);
76 DCHECK(data
->GetObjectTemplate(&MyObject::kWrapperInfo
).IsEmpty());
78 v8::Handle
<v8::ObjectTemplate
> templ
= v8::ObjectTemplate::New(isolate
);
79 templ
->SetInternalFieldCount(kNumberOfInternalFields
);
80 templ
->SetAccessorProperty(
81 StringToSymbol(isolate
, "value"),
82 v8::FunctionTemplate::New(isolate
, MyObjectGetValue
),
83 v8::FunctionTemplate::New(isolate
, MyObjectSetValue
));
85 data
->SetObjectTemplate(&MyObject::kWrapperInfo
, templ
);
88 typedef V8Test WrappableTest
;
90 TEST_F(WrappableTest
, WrapAndUnwrap
) {
91 v8::Isolate
* isolate
= instance_
->isolate();
92 v8::HandleScope
handle_scope(isolate
);
94 RegisterTemplate(isolate
);
95 scoped_refptr
<MyObject
> obj
= MyObject::Create();
97 v8::Handle
<v8::Value
> wrapper
= ConvertToV8(isolate
, obj
.get());
98 EXPECT_FALSE(wrapper
.IsEmpty());
100 MyObject
* unwrapped
= 0;
101 EXPECT_TRUE(ConvertFromV8(isolate
, wrapper
, &unwrapped
));
102 EXPECT_EQ(obj
, unwrapped
);
105 TEST_F(WrappableTest
, GetAndSetProperty
) {
106 v8::Isolate
* isolate
= instance_
->isolate();
107 v8::HandleScope
handle_scope(isolate
);
109 RegisterTemplate(isolate
);
110 scoped_refptr
<MyObject
> obj
= MyObject::Create();
113 EXPECT_EQ(42, obj
->value());
115 v8::Handle
<v8::String
> source
= StringToV8(isolate
,
117 " if (obj.value !== 42) throw 'FAIL';"
118 " else obj.value = 191; })");
119 EXPECT_FALSE(source
.IsEmpty());
121 v8::TryCatch try_catch
;
122 v8::Handle
<v8::Script
> script
= v8::Script::New(source
);
123 EXPECT_FALSE(script
.IsEmpty());
124 v8::Handle
<v8::Value
> val
= script
->Run();
125 EXPECT_FALSE(val
.IsEmpty());
126 v8::Handle
<v8::Function
> func
;
127 EXPECT_TRUE(ConvertFromV8(isolate
, val
, &func
));
128 v8::Handle
<v8::Value
> argv
[] = {
129 ConvertToV8(isolate
, obj
.get()),
131 func
->Call(v8::Undefined(isolate
), 1, argv
);
133 EXPECT_EQ(191, obj
->value());