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.
6 #include "bindings/core/v8/V8Binding.h"
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"
14 #include <gtest/gtest.h>
17 #define CHECK_TOV8VALUE(expected, value) check(expected, value, __FILE__, __LINE__)
23 class V8ValueTraitsTest : public ::testing::Test {
27 : m_scope(v8::Isolate::GetCurrent())
31 virtual ~V8ValueTraitsTest()
35 template <typename T> v8::Local<v8::Value> toV8Value(const T& value)
37 return V8ValueTraits<T>::toV8Value(value, m_scope.scriptState()->context()->Global(), m_scope.isolate());
41 void check(const char* expected, const T& value, const char* path, int lineNumber)
43 v8::Local<v8::Value> actual = toV8Value(value);
44 if (actual.IsEmpty()) {
45 ADD_FAILURE_AT(path, lineNumber) << "toV8Value returns an empty value.";
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;
55 V8TestingScope m_scope;
58 class GarbageCollectedHolder : public GarbageCollectedFinalized<GarbageCollectedHolder> {
60 GarbageCollectedHolder(GarbageCollectedScriptWrappable* scriptWrappable)
61 : m_scriptWrappable(scriptWrappable) { }
63 void trace(Visitor* visitor) { visitor->trace(m_scriptWrappable); }
65 // This should be public in order to access a Member<X> object.
66 Member<GarbageCollectedScriptWrappable> m_scriptWrappable;
69 class OffHeapGarbageCollectedHolder {
71 OffHeapGarbageCollectedHolder(GarbageCollectedScriptWrappable* scriptWrappable)
72 : m_scriptWrappable(scriptWrappable) { }
74 // This should be public in order to access a Persistent<X> object.
75 Persistent<GarbageCollectedScriptWrappable> m_scriptWrappable;
78 TEST_F(V8ValueTraitsTest, numeric)
80 CHECK_TOV8VALUE("0", static_cast<int>(0));
81 CHECK_TOV8VALUE("1", static_cast<int>(1));
82 CHECK_TOV8VALUE("-1", static_cast<int>(-1));
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));
88 CHECK_TOV8VALUE("0.5", static_cast<double>(0.5));
89 CHECK_TOV8VALUE("-0.5", static_cast<float>(-0.5));
92 TEST_F(V8ValueTraitsTest, boolean)
94 CHECK_TOV8VALUE("true", true);
95 CHECK_TOV8VALUE("false", false);
98 TEST_F(V8ValueTraitsTest, string)
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"));
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());
116 TEST_F(V8ValueTraitsTest, nullType)
118 CHECK_TOV8VALUE("null", V8NullType());
121 TEST_F(V8ValueTraitsTest, undefinedType)
123 CHECK_TOV8VALUE("undefined", V8UndefinedType());
126 TEST_F(V8ValueTraitsTest, refCountedScriptWrappable)
128 RefPtr<RefCountedScriptWrappable> object = RefCountedScriptWrappable::create("hello");
130 CHECK_TOV8VALUE("hello", object);
131 CHECK_TOV8VALUE("hello", object.get());
132 CHECK_TOV8VALUE("hello", object.release());
134 ASSERT_FALSE(object);
136 CHECK_TOV8VALUE("null", object);
137 CHECK_TOV8VALUE("null", object.get());
138 CHECK_TOV8VALUE("null", object.release());
141 TEST_F(V8ValueTraitsTest, garbageCollectedScriptWrappable)
143 GarbageCollectedScriptWrappable* object = new GarbageCollectedScriptWrappable("world");
144 GarbageCollectedHolder holder(object);
145 OffHeapGarbageCollectedHolder offHeapHolder(object);
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);
153 holder.m_scriptWrappable = nullptr;
154 offHeapHolder.m_scriptWrappable = nullptr;
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);
162 TEST_F(V8ValueTraitsTest, vector)
164 Vector<RefPtr<RefCountedScriptWrappable> > v;
165 v.append(RefCountedScriptWrappable::create("foo"));
166 v.append(RefCountedScriptWrappable::create("bar"));
168 CHECK_TOV8VALUE("foo,bar", v);
171 TEST_F(V8ValueTraitsTest, stringVectors)
173 Vector<String> stringVector;
174 stringVector.append("foo");
175 stringVector.append("bar");
176 CHECK_TOV8VALUE("foo,bar", stringVector);
178 Vector<AtomicString> atomicStringVector;
179 atomicStringVector.append("quux");
180 atomicStringVector.append("bar");
181 CHECK_TOV8VALUE("quux,bar", atomicStringVector);
184 TEST_F(V8ValueTraitsTest, basicTypeVectors)
186 Vector<int> intVector;
187 intVector.append(42);
188 intVector.append(23);
189 CHECK_TOV8VALUE("42,23", intVector);
191 Vector<long> longVector;
192 longVector.append(31773);
193 longVector.append(404);
194 CHECK_TOV8VALUE("31773,404", longVector);
196 Vector<unsigned> unsignedVector;
197 unsignedVector.append(1);
198 unsignedVector.append(2);
199 CHECK_TOV8VALUE("1,2", unsignedVector);
201 Vector<unsigned long> unsignedLongVector;
202 unsignedLongVector.append(1001);
203 unsignedLongVector.append(2002);
204 CHECK_TOV8VALUE("1001,2002", unsignedLongVector);
206 Vector<float> floatVector;
207 floatVector.append(0.125);
208 floatVector.append(1.);
209 CHECK_TOV8VALUE("0.125,1", floatVector);
211 Vector<double> doubleVector;
212 doubleVector.append(2.3);
213 doubleVector.append(4.2);
214 CHECK_TOV8VALUE("2.3,4.2", doubleVector);
216 Vector<bool> boolVector;
217 boolVector.append(true);
218 boolVector.append(true);
219 boolVector.append(false);
220 CHECK_TOV8VALUE("true,true,false", boolVector);
223 TEST_F(V8ValueTraitsTest, heapVector)
225 HeapVector<Member<GarbageCollectedScriptWrappable> > v;
226 v.append(new GarbageCollectedScriptWrappable("hoge"));
227 v.append(new GarbageCollectedScriptWrappable("fuga"));
230 CHECK_TOV8VALUE("hoge,fuga,", v);
233 TEST_F(V8ValueTraitsTest, stringHeapVectors)
235 HeapVector<String> stringVector;
236 stringVector.append("foo");
237 stringVector.append("bar");
238 CHECK_TOV8VALUE("foo,bar", stringVector);
240 HeapVector<AtomicString> atomicStringVector;
241 atomicStringVector.append("quux");
242 atomicStringVector.append("bar");
243 CHECK_TOV8VALUE("quux,bar", atomicStringVector);
246 TEST_F(V8ValueTraitsTest, basicTypeHeapVectors)
248 HeapVector<int> intVector;
249 intVector.append(42);
250 intVector.append(23);
251 CHECK_TOV8VALUE("42,23", intVector);
253 HeapVector<long> longVector;
254 longVector.append(31773);
255 longVector.append(404);
256 CHECK_TOV8VALUE("31773,404", longVector);
258 HeapVector<unsigned> unsignedVector;
259 unsignedVector.append(1);
260 unsignedVector.append(2);
261 CHECK_TOV8VALUE("1,2", unsignedVector);
263 HeapVector<unsigned long> unsignedLongVector;
264 unsignedLongVector.append(1001);
265 unsignedLongVector.append(2002);
266 CHECK_TOV8VALUE("1001,2002", unsignedLongVector);
268 HeapVector<float> floatVector;
269 floatVector.append(0.125);
270 floatVector.append(1.);
271 CHECK_TOV8VALUE("0.125,1", floatVector);
273 HeapVector<double> doubleVector;
274 doubleVector.append(2.3);
275 doubleVector.append(4.2);
276 CHECK_TOV8VALUE("2.3,4.2", doubleVector);
278 HeapVector<bool> boolVector;
279 boolVector.append(true);
280 boolVector.append(true);
281 boolVector.append(false);
282 CHECK_TOV8VALUE("true,true,false", boolVector);
285 TEST_F(V8ValueTraitsTest, scriptValue)
287 ScriptValue value(m_scope.scriptState(), v8::Number::New(m_scope.isolate(), 1234));
289 CHECK_TOV8VALUE("1234", value);
292 TEST_F(V8ValueTraitsTest, v8Value)
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));
297 CHECK_TOV8VALUE("1234", localValue);
298 CHECK_TOV8VALUE("5678", handleValue);
301 TEST_F(V8ValueTraitsTest, toImplArray)
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!"));
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]);
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));
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]);
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));
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]);
338 Vector<float> floatVector = toImplArray<float>(v8RealArray, 0, m_scope.isolate(), exceptionState);
339 EXPECT_EQ(1U, floatVector.size());
340 EXPECT_EQ(floatPi, floatVector[0]);
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));
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]));
355 Vector<ScriptValue> scriptValueVector = toImplArray<ScriptValue>(v8Array, 0, m_scope.isolate(), exceptionState);
356 EXPECT_EQ(3U, scriptValueVector.size());
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()));
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);
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]);