Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / gin / wrappable_unittest.cc
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.
4
5 #include "base/logging.h"
6 #include "gin/arguments.h"
7 #include "gin/handle.h"
8 #include "gin/object_template_builder.h"
9 #include "gin/per_isolate_data.h"
10 #include "gin/public/isolate_holder.h"
11 #include "gin/test/v8_test.h"
12 #include "gin/try_catch.h"
13 #include "gin/wrappable.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace gin {
17
18 class BaseClass {
19  public:
20   BaseClass() : value_(23) {}
21   virtual ~BaseClass() {}
22
23  private:
24   int value_;
25
26   DISALLOW_COPY_AND_ASSIGN(BaseClass);
27 };
28
29 class MyObject : public BaseClass,
30                  public Wrappable<MyObject> {
31  public:
32   static WrapperInfo kWrapperInfo;
33
34   static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
35     return CreateHandle(isolate, new MyObject());
36   }
37
38   int value() const { return value_; }
39   void set_value(int value) { value_ = value; }
40
41  protected:
42   MyObject() : value_(0) {}
43   ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate) override;
44   ~MyObject() override {}
45
46  private:
47   int value_;
48 };
49
50 class MyObjectSubclass : public MyObject {
51  public:
52   static gin::Handle<MyObjectSubclass> Create(v8::Isolate* isolate) {
53     return CreateHandle(isolate, new MyObjectSubclass());
54   }
55
56   void SayHello(const std::string& name) {
57     result = std::string("Hello, ") + name;
58   }
59
60   std::string result;
61
62  private:
63   ObjectTemplateBuilder GetObjectTemplateBuilder(
64       v8::Isolate* isolate) override {
65     return MyObject::GetObjectTemplateBuilder(isolate)
66         .SetMethod("sayHello", &MyObjectSubclass::SayHello);
67   }
68
69   MyObjectSubclass() {
70   }
71
72   ~MyObjectSubclass() override {}
73 };
74
75 class MyCallableObject : public Wrappable<MyCallableObject> {
76  public:
77   static WrapperInfo kWrapperInfo;
78
79   static gin::Handle<MyCallableObject> Create(v8::Isolate* isolate) {
80     return CreateHandle(isolate, new MyCallableObject());
81   }
82
83   int result() { return result_; }
84
85  private:
86   ObjectTemplateBuilder GetObjectTemplateBuilder(
87       v8::Isolate* isolate) override {
88     return Wrappable<MyCallableObject>::GetObjectTemplateBuilder(isolate)
89         .SetCallAsFunctionHandler(&MyCallableObject::Call);
90   }
91
92   MyCallableObject() : result_(0) {
93   }
94
95   ~MyCallableObject() override {}
96
97   void Call(int val1, int val2, int val3, const gin::Arguments& arguments) {
98     if (arguments.IsConstructCall())
99       arguments.ThrowTypeError("Cannot be called as constructor.");
100     else
101       result_ = val1;
102   }
103
104   int result_;
105 };
106
107 class MyObject2 : public Wrappable<MyObject2> {
108  public:
109   static WrapperInfo kWrapperInfo;
110 };
111
112 class MyObjectBlink : public Wrappable<MyObjectBlink> {
113  public:
114   static WrapperInfo kWrapperInfo;
115 };
116
117 WrapperInfo MyObject::kWrapperInfo = { kEmbedderNativeGin };
118 ObjectTemplateBuilder MyObject::GetObjectTemplateBuilder(v8::Isolate* isolate) {
119   return Wrappable<MyObject>::GetObjectTemplateBuilder(isolate)
120       .SetProperty("value", &MyObject::value, &MyObject::set_value);
121 }
122
123 WrapperInfo MyCallableObject::kWrapperInfo = { kEmbedderNativeGin };
124 WrapperInfo MyObject2::kWrapperInfo = { kEmbedderNativeGin };
125 WrapperInfo MyObjectBlink::kWrapperInfo = { kEmbedderNativeGin };
126
127 typedef V8Test WrappableTest;
128
129 TEST_F(WrappableTest, WrapAndUnwrap) {
130   v8::Isolate* isolate = instance_->isolate();
131   v8::HandleScope handle_scope(isolate);
132
133   Handle<MyObject> obj = MyObject::Create(isolate);
134
135   v8::Handle<v8::Value> wrapper = ConvertToV8(isolate, obj.get());
136   EXPECT_FALSE(wrapper.IsEmpty());
137
138   MyObject* unwrapped = NULL;
139   EXPECT_TRUE(ConvertFromV8(isolate, wrapper, &unwrapped));
140   EXPECT_EQ(obj.get(), unwrapped);
141 }
142
143 TEST_F(WrappableTest, UnwrapFailures) {
144   v8::Isolate* isolate = instance_->isolate();
145   v8::HandleScope handle_scope(isolate);
146
147   // Something that isn't an object.
148   v8::Handle<v8::Value> thing = v8::Number::New(isolate, 42);
149   MyObject* unwrapped = NULL;
150   EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
151   EXPECT_FALSE(unwrapped);
152
153   // An object that's not wrapping anything.
154   thing = v8::Object::New(isolate);
155   EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
156   EXPECT_FALSE(unwrapped);
157
158   // An object that's wrapping a C++ object from Blink.
159   thing.Clear();
160   thing = ConvertToV8(isolate, new MyObjectBlink());
161   EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
162   EXPECT_FALSE(unwrapped);
163
164   // An object that's wrapping a C++ object of the wrong type.
165   thing.Clear();
166   thing = ConvertToV8(isolate, new MyObject2());
167   EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
168   EXPECT_FALSE(unwrapped);
169 }
170
171 TEST_F(WrappableTest, GetAndSetProperty) {
172   v8::Isolate* isolate = instance_->isolate();
173   v8::HandleScope handle_scope(isolate);
174
175   gin::Handle<MyObject> obj = MyObject::Create(isolate);
176
177   obj->set_value(42);
178   EXPECT_EQ(42, obj->value());
179
180   v8::Handle<v8::String> source = StringToV8(isolate,
181       "(function (obj) {"
182       "   if (obj.value !== 42) throw 'FAIL';"
183       "   else obj.value = 191; })");
184   EXPECT_FALSE(source.IsEmpty());
185
186   gin::TryCatch try_catch;
187   v8::Handle<v8::Script> script = v8::Script::Compile(source);
188   EXPECT_FALSE(script.IsEmpty());
189   v8::Handle<v8::Value> val = script->Run();
190   EXPECT_FALSE(val.IsEmpty());
191   v8::Handle<v8::Function> func;
192   EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
193   v8::Handle<v8::Value> argv[] = {
194     ConvertToV8(isolate, obj.get()),
195   };
196   func->Call(v8::Undefined(isolate), 1, argv);
197   EXPECT_FALSE(try_catch.HasCaught());
198   EXPECT_EQ("", try_catch.GetStackTrace());
199
200   EXPECT_EQ(191, obj->value());
201 }
202
203 TEST_F(WrappableTest, WrappableSubclass) {
204   v8::Isolate* isolate = instance_->isolate();
205   v8::HandleScope handle_scope(isolate);
206
207   gin::Handle<MyObjectSubclass> object(MyObjectSubclass::Create(isolate));
208   v8::Handle<v8::String> source = StringToV8(isolate,
209                                              "(function(obj) {"
210                                              "obj.sayHello('Lily');"
211                                              "})");
212   gin::TryCatch try_catch;
213   v8::Handle<v8::Script> script = v8::Script::Compile(source);
214   v8::Handle<v8::Value> val = script->Run();
215   v8::Handle<v8::Function> func;
216   EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
217   v8::Handle<v8::Value> argv[] = {
218     ConvertToV8(isolate, object.get())
219   };
220   func->Call(v8::Undefined(isolate), 1, argv);
221   EXPECT_FALSE(try_catch.HasCaught());
222   EXPECT_EQ("Hello, Lily", object->result);
223 }
224
225 TEST_F(WrappableTest, CallAsFunction) {
226   v8::Isolate* isolate = instance_->isolate();
227   v8::HandleScope handle_scope(isolate);
228
229   gin::Handle<MyCallableObject> object(MyCallableObject::Create(isolate));
230   EXPECT_EQ(0, object->result());
231   v8::Handle<v8::String> source = StringToV8(isolate,
232                                              "(function(obj) {"
233                                              "obj(42, 2, 5);"
234                                              "})");
235   gin::TryCatch try_catch;
236   v8::Handle<v8::Script> script = v8::Script::Compile(source);
237   v8::Handle<v8::Value> val = script->Run();
238   v8::Handle<v8::Function> func;
239   EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
240   v8::Handle<v8::Value> argv[] = {
241     ConvertToV8(isolate, object.get())
242   };
243   func->Call(v8::Undefined(isolate), 1, argv);
244   EXPECT_FALSE(try_catch.HasCaught());
245   EXPECT_EQ(42, object->result());
246 }
247
248 TEST_F(WrappableTest, CallAsConstructor) {
249   v8::Isolate* isolate = instance_->isolate();
250   v8::HandleScope handle_scope(isolate);
251
252   gin::Handle<MyCallableObject> object(MyCallableObject::Create(isolate));
253   EXPECT_EQ(0, object->result());
254   v8::Handle<v8::String> source = StringToV8(isolate,
255                                              "(function(obj) {"
256                                              "new obj(42, 2, 5);"
257                                              "})");
258   gin::TryCatch try_catch;
259   v8::Handle<v8::Script> script = v8::Script::Compile(source);
260   v8::Handle<v8::Value> val = script->Run();
261   v8::Handle<v8::Function> func;
262   EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
263   v8::Handle<v8::Value> argv[] = {
264     ConvertToV8(isolate, object.get())
265   };
266   func->Call(v8::Undefined(isolate), 1, argv);
267   EXPECT_TRUE(try_catch.HasCaught());
268 }
269
270 }  // namespace gin