[Mac] PepperFlash default on DEV channel.
[chromium-blink-merge.git] / webkit / glue / cpp_variant_unittest.cc
blob85cc140752014c9a83aae8ea2022b009753d21f2
1 // Copyright (c) 2012 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 <vector>
7 #include "base/compiler_specific.h"
8 #include "base/string_util.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h"
11 #include "webkit/glue/cpp_variant.h"
13 using WebKit::WebBindings;
14 using webkit_glue::CppVariant;
16 // Creates a std::string from an NPVariant of string type. If the NPVariant
17 // is not a string, empties the std::string.
18 void MakeStdString(const NPVariant& np, std::string* std_string) {
19 if (np.type == NPVariantType_String) {
20 const char* chars =
21 reinterpret_cast<const char*>(np.value.stringValue.UTF8Characters);
22 (*std_string).assign(chars, np.value.stringValue.UTF8Length);
23 } else {
24 (*std_string).clear();
28 // Verifies that the actual NPVariant is a string and that its value matches
29 // the expected_str.
30 void CheckString(const std::string& expected_str, const NPVariant& actual) {
31 EXPECT_EQ(NPVariantType_String, actual.type);
32 std::string actual_str;
33 MakeStdString(actual, &actual_str);
34 EXPECT_EQ(expected_str, actual_str);
37 // Verifies that both the actual and the expected NPVariants are strings and
38 // that their values match.
39 void CheckString(const NPVariant& expected, const NPVariant& actual) {
40 EXPECT_EQ(NPVariantType_String, expected.type);
41 std::string expected_str;
42 MakeStdString(expected, &expected_str);
43 CheckString(expected_str, actual);
46 int g_allocate_call_count = 0;
47 int g_deallocate_call_count = 0;
49 void CheckObject(const NPVariant& actual) {
50 EXPECT_EQ(NPVariantType_Object, actual.type);
51 EXPECT_TRUE(actual.value.objectValue);
52 EXPECT_EQ(1U, actual.value.objectValue->referenceCount);
53 EXPECT_EQ(1, g_allocate_call_count);
54 EXPECT_EQ(0, g_deallocate_call_count);
57 NPObject* MockNPAllocate(NPP npp, NPClass* aClass) {
58 // This is a mock allocate method that mimics the behavior
59 // of WebBindings::createObject when allocate() is NULL
61 ++g_allocate_call_count;
62 // Ignore npp and NPClass
63 return reinterpret_cast<NPObject*>(malloc(sizeof(NPObject)));
66 void MockNPDeallocate(NPObject* npobj) {
67 // This is a mock deallocate method that mimics the behavior
68 // of NPN_DeallocateObject when deallocate() is NULL
70 ++g_deallocate_call_count;
71 free(npobj);
74 static NPClass void_class = { NP_CLASS_STRUCT_VERSION,
75 MockNPAllocate,
76 MockNPDeallocate,
77 0, 0, 0, 0, 0, 0, 0, 0, 0 };
79 NPObject* MakeVoidObject() {
80 g_allocate_call_count = 0;
81 g_deallocate_call_count = 0;
82 return WebBindings::createObject(NULL, &void_class);
85 TEST(CppVariantTest, NewVariantHasNullType) {
86 CppVariant value;
87 EXPECT_EQ(NPVariantType_Null, value.type);
90 TEST(CppVariantTest, SetNullSetsType) {
91 CppVariant value;
92 value.Set(17);
93 value.SetNull();
94 EXPECT_EQ(NPVariantType_Null, value.type);
97 TEST(CppVariantTest, CopyConstructorDoesDeepCopy) {
98 CppVariant source;
99 source.Set("test string");
100 CppVariant dest = source;
101 EXPECT_EQ(NPVariantType_String, dest.type);
102 EXPECT_EQ(NPVariantType_String, source.type);
104 // Ensure that the string was copied, not just the pointer.
105 EXPECT_NE(source.value.stringValue.UTF8Characters,
106 dest.value.stringValue.UTF8Characters);
108 CheckString(source, dest);
111 TEST(CppVariantTest, CopyConstructorIncrementsRefCount) {
112 CppVariant source;
113 NPObject *object = MakeVoidObject();
114 source.Set(object);
115 // 2 references so far.
116 EXPECT_EQ(2U, source.value.objectValue->referenceCount);
118 CppVariant dest = source;
119 EXPECT_EQ(3U, dest.value.objectValue->referenceCount);
120 EXPECT_EQ(1, g_allocate_call_count);
121 WebBindings::releaseObject(object);
122 source.SetNull();
123 CheckObject(dest);
126 TEST(CppVariantTest, AssignmentDoesDeepCopy) {
127 CppVariant source;
128 source.Set("test string");
129 CppVariant dest;
130 dest = source;
131 EXPECT_EQ(NPVariantType_String, dest.type);
132 EXPECT_EQ(NPVariantType_String, source.type);
134 // Ensure that the string was copied, not just the pointer.
135 EXPECT_NE(source.value.stringValue.UTF8Characters,
136 dest.value.stringValue.UTF8Characters);
138 CheckString(source, dest);
141 TEST(CppVariantTest, AssignmentIncrementsRefCount) {
142 CppVariant source;
143 NPObject *object = MakeVoidObject();
144 source.Set(object);
145 // 2 references so far.
146 EXPECT_EQ(2U, source.value.objectValue->referenceCount);
148 CppVariant dest;
149 dest = source;
150 EXPECT_EQ(3U, dest.value.objectValue->referenceCount);
151 EXPECT_EQ(1, g_allocate_call_count);
153 WebBindings::releaseObject(object);
154 source.SetNull();
155 CheckObject(dest);
158 TEST(CppVariantTest, DestroyingCopyDoesNotCorruptSource) {
159 CppVariant source;
160 source.Set("test string");
161 std::string before;
162 MakeStdString(source, &before);
164 CppVariant dest = source;
166 CheckString(before, source);
168 NPObject *object = MakeVoidObject();
169 source.Set(object);
171 CppVariant dest2 = source;
173 WebBindings::releaseObject(object);
174 CheckObject(source);
177 TEST(CppVariantTest, CopiesTypeAndValueToNPVariant) {
178 NPVariant np;
179 CppVariant cpp;
181 cpp.Set(true);
182 cpp.CopyToNPVariant(&np);
183 EXPECT_EQ(cpp.type, np.type);
184 EXPECT_EQ(cpp.value.boolValue, np.value.boolValue);
185 WebBindings::releaseVariantValue(&np);
187 cpp.Set(17);
188 cpp.CopyToNPVariant(&np);
189 EXPECT_EQ(cpp.type, np.type);
190 EXPECT_EQ(cpp.value.intValue, np.value.intValue);
191 WebBindings::releaseVariantValue(&np);
193 cpp.Set(3.1415);
194 cpp.CopyToNPVariant(&np);
195 EXPECT_EQ(cpp.type, np.type);
196 EXPECT_EQ(cpp.value.doubleValue, np.value.doubleValue);
197 WebBindings::releaseVariantValue(&np);
199 cpp.Set("test value");
200 cpp.CopyToNPVariant(&np);
201 CheckString("test value", np);
202 WebBindings::releaseVariantValue(&np);
204 cpp.SetNull();
205 cpp.CopyToNPVariant(&np);
206 EXPECT_EQ(cpp.type, np.type);
207 WebBindings::releaseVariantValue(&np);
209 NPObject *object = MakeVoidObject();
210 cpp.Set(object);
211 cpp.CopyToNPVariant(&np);
212 WebBindings::releaseObject(object);
213 cpp.SetNull();
214 CheckObject(np);
215 WebBindings::releaseVariantValue(&np);
218 TEST(CppVariantTest, SetsTypeAndValueFromNPVariant) {
219 NPVariant np;
220 CppVariant cpp;
222 VOID_TO_NPVARIANT(np);
223 cpp.Set(np);
224 EXPECT_EQ(np.type, cpp.type);
225 WebBindings::releaseVariantValue(&np);
227 NULL_TO_NPVARIANT(np);
228 cpp.Set(np);
229 EXPECT_EQ(np.type, cpp.type);
230 WebBindings::releaseVariantValue(&np);
232 BOOLEAN_TO_NPVARIANT(true, np);
233 cpp.Set(np);
234 EXPECT_EQ(np.type, cpp.type);
235 EXPECT_EQ(np.value.boolValue, cpp.value.boolValue);
236 WebBindings::releaseVariantValue(&np);
238 INT32_TO_NPVARIANT(15, np);
239 cpp.Set(np);
240 EXPECT_EQ(np.type, cpp.type);
241 EXPECT_EQ(np.value.intValue, cpp.value.intValue);
242 WebBindings::releaseVariantValue(&np);
244 DOUBLE_TO_NPVARIANT(2.71828, np);
245 cpp.Set(np);
246 EXPECT_EQ(np.type, cpp.type);
247 EXPECT_EQ(np.value.doubleValue, cpp.value.doubleValue);
248 WebBindings::releaseVariantValue(&np);
250 NPString np_ascii_str = { "1st test value",
251 static_cast<uint32_t>(strlen("1st test value")) };
252 WebBindings::initializeVariantWithStringCopy(&np, &np_ascii_str);
253 cpp.Set(np);
254 CheckString("1st test value", cpp);
255 WebBindings::releaseVariantValue(&np);
257 // Test characters represented in 2/3/4 bytes in UTF-8
258 // Greek alpha, Chinese number 1 (horizontal bar),
259 // Deseret letter (similar to 'O')
260 NPString np_intl_str = { "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84",
261 static_cast<uint32_t>(strlen(
262 "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84")) };
263 WebBindings::initializeVariantWithStringCopy(&np, &np_intl_str);
264 cpp.Set(np);
265 CheckString("\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84", cpp);
266 WebBindings::releaseVariantValue(&np);
268 NPObject *obj = MakeVoidObject();
269 OBJECT_TO_NPVARIANT(obj, np); // Doesn't make a copy.
270 cpp.Set(np);
271 // Use this or WebBindings::releaseObject but NOT both.
272 WebBindings::releaseVariantValue(&np);
273 CheckObject(cpp);
276 TEST(CppVariantTest, SetsSimpleTypesAndValues) {
277 CppVariant cpp;
278 cpp.Set(true);
279 EXPECT_EQ(NPVariantType_Bool, cpp.type);
280 EXPECT_TRUE(cpp.value.boolValue);
282 cpp.Set(5);
283 EXPECT_EQ(NPVariantType_Int32, cpp.type);
284 EXPECT_EQ(5, cpp.value.intValue);
286 cpp.Set(1.234);
287 EXPECT_EQ(NPVariantType_Double, cpp.type);
288 EXPECT_EQ(1.234, cpp.value.doubleValue);
290 // C string
291 cpp.Set("1st test string");
292 CheckString("1st test string", cpp);
294 // std::string
295 std::string source("std test string");
296 cpp.Set(source);
297 CheckString("std test string", cpp);
299 // NPString
300 NPString np_ascii_str = { "test NPString",
301 static_cast<uint32_t>(strlen("test NPString")) };
302 cpp.Set(np_ascii_str);
303 std::string expected("test NPString");
304 CheckString(expected, cpp);
306 // Test characters represented in 2/3/4 bytes in UTF-8
307 // Greek alpha, Chinese number 1 (horizontal bar),
308 // Deseret letter (similar to 'O')
309 NPString np_intl_str = { "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84",
310 static_cast<uint32_t>(strlen(
311 "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84")) };
312 cpp.Set(np_intl_str);
313 expected = std::string("\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84");
314 CheckString(expected, cpp);
316 NPObject* obj = MakeVoidObject();
317 cpp.Set(obj);
318 WebBindings::releaseObject(obj);
319 CheckObject(cpp);
322 TEST(CppVariantTest, FreeDataSetsToVoid) {
323 CppVariant cpp;
324 EXPECT_EQ(NPVariantType_Null, cpp.type);
325 cpp.Set(12);
326 EXPECT_EQ(NPVariantType_Int32, cpp.type);
327 cpp.FreeData();
328 EXPECT_EQ(NPVariantType_Void, cpp.type);
331 TEST(CppVariantTest, FreeDataReleasesObject) {
332 CppVariant cpp;
333 NPObject* object = MakeVoidObject();
334 cpp.Set(object);
335 EXPECT_EQ(2U, object->referenceCount);
336 cpp.FreeData();
337 EXPECT_EQ(1U, object->referenceCount);
338 EXPECT_EQ(0, g_deallocate_call_count);
340 cpp.Set(object);
341 WebBindings::releaseObject(object);
342 EXPECT_EQ(0, g_deallocate_call_count);
343 cpp.FreeData();
344 EXPECT_EQ(1, g_deallocate_call_count);
347 TEST(CppVariantTest, IsTypeFunctionsWork) {
348 CppVariant cpp;
349 // These should not happen in practice, since voids are not supported
350 // This test must be first since it just clobbers internal data without
351 // releasing.
352 VOID_TO_NPVARIANT(cpp);
353 EXPECT_FALSE(cpp.isBool());
354 EXPECT_FALSE(cpp.isInt32());
355 EXPECT_FALSE(cpp.isDouble());
356 EXPECT_FALSE(cpp.isNumber());
357 EXPECT_FALSE(cpp.isString());
358 EXPECT_TRUE(cpp.isVoid());
359 EXPECT_FALSE(cpp.isNull());
360 EXPECT_TRUE(cpp.isEmpty());
362 cpp.Set(true);
363 EXPECT_TRUE(cpp.isBool());
364 EXPECT_FALSE(cpp.isInt32());
365 EXPECT_FALSE(cpp.isDouble());
366 EXPECT_FALSE(cpp.isNumber());
367 EXPECT_FALSE(cpp.isString());
368 EXPECT_FALSE(cpp.isVoid());
369 EXPECT_FALSE(cpp.isNull());
370 EXPECT_FALSE(cpp.isEmpty());
371 EXPECT_FALSE(cpp.isObject());
373 cpp.Set(12);
374 EXPECT_FALSE(cpp.isBool());
375 EXPECT_TRUE(cpp.isInt32());
376 EXPECT_FALSE(cpp.isDouble());
377 EXPECT_TRUE(cpp.isNumber());
378 EXPECT_FALSE(cpp.isString());
379 EXPECT_FALSE(cpp.isVoid());
380 EXPECT_FALSE(cpp.isNull());
381 EXPECT_FALSE(cpp.isEmpty());
382 EXPECT_FALSE(cpp.isObject());
384 cpp.Set(3.1415);
385 EXPECT_FALSE(cpp.isBool());
386 EXPECT_FALSE(cpp.isInt32());
387 EXPECT_TRUE(cpp.isDouble());
388 EXPECT_TRUE(cpp.isNumber());
389 EXPECT_FALSE(cpp.isString());
390 EXPECT_FALSE(cpp.isVoid());
391 EXPECT_FALSE(cpp.isNull());
392 EXPECT_FALSE(cpp.isEmpty());
393 EXPECT_FALSE(cpp.isObject());
395 cpp.Set("a string");
396 EXPECT_FALSE(cpp.isBool());
397 EXPECT_FALSE(cpp.isInt32());
398 EXPECT_FALSE(cpp.isDouble());
399 EXPECT_FALSE(cpp.isNumber());
400 EXPECT_TRUE(cpp.isString());
401 EXPECT_FALSE(cpp.isVoid());
402 EXPECT_FALSE(cpp.isNull());
403 EXPECT_FALSE(cpp.isEmpty());
404 EXPECT_FALSE(cpp.isObject());
406 cpp.SetNull();
407 EXPECT_FALSE(cpp.isBool());
408 EXPECT_FALSE(cpp.isInt32());
409 EXPECT_FALSE(cpp.isDouble());
410 EXPECT_FALSE(cpp.isNumber());
411 EXPECT_FALSE(cpp.isString());
412 EXPECT_FALSE(cpp.isVoid());
413 EXPECT_TRUE(cpp.isNull());
414 EXPECT_TRUE(cpp.isEmpty());
415 EXPECT_FALSE(cpp.isObject());
417 NPObject *obj = MakeVoidObject();
418 cpp.Set(obj);
419 EXPECT_FALSE(cpp.isBool());
420 EXPECT_FALSE(cpp.isInt32());
421 EXPECT_FALSE(cpp.isDouble());
422 EXPECT_FALSE(cpp.isNumber());
423 EXPECT_FALSE(cpp.isString());
424 EXPECT_FALSE(cpp.isVoid());
425 EXPECT_FALSE(cpp.isNull());
426 EXPECT_FALSE(cpp.isEmpty());
427 EXPECT_TRUE(cpp.isObject());
428 WebBindings::releaseObject(obj);
429 CheckObject(cpp);
432 bool MockNPHasPropertyFunction(NPObject *npobj, NPIdentifier name) {
433 return true;
436 bool MockNPGetPropertyFunction(NPObject *npobj, NPIdentifier name,
437 NPVariant *result) {
438 if (WebBindings::getStringIdentifier("length") == name) {
439 DOUBLE_TO_NPVARIANT(4, *result);
440 } else if (WebBindings::getIntIdentifier(0) == name) {
441 DOUBLE_TO_NPVARIANT(0, *result);
442 } else if (WebBindings::getIntIdentifier(1) == name) {
443 BOOLEAN_TO_NPVARIANT(true, *result);
444 } else if (WebBindings::getIntIdentifier(2) == name) {
445 NULL_TO_NPVARIANT(*result);
446 } else if (WebBindings::getIntIdentifier(3) == name) {
447 const char* s = "string";
448 size_t length = strlen(s);
449 char* mem = static_cast<char*>(malloc(length + 1));
450 base::strlcpy(mem, s, length + 1);
451 STRINGZ_TO_NPVARIANT(mem, *result);
454 return true;
457 TEST(CppVariantTest, ToVector) {
458 NPClass array_like_class = {
459 NP_CLASS_STRUCT_VERSION,
460 0, // NPAllocateFunctionPtr allocate;
461 0, // NPDeallocateFunctionPtr deallocate;
462 0, // NPInvalidateFunctionPtr invalidate;
463 0, // NPHasMethodFunctionPtr hasMethod;
464 0, // NPInvokeFunctionPtr invoke;
465 0, // NPInvokeDefaultFunctionPtr invokeDefault;
466 MockNPHasPropertyFunction, // NPHasPropertyFunctionPtr hasProperty;
467 MockNPGetPropertyFunction, // NPGetPropertyFunctionPtr getProperty;
468 0, // NPSetPropertyFunctionPtr setProperty;
469 0, // NPRemovePropertyFunctionPtr removeProperty;
470 0, // NPEnumerationFunctionPtr enumerate;
471 0 // NPConstructFunctionPtr construct;
474 NPObject* obj = WebBindings::createObject(NULL, &array_like_class);
476 CppVariant cpp;
477 cpp.Set(obj);
479 std::vector<CppVariant> cpp_vector = cpp.ToVector();
480 EXPECT_EQ(4u, cpp_vector.size());
482 EXPECT_TRUE(cpp_vector[0].isDouble());
483 EXPECT_EQ(0, cpp_vector[0].ToDouble());
485 EXPECT_TRUE(cpp_vector[1].isBool());
486 EXPECT_EQ(true, cpp_vector[1].ToBoolean());
488 EXPECT_TRUE(cpp_vector[2].isNull());
490 EXPECT_TRUE(cpp_vector[3].isString());
491 CheckString("string", cpp_vector[3]);
493 WebBindings::releaseObject(obj);