Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / core / v8 / V8BindingTest.cpp
1 // Copyright 2014 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 "config.h"
6 #include "bindings/core/v8/V8Binding.h"
7
8 #include "bindings/core/v8/ExceptionState.h"
9 #include "core/testing/GarbageCollectedScriptWrappable.h"
10 #include "core/testing/RefCountedScriptWrappable.h"
11 #include "platform/heap/Heap.h"
12 #include "wtf/Vector.h"
13
14 #include <gtest/gtest.h>
15 #include <v8.h>
16
17 #define CHECK_TOV8VALUE(expected, value) check(expected, value, __FILE__, __LINE__)
18
19 namespace blink {
20
21 namespace {
22
23 class V8ValueTraitsTest : public ::testing::Test {
24 public:
25
26     V8ValueTraitsTest()
27         : m_scope(v8::Isolate::GetCurrent())
28     {
29     }
30
31     virtual ~V8ValueTraitsTest()
32     {
33     }
34
35     template <typename T> v8::Local<v8::Value> toV8Value(const T& value)
36     {
37         return V8ValueTraits<T>::toV8Value(value, m_scope.scriptState()->context()->Global(), m_scope.isolate());
38     }
39
40     template <typename T>
41     void check(const char* expected, const T& value, const char* path, int lineNumber)
42     {
43         v8::Local<v8::Value> actual = toV8Value(value);
44         if (actual.IsEmpty()) {
45             ADD_FAILURE_AT(path, lineNumber) << "toV8Value returns an empty value.";
46             return;
47         }
48         String actualString = toCoreString(actual->ToString());
49         if (String(expected) != actualString) {
50             ADD_FAILURE_AT(path, lineNumber) << "toV8Value returns an incorrect value.\n  Actual: " << actualString.utf8().data() << "\nExpected: " << expected;
51             return;
52         }
53     }
54
55     V8TestingScope m_scope;
56 };
57
58 class GarbageCollectedHolder : public GarbageCollectedFinalized<GarbageCollectedHolder> {
59 public:
60     GarbageCollectedHolder(GarbageCollectedScriptWrappable* scriptWrappable)
61         : m_scriptWrappable(scriptWrappable) { }
62
63     void trace(Visitor* visitor) { visitor->trace(m_scriptWrappable); }
64
65     // This should be public in order to access a Member<X> object.
66     Member<GarbageCollectedScriptWrappable> m_scriptWrappable;
67 };
68
69 class OffHeapGarbageCollectedHolder {
70 public:
71     OffHeapGarbageCollectedHolder(GarbageCollectedScriptWrappable* scriptWrappable)
72         : m_scriptWrappable(scriptWrappable) { }
73
74     // This should be public in order to access a Persistent<X> object.
75     Persistent<GarbageCollectedScriptWrappable> m_scriptWrappable;
76 };
77
78 TEST_F(V8ValueTraitsTest, numeric)
79 {
80     CHECK_TOV8VALUE("0", static_cast<int>(0));
81     CHECK_TOV8VALUE("1", static_cast<int>(1));
82     CHECK_TOV8VALUE("-1", static_cast<int>(-1));
83
84     CHECK_TOV8VALUE("-2", static_cast<long>(-2));
85     CHECK_TOV8VALUE("2", static_cast<unsigned>(2));
86     CHECK_TOV8VALUE("2", static_cast<unsigned long>(2));
87
88     CHECK_TOV8VALUE("0.5", static_cast<double>(0.5));
89     CHECK_TOV8VALUE("-0.5", static_cast<float>(-0.5));
90 }
91
92 TEST_F(V8ValueTraitsTest, boolean)
93 {
94     CHECK_TOV8VALUE("true", true);
95     CHECK_TOV8VALUE("false", false);
96 }
97
98 TEST_F(V8ValueTraitsTest, string)
99 {
100     char arrayString[] = "arrayString";
101     const char constArrayString[] = "constArrayString";
102     CHECK_TOV8VALUE("arrayString", arrayString);
103     CHECK_TOV8VALUE("constArrayString", constArrayString);
104     CHECK_TOV8VALUE("pointer", const_cast<char*>(static_cast<const char*>("pointer")));
105     CHECK_TOV8VALUE("constpointer", static_cast<const char*>("constpointer"));
106     CHECK_TOV8VALUE("coreString", String("coreString"));
107     CHECK_TOV8VALUE("atomicString", AtomicString("atomicString"));
108
109     // Null strings are converted to empty strings.
110     CHECK_TOV8VALUE("", static_cast<char*>(nullptr));
111     CHECK_TOV8VALUE("", static_cast<const char*>(nullptr));
112     CHECK_TOV8VALUE("", String());
113     CHECK_TOV8VALUE("", AtomicString());
114 }
115
116 TEST_F(V8ValueTraitsTest, nullType)
117 {
118     CHECK_TOV8VALUE("null", V8NullType());
119 }
120
121 TEST_F(V8ValueTraitsTest, undefinedType)
122 {
123     CHECK_TOV8VALUE("undefined", V8UndefinedType());
124 }
125
126 TEST_F(V8ValueTraitsTest, refCountedScriptWrappable)
127 {
128     RefPtr<RefCountedScriptWrappable> object = RefCountedScriptWrappable::create("hello");
129
130     CHECK_TOV8VALUE("hello", object);
131     CHECK_TOV8VALUE("hello", object.get());
132     CHECK_TOV8VALUE("hello", object.release());
133
134     ASSERT_FALSE(object);
135
136     CHECK_TOV8VALUE("null", object);
137     CHECK_TOV8VALUE("null", object.get());
138     CHECK_TOV8VALUE("null", object.release());
139 }
140
141 TEST_F(V8ValueTraitsTest, garbageCollectedScriptWrappable)
142 {
143     GarbageCollectedScriptWrappable* object = new GarbageCollectedScriptWrappable("world");
144     GarbageCollectedHolder holder(object);
145     OffHeapGarbageCollectedHolder offHeapHolder(object);
146
147     CHECK_TOV8VALUE("world", object);
148     CHECK_TOV8VALUE("world", RawPtr<GarbageCollectedScriptWrappable>(object));
149     CHECK_TOV8VALUE("world", holder.m_scriptWrappable);
150     CHECK_TOV8VALUE("world", offHeapHolder.m_scriptWrappable);
151
152     object = nullptr;
153     holder.m_scriptWrappable = nullptr;
154     offHeapHolder.m_scriptWrappable = nullptr;
155
156     CHECK_TOV8VALUE("null", object);
157     CHECK_TOV8VALUE("null", RawPtr<GarbageCollectedScriptWrappable>(object));
158     CHECK_TOV8VALUE("null", holder.m_scriptWrappable);
159     CHECK_TOV8VALUE("null", offHeapHolder.m_scriptWrappable);
160 }
161
162 TEST_F(V8ValueTraitsTest, vector)
163 {
164     Vector<RefPtr<RefCountedScriptWrappable> > v;
165     v.append(RefCountedScriptWrappable::create("foo"));
166     v.append(RefCountedScriptWrappable::create("bar"));
167
168     CHECK_TOV8VALUE("foo,bar", v);
169 }
170
171 TEST_F(V8ValueTraitsTest, stringVectors)
172 {
173     Vector<String> stringVector;
174     stringVector.append("foo");
175     stringVector.append("bar");
176     CHECK_TOV8VALUE("foo,bar", stringVector);
177
178     Vector<AtomicString> atomicStringVector;
179     atomicStringVector.append("quux");
180     atomicStringVector.append("bar");
181     CHECK_TOV8VALUE("quux,bar", atomicStringVector);
182 }
183
184 TEST_F(V8ValueTraitsTest, basicTypeVectors)
185 {
186     Vector<int> intVector;
187     intVector.append(42);
188     intVector.append(23);
189     CHECK_TOV8VALUE("42,23", intVector);
190
191     Vector<long> longVector;
192     longVector.append(31773);
193     longVector.append(404);
194     CHECK_TOV8VALUE("31773,404", longVector);
195
196     Vector<unsigned> unsignedVector;
197     unsignedVector.append(1);
198     unsignedVector.append(2);
199     CHECK_TOV8VALUE("1,2", unsignedVector);
200
201     Vector<unsigned long> unsignedLongVector;
202     unsignedLongVector.append(1001);
203     unsignedLongVector.append(2002);
204     CHECK_TOV8VALUE("1001,2002", unsignedLongVector);
205
206     Vector<float> floatVector;
207     floatVector.append(0.125);
208     floatVector.append(1.);
209     CHECK_TOV8VALUE("0.125,1", floatVector);
210
211     Vector<double> doubleVector;
212     doubleVector.append(2.3);
213     doubleVector.append(4.2);
214     CHECK_TOV8VALUE("2.3,4.2", doubleVector);
215
216     Vector<bool> boolVector;
217     boolVector.append(true);
218     boolVector.append(true);
219     boolVector.append(false);
220     CHECK_TOV8VALUE("true,true,false", boolVector);
221 }
222
223 TEST_F(V8ValueTraitsTest, heapVector)
224 {
225     HeapVector<Member<GarbageCollectedScriptWrappable> > v;
226     v.append(new GarbageCollectedScriptWrappable("hoge"));
227     v.append(new GarbageCollectedScriptWrappable("fuga"));
228     v.append(nullptr);
229
230     CHECK_TOV8VALUE("hoge,fuga,", v);
231 }
232
233 TEST_F(V8ValueTraitsTest, stringHeapVectors)
234 {
235     HeapVector<String> stringVector;
236     stringVector.append("foo");
237     stringVector.append("bar");
238     CHECK_TOV8VALUE("foo,bar", stringVector);
239
240     HeapVector<AtomicString> atomicStringVector;
241     atomicStringVector.append("quux");
242     atomicStringVector.append("bar");
243     CHECK_TOV8VALUE("quux,bar", atomicStringVector);
244 }
245
246 TEST_F(V8ValueTraitsTest, basicTypeHeapVectors)
247 {
248     HeapVector<int> intVector;
249     intVector.append(42);
250     intVector.append(23);
251     CHECK_TOV8VALUE("42,23", intVector);
252
253     HeapVector<long> longVector;
254     longVector.append(31773);
255     longVector.append(404);
256     CHECK_TOV8VALUE("31773,404", longVector);
257
258     HeapVector<unsigned> unsignedVector;
259     unsignedVector.append(1);
260     unsignedVector.append(2);
261     CHECK_TOV8VALUE("1,2", unsignedVector);
262
263     HeapVector<unsigned long> unsignedLongVector;
264     unsignedLongVector.append(1001);
265     unsignedLongVector.append(2002);
266     CHECK_TOV8VALUE("1001,2002", unsignedLongVector);
267
268     HeapVector<float> floatVector;
269     floatVector.append(0.125);
270     floatVector.append(1.);
271     CHECK_TOV8VALUE("0.125,1", floatVector);
272
273     HeapVector<double> doubleVector;
274     doubleVector.append(2.3);
275     doubleVector.append(4.2);
276     CHECK_TOV8VALUE("2.3,4.2", doubleVector);
277
278     HeapVector<bool> boolVector;
279     boolVector.append(true);
280     boolVector.append(true);
281     boolVector.append(false);
282     CHECK_TOV8VALUE("true,true,false", boolVector);
283 }
284
285 TEST_F(V8ValueTraitsTest, scriptValue)
286 {
287     ScriptValue value(m_scope.scriptState(), v8::Number::New(m_scope.isolate(), 1234));
288
289     CHECK_TOV8VALUE("1234", value);
290 }
291
292 TEST_F(V8ValueTraitsTest, v8Value)
293 {
294     v8::Local<v8::Value> localValue(v8::Number::New(m_scope.isolate(), 1234));
295     v8::Handle<v8::Value> handleValue(v8::Number::New(m_scope.isolate(), 5678));
296
297     CHECK_TOV8VALUE("1234", localValue);
298     CHECK_TOV8VALUE("5678", handleValue);
299 }
300
301 TEST_F(V8ValueTraitsTest, toImplArray)
302 {
303     {
304         v8::Handle<v8::Array> v8StringArray = v8::Array::New(m_scope.isolate(), 2);
305         v8StringArray->Set(toV8Value(0), toV8Value("Hello, World!"));
306         v8StringArray->Set(toV8Value(1), toV8Value("Hi, Mom!"));
307
308         NonThrowableExceptionState exceptionState;
309         Vector<String> stringVector = toImplArray<String>(v8StringArray, 0, m_scope.isolate(), exceptionState);
310         EXPECT_EQ(2U, stringVector.size());
311         EXPECT_EQ("Hello, World!", stringVector[0]);
312         EXPECT_EQ("Hi, Mom!", stringVector[1]);
313     }
314     {
315         v8::Handle<v8::Array> v8UnsignedArray = v8::Array::New(m_scope.isolate(), 3);
316         v8UnsignedArray->Set(toV8Value(0), toV8Value(42));
317         v8UnsignedArray->Set(toV8Value(1), toV8Value(1729));
318         v8UnsignedArray->Set(toV8Value(2), toV8Value(31773));
319
320         NonThrowableExceptionState exceptionState;
321         Vector<unsigned> unsignedVector = toImplArray<unsigned>(v8UnsignedArray, 0, m_scope.isolate(), exceptionState);
322         EXPECT_EQ(3U, unsignedVector.size());
323         EXPECT_EQ(42U, unsignedVector[0]);
324         EXPECT_EQ(1729U, unsignedVector[1]);
325         EXPECT_EQ(31773U, unsignedVector[2]);
326     }
327     {
328         const double doublePi = 3.141592653589793238;
329         const float floatPi = doublePi;
330         v8::Handle<v8::Array> v8RealArray = v8::Array::New(m_scope.isolate(), 1);
331         v8RealArray->Set(toV8Value(0), toV8Value(doublePi));
332
333         NonThrowableExceptionState exceptionState;
334         Vector<double> doubleVector = toImplArray<double>(v8RealArray, 0, m_scope.isolate(), exceptionState);
335         EXPECT_EQ(1U, doubleVector.size());
336         EXPECT_EQ(doublePi, doubleVector[0]);
337
338         Vector<float> floatVector = toImplArray<float>(v8RealArray, 0, m_scope.isolate(), exceptionState);
339         EXPECT_EQ(1U, floatVector.size());
340         EXPECT_EQ(floatPi, floatVector[0]);
341     }
342     {
343         v8::Handle<v8::Array> v8Array = v8::Array::New(m_scope.isolate(), 3);
344         v8Array->Set(toV8Value(0), toV8Value("Vini, vidi, vici."));
345         v8Array->Set(toV8Value(1), toV8Value(65535));
346         v8Array->Set(toV8Value(2), toV8Value(0.125));
347
348         NonThrowableExceptionState exceptionState;
349         Vector<v8::Handle<v8::Value> > v8HandleVector = toImplArray<v8::Handle<v8::Value> >(v8Array, 0, m_scope.isolate(), exceptionState);
350         EXPECT_EQ(3U, v8HandleVector.size());
351         EXPECT_EQ("Vini, vidi, vici.", toScalarValueString(v8HandleVector[0], exceptionState));
352         EXPECT_EQ(65535U, toUInt32(v8HandleVector[1]));
353         EXPECT_EQ(0.125, toFloat(v8HandleVector[2]));
354
355         Vector<ScriptValue> scriptValueVector = toImplArray<ScriptValue>(v8Array, 0, m_scope.isolate(), exceptionState);
356         EXPECT_EQ(3U, scriptValueVector.size());
357         String reportOnZela;
358         EXPECT_TRUE(scriptValueVector[0].toString(reportOnZela));
359         EXPECT_EQ("Vini, vidi, vici.", reportOnZela);
360         EXPECT_EQ(65535U, toUInt32(scriptValueVector[1].v8Value()));
361         EXPECT_EQ(0.125, toFloat(scriptValueVector[2].v8Value()));
362     }
363     {
364         v8::Handle<v8::Array> v8StringArray1 = v8::Array::New(m_scope.isolate(), 2);
365         v8StringArray1->Set(toV8Value(0), toV8Value("foo"));
366         v8StringArray1->Set(toV8Value(1), toV8Value("bar"));
367         v8::Handle<v8::Array> v8StringArray2 = v8::Array::New(m_scope.isolate(), 3);
368         v8StringArray2->Set(toV8Value(0), toV8Value("x"));
369         v8StringArray2->Set(toV8Value(1), toV8Value("y"));
370         v8StringArray2->Set(toV8Value(2), toV8Value("z"));
371         v8::Handle<v8::Array> v8StringArrayArray = v8::Array::New(m_scope.isolate(), 2);
372         v8StringArrayArray->Set(toV8Value(0), v8StringArray1);
373         v8StringArrayArray->Set(toV8Value(1), v8StringArray2);
374
375         NonThrowableExceptionState exceptionState;
376         Vector<Vector<String> > stringVectorVector = toImplArray<Vector<String> >(v8StringArrayArray, 0, m_scope.isolate(), exceptionState);
377         EXPECT_EQ(2U, stringVectorVector.size());
378         EXPECT_EQ(2U, stringVectorVector[0].size());
379         EXPECT_EQ("foo", stringVectorVector[0][0]);
380         EXPECT_EQ("bar", stringVectorVector[0][1]);
381         EXPECT_EQ(3U, stringVectorVector[1].size());
382         EXPECT_EQ("x", stringVectorVector[1][0]);
383         EXPECT_EQ("y", stringVectorVector[1][1]);
384         EXPECT_EQ("z", stringVectorVector[1][2]);
385     }
386 }
387
388 } // namespace
389
390 } // namespace blink