Dismiss autofill popup on screen orientation change.
[chromium-blink-merge.git] / webkit / renderer / cpp_variant_unittest.cc
blob1f2d3fe8d3e1837de83d4bc99c4fed093d8c28ea
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/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "third_party/WebKit/public/web/WebBindings.h"
12 #include "webkit/renderer/cpp_variant.h"
14 using WebKit::WebBindings;
15 using webkit_glue::CppVariant;
17 // Creates a std::string from an NPVariant of string type. If the NPVariant
18 // is not a string, empties the std::string.
19 void MakeStdString(const NPVariant& np, std::string* std_string) {
20 if (np.type == NPVariantType_String) {
21 const char* chars =
22 reinterpret_cast<const char*>(np.value.stringValue.UTF8Characters);
23 (*std_string).assign(chars, np.value.stringValue.UTF8Length);
24 } else {
25 (*std_string).clear();
29 // Verifies that the actual NPVariant is a string and that its value matches
30 // the expected_str.
31 void CheckString(const std::string& expected_str, const NPVariant& actual) {
32 EXPECT_EQ(NPVariantType_String, actual.type);
33 std::string actual_str;
34 MakeStdString(actual, &actual_str);
35 EXPECT_EQ(expected_str, actual_str);
38 // Verifies that both the actual and the expected NPVariants are strings and
39 // that their values match.
40 void CheckString(const NPVariant& expected, const NPVariant& actual) {
41 EXPECT_EQ(NPVariantType_String, expected.type);
42 std::string expected_str;
43 MakeStdString(expected, &expected_str);
44 CheckString(expected_str, actual);
47 int g_allocate_call_count = 0;
48 int g_deallocate_call_count = 0;
50 void CheckObject(const NPVariant& actual) {
51 EXPECT_EQ(NPVariantType_Object, actual.type);
52 EXPECT_TRUE(actual.value.objectValue);
53 EXPECT_EQ(1U, actual.value.objectValue->referenceCount);
54 EXPECT_EQ(1, g_allocate_call_count);
55 EXPECT_EQ(0, g_deallocate_call_count);
58 NPObject* MockNPAllocate(NPP npp, NPClass* aClass) {
59 // This is a mock allocate method that mimics the behavior
60 // of WebBindings::createObject when allocate() is NULL
62 ++g_allocate_call_count;
63 // Ignore npp and NPClass
64 return reinterpret_cast<NPObject*>(malloc(sizeof(NPObject)));
67 void MockNPDeallocate(NPObject* npobj) {
68 // This is a mock deallocate method that mimics the behavior
69 // of NPN_DeallocateObject when deallocate() is NULL
71 ++g_deallocate_call_count;
72 free(npobj);
75 static NPClass void_class = { NP_CLASS_STRUCT_VERSION,
76 MockNPAllocate,
77 MockNPDeallocate,
78 0, 0, 0, 0, 0, 0, 0, 0, 0 };
80 class CppVariantTest : public testing::Test {
81 public:
82 CppVariantTest() : npp_(new struct _NPP) {}
83 virtual ~CppVariantTest() {}
85 virtual void SetUp() OVERRIDE {
86 WebBindings::registerObjectOwner(npp_.get());
89 virtual void TearDown() OVERRIDE {
90 WebBindings::unregisterObjectOwner(npp_.get());
93 struct _NPP* npp() { return npp_.get(); }
95 NPObject* MakeVoidObject() {
96 g_allocate_call_count = 0;
97 g_deallocate_call_count = 0;
98 return WebBindings::createObject(npp_.get(), &void_class);
101 private:
102 scoped_ptr<struct _NPP> npp_;
105 TEST_F(CppVariantTest, NewVariantHasNullType) {
106 CppVariant value;
107 EXPECT_EQ(NPVariantType_Null, value.type);
110 TEST_F(CppVariantTest, SetNullSetsType) {
111 CppVariant value;
112 value.Set(17);
113 value.SetNull();
114 EXPECT_EQ(NPVariantType_Null, value.type);
117 TEST_F(CppVariantTest, CopyConstructorDoesDeepCopy) {
118 CppVariant source;
119 source.Set("test string");
120 CppVariant dest = source;
121 EXPECT_EQ(NPVariantType_String, dest.type);
122 EXPECT_EQ(NPVariantType_String, source.type);
124 // Ensure that the string was copied, not just the pointer.
125 EXPECT_NE(source.value.stringValue.UTF8Characters,
126 dest.value.stringValue.UTF8Characters);
128 CheckString(source, dest);
131 TEST_F(CppVariantTest, CopyConstructorIncrementsRefCount) {
132 CppVariant source;
133 NPObject *object = MakeVoidObject();
134 source.Set(object);
135 // 2 references so far.
136 EXPECT_EQ(2U, source.value.objectValue->referenceCount);
138 CppVariant dest = source;
139 EXPECT_EQ(3U, dest.value.objectValue->referenceCount);
140 EXPECT_EQ(1, g_allocate_call_count);
141 WebBindings::releaseObject(object);
142 source.SetNull();
143 CheckObject(dest);
146 TEST_F(CppVariantTest, AssignmentDoesDeepCopy) {
147 CppVariant source;
148 source.Set("test string");
149 CppVariant dest;
150 dest = source;
151 EXPECT_EQ(NPVariantType_String, dest.type);
152 EXPECT_EQ(NPVariantType_String, source.type);
154 // Ensure that the string was copied, not just the pointer.
155 EXPECT_NE(source.value.stringValue.UTF8Characters,
156 dest.value.stringValue.UTF8Characters);
158 CheckString(source, dest);
161 TEST_F(CppVariantTest, AssignmentIncrementsRefCount) {
162 CppVariant source;
163 NPObject *object = MakeVoidObject();
164 source.Set(object);
165 // 2 references so far.
166 EXPECT_EQ(2U, source.value.objectValue->referenceCount);
168 CppVariant dest;
169 dest = source;
170 EXPECT_EQ(3U, dest.value.objectValue->referenceCount);
171 EXPECT_EQ(1, g_allocate_call_count);
173 WebBindings::releaseObject(object);
174 source.SetNull();
175 CheckObject(dest);
178 TEST_F(CppVariantTest, DestroyingCopyDoesNotCorruptSource) {
179 CppVariant source;
180 source.Set("test string");
181 std::string before;
182 MakeStdString(source, &before);
184 CppVariant dest = source;
186 CheckString(before, source);
188 NPObject *object = MakeVoidObject();
189 source.Set(object);
191 CppVariant dest2 = source;
193 WebBindings::releaseObject(object);
194 CheckObject(source);
197 TEST_F(CppVariantTest, CopiesTypeAndValueToNPVariant) {
198 NPVariant np;
199 CppVariant cpp;
201 cpp.Set(true);
202 cpp.CopyToNPVariant(&np);
203 EXPECT_EQ(cpp.type, np.type);
204 EXPECT_EQ(cpp.value.boolValue, np.value.boolValue);
205 WebBindings::releaseVariantValue(&np);
207 cpp.Set(17);
208 cpp.CopyToNPVariant(&np);
209 EXPECT_EQ(cpp.type, np.type);
210 EXPECT_EQ(cpp.value.intValue, np.value.intValue);
211 WebBindings::releaseVariantValue(&np);
213 cpp.Set(3.1415);
214 cpp.CopyToNPVariant(&np);
215 EXPECT_EQ(cpp.type, np.type);
216 EXPECT_EQ(cpp.value.doubleValue, np.value.doubleValue);
217 WebBindings::releaseVariantValue(&np);
219 cpp.Set("test value");
220 cpp.CopyToNPVariant(&np);
221 CheckString("test value", np);
222 WebBindings::releaseVariantValue(&np);
224 cpp.SetNull();
225 cpp.CopyToNPVariant(&np);
226 EXPECT_EQ(cpp.type, np.type);
227 WebBindings::releaseVariantValue(&np);
229 NPObject *object = MakeVoidObject();
230 cpp.Set(object);
231 cpp.CopyToNPVariant(&np);
232 WebBindings::releaseObject(object);
233 cpp.SetNull();
234 CheckObject(np);
235 WebBindings::releaseVariantValue(&np);
238 TEST_F(CppVariantTest, SetsTypeAndValueFromNPVariant) {
239 NPVariant np;
240 CppVariant cpp;
242 VOID_TO_NPVARIANT(np);
243 cpp.Set(np);
244 EXPECT_EQ(np.type, cpp.type);
245 WebBindings::releaseVariantValue(&np);
247 NULL_TO_NPVARIANT(np);
248 cpp.Set(np);
249 EXPECT_EQ(np.type, cpp.type);
250 WebBindings::releaseVariantValue(&np);
252 BOOLEAN_TO_NPVARIANT(true, np);
253 cpp.Set(np);
254 EXPECT_EQ(np.type, cpp.type);
255 EXPECT_EQ(np.value.boolValue, cpp.value.boolValue);
256 WebBindings::releaseVariantValue(&np);
258 INT32_TO_NPVARIANT(15, np);
259 cpp.Set(np);
260 EXPECT_EQ(np.type, cpp.type);
261 EXPECT_EQ(np.value.intValue, cpp.value.intValue);
262 WebBindings::releaseVariantValue(&np);
264 DOUBLE_TO_NPVARIANT(2.71828, np);
265 cpp.Set(np);
266 EXPECT_EQ(np.type, cpp.type);
267 EXPECT_EQ(np.value.doubleValue, cpp.value.doubleValue);
268 WebBindings::releaseVariantValue(&np);
270 NPString np_ascii_str = { "1st test value",
271 static_cast<uint32_t>(strlen("1st test value")) };
272 WebBindings::initializeVariantWithStringCopy(&np, &np_ascii_str);
273 cpp.Set(np);
274 CheckString("1st test value", cpp);
275 WebBindings::releaseVariantValue(&np);
277 // Test characters represented in 2/3/4 bytes in UTF-8
278 // Greek alpha, Chinese number 1 (horizontal bar),
279 // Deseret letter (similar to 'O')
280 NPString np_intl_str = { "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84",
281 static_cast<uint32_t>(strlen(
282 "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84")) };
283 WebBindings::initializeVariantWithStringCopy(&np, &np_intl_str);
284 cpp.Set(np);
285 CheckString("\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84", cpp);
286 WebBindings::releaseVariantValue(&np);
288 NPObject *obj = MakeVoidObject();
289 OBJECT_TO_NPVARIANT(obj, np); // Doesn't make a copy.
290 cpp.Set(np);
291 // Use this or WebBindings::releaseObject but NOT both.
292 WebBindings::releaseVariantValue(&np);
293 CheckObject(cpp);
296 TEST_F(CppVariantTest, SetsSimpleTypesAndValues) {
297 CppVariant cpp;
298 cpp.Set(true);
299 EXPECT_EQ(NPVariantType_Bool, cpp.type);
300 EXPECT_TRUE(cpp.value.boolValue);
302 cpp.Set(5);
303 EXPECT_EQ(NPVariantType_Int32, cpp.type);
304 EXPECT_EQ(5, cpp.value.intValue);
306 cpp.Set(1.234);
307 EXPECT_EQ(NPVariantType_Double, cpp.type);
308 EXPECT_EQ(1.234, cpp.value.doubleValue);
310 // C string
311 cpp.Set("1st test string");
312 CheckString("1st test string", cpp);
314 // std::string
315 std::string source("std test string");
316 cpp.Set(source);
317 CheckString("std test string", cpp);
319 // NPString
320 NPString np_ascii_str = { "test NPString",
321 static_cast<uint32_t>(strlen("test NPString")) };
322 cpp.Set(np_ascii_str);
323 std::string expected("test NPString");
324 CheckString(expected, cpp);
326 // Test characters represented in 2/3/4 bytes in UTF-8
327 // Greek alpha, Chinese number 1 (horizontal bar),
328 // Deseret letter (similar to 'O')
329 NPString np_intl_str = { "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84",
330 static_cast<uint32_t>(strlen(
331 "\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84")) };
332 cpp.Set(np_intl_str);
333 expected = std::string("\xce\xb1\xe4\xb8\x80\xf0\x90\x90\x84");
334 CheckString(expected, cpp);
336 NPObject* obj = MakeVoidObject();
337 cpp.Set(obj);
338 WebBindings::releaseObject(obj);
339 CheckObject(cpp);
342 TEST_F(CppVariantTest, FreeDataSetsToVoid) {
343 CppVariant cpp;
344 EXPECT_EQ(NPVariantType_Null, cpp.type);
345 cpp.Set(12);
346 EXPECT_EQ(NPVariantType_Int32, cpp.type);
347 cpp.FreeData();
348 EXPECT_EQ(NPVariantType_Void, cpp.type);
351 TEST_F(CppVariantTest, FreeDataReleasesObject) {
352 CppVariant cpp;
353 NPObject* object = MakeVoidObject();
354 cpp.Set(object);
355 EXPECT_EQ(2U, object->referenceCount);
356 cpp.FreeData();
357 EXPECT_EQ(1U, object->referenceCount);
358 EXPECT_EQ(0, g_deallocate_call_count);
360 cpp.Set(object);
361 WebBindings::releaseObject(object);
362 EXPECT_EQ(0, g_deallocate_call_count);
363 cpp.FreeData();
364 EXPECT_EQ(1, g_deallocate_call_count);
367 TEST_F(CppVariantTest, IsTypeFunctionsWork) {
368 CppVariant cpp;
369 // These should not happen in practice, since voids are not supported
370 // This test must be first since it just clobbers internal data without
371 // releasing.
372 VOID_TO_NPVARIANT(cpp);
373 EXPECT_FALSE(cpp.isBool());
374 EXPECT_FALSE(cpp.isInt32());
375 EXPECT_FALSE(cpp.isDouble());
376 EXPECT_FALSE(cpp.isNumber());
377 EXPECT_FALSE(cpp.isString());
378 EXPECT_TRUE(cpp.isVoid());
379 EXPECT_FALSE(cpp.isNull());
380 EXPECT_TRUE(cpp.isEmpty());
382 cpp.Set(true);
383 EXPECT_TRUE(cpp.isBool());
384 EXPECT_FALSE(cpp.isInt32());
385 EXPECT_FALSE(cpp.isDouble());
386 EXPECT_FALSE(cpp.isNumber());
387 EXPECT_FALSE(cpp.isString());
388 EXPECT_FALSE(cpp.isVoid());
389 EXPECT_FALSE(cpp.isNull());
390 EXPECT_FALSE(cpp.isEmpty());
391 EXPECT_FALSE(cpp.isObject());
393 cpp.Set(12);
394 EXPECT_FALSE(cpp.isBool());
395 EXPECT_TRUE(cpp.isInt32());
396 EXPECT_FALSE(cpp.isDouble());
397 EXPECT_TRUE(cpp.isNumber());
398 EXPECT_FALSE(cpp.isString());
399 EXPECT_FALSE(cpp.isVoid());
400 EXPECT_FALSE(cpp.isNull());
401 EXPECT_FALSE(cpp.isEmpty());
402 EXPECT_FALSE(cpp.isObject());
404 cpp.Set(3.1415);
405 EXPECT_FALSE(cpp.isBool());
406 EXPECT_FALSE(cpp.isInt32());
407 EXPECT_TRUE(cpp.isDouble());
408 EXPECT_TRUE(cpp.isNumber());
409 EXPECT_FALSE(cpp.isString());
410 EXPECT_FALSE(cpp.isVoid());
411 EXPECT_FALSE(cpp.isNull());
412 EXPECT_FALSE(cpp.isEmpty());
413 EXPECT_FALSE(cpp.isObject());
415 cpp.Set("a string");
416 EXPECT_FALSE(cpp.isBool());
417 EXPECT_FALSE(cpp.isInt32());
418 EXPECT_FALSE(cpp.isDouble());
419 EXPECT_FALSE(cpp.isNumber());
420 EXPECT_TRUE(cpp.isString());
421 EXPECT_FALSE(cpp.isVoid());
422 EXPECT_FALSE(cpp.isNull());
423 EXPECT_FALSE(cpp.isEmpty());
424 EXPECT_FALSE(cpp.isObject());
426 cpp.SetNull();
427 EXPECT_FALSE(cpp.isBool());
428 EXPECT_FALSE(cpp.isInt32());
429 EXPECT_FALSE(cpp.isDouble());
430 EXPECT_FALSE(cpp.isNumber());
431 EXPECT_FALSE(cpp.isString());
432 EXPECT_FALSE(cpp.isVoid());
433 EXPECT_TRUE(cpp.isNull());
434 EXPECT_TRUE(cpp.isEmpty());
435 EXPECT_FALSE(cpp.isObject());
437 NPObject *obj = MakeVoidObject();
438 cpp.Set(obj);
439 EXPECT_FALSE(cpp.isBool());
440 EXPECT_FALSE(cpp.isInt32());
441 EXPECT_FALSE(cpp.isDouble());
442 EXPECT_FALSE(cpp.isNumber());
443 EXPECT_FALSE(cpp.isString());
444 EXPECT_FALSE(cpp.isVoid());
445 EXPECT_FALSE(cpp.isNull());
446 EXPECT_FALSE(cpp.isEmpty());
447 EXPECT_TRUE(cpp.isObject());
448 WebBindings::releaseObject(obj);
449 CheckObject(cpp);
452 bool MockNPHasPropertyFunction(NPObject *npobj, NPIdentifier name) {
453 return true;
456 bool MockNPGetPropertyFunction(NPObject *npobj, NPIdentifier name,
457 NPVariant *result) {
458 if (WebBindings::getStringIdentifier("length") == name) {
459 DOUBLE_TO_NPVARIANT(4, *result);
460 } else if (WebBindings::getIntIdentifier(0) == name) {
461 DOUBLE_TO_NPVARIANT(0, *result);
462 } else if (WebBindings::getIntIdentifier(1) == name) {
463 BOOLEAN_TO_NPVARIANT(true, *result);
464 } else if (WebBindings::getIntIdentifier(2) == name) {
465 NULL_TO_NPVARIANT(*result);
466 } else if (WebBindings::getIntIdentifier(3) == name) {
467 const char* s = "string";
468 size_t length = strlen(s);
469 char* mem = static_cast<char*>(malloc(length + 1));
470 base::strlcpy(mem, s, length + 1);
471 STRINGZ_TO_NPVARIANT(mem, *result);
474 return true;
477 TEST_F(CppVariantTest, ToVector) {
478 NPClass array_like_class = {
479 NP_CLASS_STRUCT_VERSION,
480 0, // NPAllocateFunctionPtr allocate;
481 0, // NPDeallocateFunctionPtr deallocate;
482 0, // NPInvalidateFunctionPtr invalidate;
483 0, // NPHasMethodFunctionPtr hasMethod;
484 0, // NPInvokeFunctionPtr invoke;
485 0, // NPInvokeDefaultFunctionPtr invokeDefault;
486 MockNPHasPropertyFunction, // NPHasPropertyFunctionPtr hasProperty;
487 MockNPGetPropertyFunction, // NPGetPropertyFunctionPtr getProperty;
488 0, // NPSetPropertyFunctionPtr setProperty;
489 0, // NPRemovePropertyFunctionPtr removeProperty;
490 0, // NPEnumerationFunctionPtr enumerate;
491 0 // NPConstructFunctionPtr construct;
494 NPObject* obj = WebBindings::createObject(npp(), &array_like_class);
496 CppVariant cpp;
497 cpp.Set(obj);
499 std::vector<CppVariant> cpp_vector = cpp.ToVector();
500 EXPECT_EQ(4u, cpp_vector.size());
502 EXPECT_TRUE(cpp_vector[0].isDouble());
503 EXPECT_EQ(0, cpp_vector[0].ToDouble());
505 EXPECT_TRUE(cpp_vector[1].isBool());
506 EXPECT_EQ(true, cpp_vector[1].ToBoolean());
508 EXPECT_TRUE(cpp_vector[2].isNull());
510 EXPECT_TRUE(cpp_vector[3].isString());
511 CheckString("string", cpp_vector[3]);
513 WebBindings::releaseObject(obj);