Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / base / mac / foundation_util_unittest.mm
blobe60a0f6b6495c6cbe04331f741c15ff3c07b4496
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 "base/mac/foundation_util.h"
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/files/file_path.h"
10 #include "base/format_macros.h"
11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/scoped_nsautorelease_pool.h"
13 #include "base/strings/stringprintf.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #import "testing/gtest_mac.h"
17 namespace base {
18 namespace mac {
20 TEST(FoundationUtilTest, CFCast) {
21   // Build out the CF types to be tested as empty containers.
22   ScopedCFTypeRef<CFTypeRef> test_array(
23       CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks));
24   ScopedCFTypeRef<CFTypeRef> test_array_mutable(
25       CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
26   ScopedCFTypeRef<CFTypeRef> test_bag(
27       CFBagCreate(NULL, NULL, 0, &kCFTypeBagCallBacks));
28   ScopedCFTypeRef<CFTypeRef> test_bag_mutable(
29       CFBagCreateMutable(NULL, 0, &kCFTypeBagCallBacks));
30   CFTypeRef test_bool = kCFBooleanTrue;
31   ScopedCFTypeRef<CFTypeRef> test_data(
32       CFDataCreate(NULL, NULL, 0));
33   ScopedCFTypeRef<CFTypeRef> test_data_mutable(
34       CFDataCreateMutable(NULL, 0));
35   ScopedCFTypeRef<CFTypeRef> test_date(
36       CFDateCreate(NULL, 0));
37   ScopedCFTypeRef<CFTypeRef> test_dict(
38       CFDictionaryCreate(NULL, NULL, NULL, 0,
39                          &kCFCopyStringDictionaryKeyCallBacks,
40                          &kCFTypeDictionaryValueCallBacks));
41   ScopedCFTypeRef<CFTypeRef> test_dict_mutable(
42       CFDictionaryCreateMutable(NULL, 0,
43                                 &kCFCopyStringDictionaryKeyCallBacks,
44                                 &kCFTypeDictionaryValueCallBacks));
45   int int_val = 256;
46   ScopedCFTypeRef<CFTypeRef> test_number(
47       CFNumberCreate(NULL, kCFNumberIntType, &int_val));
48   CFTypeRef test_null = kCFNull;
49   ScopedCFTypeRef<CFTypeRef> test_set(
50       CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks));
51   ScopedCFTypeRef<CFTypeRef> test_set_mutable(
52       CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks));
53   ScopedCFTypeRef<CFTypeRef> test_str(
54       CFStringCreateWithBytes(NULL, NULL, 0, kCFStringEncodingASCII, false));
55   CFTypeRef test_str_const = CFSTR("hello");
56   ScopedCFTypeRef<CFTypeRef> test_str_mutable(CFStringCreateMutable(NULL, 0));
58   // Make sure the allocations of CF types are good.
59   EXPECT_TRUE(test_array);
60   EXPECT_TRUE(test_array_mutable);
61   EXPECT_TRUE(test_bag);
62   EXPECT_TRUE(test_bag_mutable);
63   EXPECT_TRUE(test_bool);
64   EXPECT_TRUE(test_data);
65   EXPECT_TRUE(test_data_mutable);
66   EXPECT_TRUE(test_date);
67   EXPECT_TRUE(test_dict);
68   EXPECT_TRUE(test_dict_mutable);
69   EXPECT_TRUE(test_number);
70   EXPECT_TRUE(test_null);
71   EXPECT_TRUE(test_set);
72   EXPECT_TRUE(test_set_mutable);
73   EXPECT_TRUE(test_str);
74   EXPECT_TRUE(test_str_const);
75   EXPECT_TRUE(test_str_mutable);
77   // Casting the CFTypeRef objects correctly provides the same pointer.
78   EXPECT_EQ(test_array, CFCast<CFArrayRef>(test_array));
79   EXPECT_EQ(test_array_mutable, CFCast<CFArrayRef>(test_array_mutable));
80   EXPECT_EQ(test_bag, CFCast<CFBagRef>(test_bag));
81   EXPECT_EQ(test_bag_mutable, CFCast<CFBagRef>(test_bag_mutable));
82   EXPECT_EQ(test_bool, CFCast<CFBooleanRef>(test_bool));
83   EXPECT_EQ(test_data, CFCast<CFDataRef>(test_data));
84   EXPECT_EQ(test_data_mutable, CFCast<CFDataRef>(test_data_mutable));
85   EXPECT_EQ(test_date, CFCast<CFDateRef>(test_date));
86   EXPECT_EQ(test_dict, CFCast<CFDictionaryRef>(test_dict));
87   EXPECT_EQ(test_dict_mutable, CFCast<CFDictionaryRef>(test_dict_mutable));
88   EXPECT_EQ(test_number, CFCast<CFNumberRef>(test_number));
89   EXPECT_EQ(test_null, CFCast<CFNullRef>(test_null));
90   EXPECT_EQ(test_set, CFCast<CFSetRef>(test_set));
91   EXPECT_EQ(test_set_mutable, CFCast<CFSetRef>(test_set_mutable));
92   EXPECT_EQ(test_str, CFCast<CFStringRef>(test_str));
93   EXPECT_EQ(test_str_const, CFCast<CFStringRef>(test_str_const));
94   EXPECT_EQ(test_str_mutable, CFCast<CFStringRef>(test_str_mutable));
96   // When given an incorrect CF cast, provide NULL.
97   EXPECT_FALSE(CFCast<CFStringRef>(test_array));
98   EXPECT_FALSE(CFCast<CFStringRef>(test_array_mutable));
99   EXPECT_FALSE(CFCast<CFStringRef>(test_bag));
100   EXPECT_FALSE(CFCast<CFSetRef>(test_bag_mutable));
101   EXPECT_FALSE(CFCast<CFSetRef>(test_bool));
102   EXPECT_FALSE(CFCast<CFNullRef>(test_data));
103   EXPECT_FALSE(CFCast<CFDictionaryRef>(test_data_mutable));
104   EXPECT_FALSE(CFCast<CFDictionaryRef>(test_date));
105   EXPECT_FALSE(CFCast<CFNumberRef>(test_dict));
106   EXPECT_FALSE(CFCast<CFDateRef>(test_dict_mutable));
107   EXPECT_FALSE(CFCast<CFDataRef>(test_number));
108   EXPECT_FALSE(CFCast<CFDataRef>(test_null));
109   EXPECT_FALSE(CFCast<CFBooleanRef>(test_set));
110   EXPECT_FALSE(CFCast<CFBagRef>(test_set_mutable));
111   EXPECT_FALSE(CFCast<CFBagRef>(test_str));
112   EXPECT_FALSE(CFCast<CFArrayRef>(test_str_const));
113   EXPECT_FALSE(CFCast<CFArrayRef>(test_str_mutable));
115   // Giving a NULL provides a NULL.
116   EXPECT_FALSE(CFCast<CFArrayRef>(NULL));
117   EXPECT_FALSE(CFCast<CFBagRef>(NULL));
118   EXPECT_FALSE(CFCast<CFBooleanRef>(NULL));
119   EXPECT_FALSE(CFCast<CFDataRef>(NULL));
120   EXPECT_FALSE(CFCast<CFDateRef>(NULL));
121   EXPECT_FALSE(CFCast<CFDictionaryRef>(NULL));
122   EXPECT_FALSE(CFCast<CFNullRef>(NULL));
123   EXPECT_FALSE(CFCast<CFNumberRef>(NULL));
124   EXPECT_FALSE(CFCast<CFSetRef>(NULL));
125   EXPECT_FALSE(CFCast<CFStringRef>(NULL));
127   // CFCastStrict: correct cast results in correct pointer being returned.
128   EXPECT_EQ(test_array, CFCastStrict<CFArrayRef>(test_array));
129   EXPECT_EQ(test_array_mutable, CFCastStrict<CFArrayRef>(test_array_mutable));
130   EXPECT_EQ(test_bag, CFCastStrict<CFBagRef>(test_bag));
131   EXPECT_EQ(test_bag_mutable, CFCastStrict<CFBagRef>(test_bag_mutable));
132   EXPECT_EQ(test_bool, CFCastStrict<CFBooleanRef>(test_bool));
133   EXPECT_EQ(test_data, CFCastStrict<CFDataRef>(test_data));
134   EXPECT_EQ(test_data_mutable, CFCastStrict<CFDataRef>(test_data_mutable));
135   EXPECT_EQ(test_date, CFCastStrict<CFDateRef>(test_date));
136   EXPECT_EQ(test_dict, CFCastStrict<CFDictionaryRef>(test_dict));
137   EXPECT_EQ(test_dict_mutable,
138             CFCastStrict<CFDictionaryRef>(test_dict_mutable));
139   EXPECT_EQ(test_number, CFCastStrict<CFNumberRef>(test_number));
140   EXPECT_EQ(test_null, CFCastStrict<CFNullRef>(test_null));
141   EXPECT_EQ(test_set, CFCastStrict<CFSetRef>(test_set));
142   EXPECT_EQ(test_set_mutable, CFCastStrict<CFSetRef>(test_set_mutable));
143   EXPECT_EQ(test_str, CFCastStrict<CFStringRef>(test_str));
144   EXPECT_EQ(test_str_const, CFCastStrict<CFStringRef>(test_str_const));
145   EXPECT_EQ(test_str_mutable, CFCastStrict<CFStringRef>(test_str_mutable));
147   // CFCastStrict: Giving a NULL provides a NULL.
148   EXPECT_FALSE(CFCastStrict<CFArrayRef>(NULL));
149   EXPECT_FALSE(CFCastStrict<CFBagRef>(NULL));
150   EXPECT_FALSE(CFCastStrict<CFBooleanRef>(NULL));
151   EXPECT_FALSE(CFCastStrict<CFDataRef>(NULL));
152   EXPECT_FALSE(CFCastStrict<CFDateRef>(NULL));
153   EXPECT_FALSE(CFCastStrict<CFDictionaryRef>(NULL));
154   EXPECT_FALSE(CFCastStrict<CFNullRef>(NULL));
155   EXPECT_FALSE(CFCastStrict<CFNumberRef>(NULL));
156   EXPECT_FALSE(CFCastStrict<CFSetRef>(NULL));
157   EXPECT_FALSE(CFCastStrict<CFStringRef>(NULL));
160 TEST(FoundationUtilTest, ObjCCast) {
161   ScopedNSAutoreleasePool pool;
163   id test_array = [NSArray array];
164   id test_array_mutable = [NSMutableArray array];
165   id test_data = [NSData data];
166   id test_data_mutable = [NSMutableData dataWithCapacity:10];
167   id test_date = [NSDate date];
168   id test_dict =
169       [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42]
170                                   forKey:@"meaning"];
171   id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10];
172   id test_number = [NSNumber numberWithInt:42];
173   id test_null = [NSNull null];
174   id test_set = [NSSet setWithObject:@"string object"];
175   id test_set_mutable = [NSMutableSet setWithCapacity:10];
176   id test_str = [NSString string];
177   id test_str_const = @"bonjour";
178   id test_str_mutable = [NSMutableString stringWithCapacity:10];
180   // Make sure the allocations of NS types are good.
181   EXPECT_TRUE(test_array);
182   EXPECT_TRUE(test_array_mutable);
183   EXPECT_TRUE(test_data);
184   EXPECT_TRUE(test_data_mutable);
185   EXPECT_TRUE(test_date);
186   EXPECT_TRUE(test_dict);
187   EXPECT_TRUE(test_dict_mutable);
188   EXPECT_TRUE(test_number);
189   EXPECT_TRUE(test_null);
190   EXPECT_TRUE(test_set);
191   EXPECT_TRUE(test_set_mutable);
192   EXPECT_TRUE(test_str);
193   EXPECT_TRUE(test_str_const);
194   EXPECT_TRUE(test_str_mutable);
196   // Casting the id correctly provides the same pointer.
197   EXPECT_EQ(test_array, ObjCCast<NSArray>(test_array));
198   EXPECT_EQ(test_array_mutable, ObjCCast<NSArray>(test_array_mutable));
199   EXPECT_EQ(test_data, ObjCCast<NSData>(test_data));
200   EXPECT_EQ(test_data_mutable, ObjCCast<NSData>(test_data_mutable));
201   EXPECT_EQ(test_date, ObjCCast<NSDate>(test_date));
202   EXPECT_EQ(test_dict, ObjCCast<NSDictionary>(test_dict));
203   EXPECT_EQ(test_dict_mutable, ObjCCast<NSDictionary>(test_dict_mutable));
204   EXPECT_EQ(test_number, ObjCCast<NSNumber>(test_number));
205   EXPECT_EQ(test_null, ObjCCast<NSNull>(test_null));
206   EXPECT_EQ(test_set, ObjCCast<NSSet>(test_set));
207   EXPECT_EQ(test_set_mutable, ObjCCast<NSSet>(test_set_mutable));
208   EXPECT_EQ(test_str, ObjCCast<NSString>(test_str));
209   EXPECT_EQ(test_str_const, ObjCCast<NSString>(test_str_const));
210   EXPECT_EQ(test_str_mutable, ObjCCast<NSString>(test_str_mutable));
212   // When given an incorrect ObjC cast, provide nil.
213   EXPECT_FALSE(ObjCCast<NSString>(test_array));
214   EXPECT_FALSE(ObjCCast<NSString>(test_array_mutable));
215   EXPECT_FALSE(ObjCCast<NSString>(test_data));
216   EXPECT_FALSE(ObjCCast<NSString>(test_data_mutable));
217   EXPECT_FALSE(ObjCCast<NSSet>(test_date));
218   EXPECT_FALSE(ObjCCast<NSSet>(test_dict));
219   EXPECT_FALSE(ObjCCast<NSNumber>(test_dict_mutable));
220   EXPECT_FALSE(ObjCCast<NSNull>(test_number));
221   EXPECT_FALSE(ObjCCast<NSDictionary>(test_null));
222   EXPECT_FALSE(ObjCCast<NSDictionary>(test_set));
223   EXPECT_FALSE(ObjCCast<NSDate>(test_set_mutable));
224   EXPECT_FALSE(ObjCCast<NSData>(test_str));
225   EXPECT_FALSE(ObjCCast<NSData>(test_str_const));
226   EXPECT_FALSE(ObjCCast<NSArray>(test_str_mutable));
228   // Giving a nil provides a nil.
229   EXPECT_FALSE(ObjCCast<NSArray>(nil));
230   EXPECT_FALSE(ObjCCast<NSData>(nil));
231   EXPECT_FALSE(ObjCCast<NSDate>(nil));
232   EXPECT_FALSE(ObjCCast<NSDictionary>(nil));
233   EXPECT_FALSE(ObjCCast<NSNull>(nil));
234   EXPECT_FALSE(ObjCCast<NSNumber>(nil));
235   EXPECT_FALSE(ObjCCast<NSSet>(nil));
236   EXPECT_FALSE(ObjCCast<NSString>(nil));
238   // ObjCCastStrict: correct cast results in correct pointer being returned.
239   EXPECT_EQ(test_array, ObjCCastStrict<NSArray>(test_array));
240   EXPECT_EQ(test_array_mutable,
241             ObjCCastStrict<NSArray>(test_array_mutable));
242   EXPECT_EQ(test_data, ObjCCastStrict<NSData>(test_data));
243   EXPECT_EQ(test_data_mutable,
244             ObjCCastStrict<NSData>(test_data_mutable));
245   EXPECT_EQ(test_date, ObjCCastStrict<NSDate>(test_date));
246   EXPECT_EQ(test_dict, ObjCCastStrict<NSDictionary>(test_dict));
247   EXPECT_EQ(test_dict_mutable,
248             ObjCCastStrict<NSDictionary>(test_dict_mutable));
249   EXPECT_EQ(test_number, ObjCCastStrict<NSNumber>(test_number));
250   EXPECT_EQ(test_null, ObjCCastStrict<NSNull>(test_null));
251   EXPECT_EQ(test_set, ObjCCastStrict<NSSet>(test_set));
252   EXPECT_EQ(test_set_mutable,
253             ObjCCastStrict<NSSet>(test_set_mutable));
254   EXPECT_EQ(test_str, ObjCCastStrict<NSString>(test_str));
255   EXPECT_EQ(test_str_const,
256             ObjCCastStrict<NSString>(test_str_const));
257   EXPECT_EQ(test_str_mutable,
258             ObjCCastStrict<NSString>(test_str_mutable));
260   // ObjCCastStrict: Giving a nil provides a nil.
261   EXPECT_FALSE(ObjCCastStrict<NSArray>(nil));
262   EXPECT_FALSE(ObjCCastStrict<NSData>(nil));
263   EXPECT_FALSE(ObjCCastStrict<NSDate>(nil));
264   EXPECT_FALSE(ObjCCastStrict<NSDictionary>(nil));
265   EXPECT_FALSE(ObjCCastStrict<NSNull>(nil));
266   EXPECT_FALSE(ObjCCastStrict<NSNumber>(nil));
267   EXPECT_FALSE(ObjCCastStrict<NSSet>(nil));
268   EXPECT_FALSE(ObjCCastStrict<NSString>(nil));
271 TEST(FoundationUtilTest, GetValueFromDictionary) {
272   int one = 1, two = 2, three = 3;
274   ScopedCFTypeRef<CFNumberRef> cf_one(
275       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &one));
276   ScopedCFTypeRef<CFNumberRef> cf_two(
277       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &two));
278   ScopedCFTypeRef<CFNumberRef> cf_three(
279       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &three));
281   CFStringRef keys[] = { CFSTR("one"), CFSTR("two"), CFSTR("three") };
282   CFNumberRef values[] = { cf_one, cf_two, cf_three };
284   COMPILE_ASSERT(arraysize(keys) == arraysize(values),
285                  keys_and_values_arraysizes_are_different);
287   ScopedCFTypeRef<CFDictionaryRef> test_dict(
288       CFDictionaryCreate(kCFAllocatorDefault,
289                          reinterpret_cast<const void**>(keys),
290                          reinterpret_cast<const void**>(values),
291                          arraysize(values),
292                          &kCFCopyStringDictionaryKeyCallBacks,
293                          &kCFTypeDictionaryValueCallBacks));
295   // GetValueFromDictionary<>(_, _) should produce the correct
296   // expected output.
297   EXPECT_EQ(values[0],
298             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("one")));
299   EXPECT_EQ(values[1],
300             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("two")));
301   EXPECT_EQ(values[2],
302             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("three")));
304   // Bad input should produce bad output.
305   EXPECT_FALSE(GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("four")));
306   EXPECT_FALSE(GetValueFromDictionary<CFStringRef>(test_dict, CFSTR("one")));
309 TEST(FoundationUtilTest, FilePathToNSString) {
310   EXPECT_NSEQ(nil, FilePathToNSString(FilePath()));
311   EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b")));
314 TEST(FoundationUtilTest, NSStringToFilePath) {
315   EXPECT_EQ(FilePath(), NSStringToFilePath(nil));
316   EXPECT_EQ(FilePath(), NSStringToFilePath(@""));
317   EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b"));
320 TEST(StringNumberConversionsTest, FormatNSInteger) {
321   // The PRI[dxu]NS macro assumes that NSInteger is a typedef to "int" on
322   // 32-bit architecture and a typedef to "long" on 64-bit architecture
323   // (respectively "unsigned int" and "unsigned long" for NSUInteger). Use
324   // pointer incompatibility to validate this at compilation.
325 #if defined(ARCH_CPU_64_BITS)
326   typedef long FormatNSIntegerAsType;
327   typedef unsigned long FormatNSUIntegerAsType;
328 #else
329   typedef int FormatNSIntegerAsType;
330   typedef unsigned int FormatNSUIntegerAsType;
331 #endif  // defined(ARCH_CPU_64_BITS)
333   NSInteger some_nsinteger;
334   FormatNSIntegerAsType* pointer_to_some_nsinteger = &some_nsinteger;
335   ALLOW_UNUSED_LOCAL(pointer_to_some_nsinteger);
337   NSUInteger some_nsuinteger;
338   FormatNSUIntegerAsType* pointer_to_some_nsuinteger = &some_nsuinteger;
339   ALLOW_UNUSED_LOCAL(pointer_to_some_nsuinteger);
341   // Check that format specifier works correctly for NSInteger.
342   const struct {
343     NSInteger value;
344     const char* expected;
345     const char* expected_hex;
346   } nsinteger_cases[] = {
347 #if !defined(ARCH_CPU_64_BITS)
348     {12345678, "12345678", "bc614e"},
349     {-12345678, "-12345678", "ff439eb2"},
350 #else
351     {12345678, "12345678", "bc614e"},
352     {-12345678, "-12345678", "ffffffffff439eb2"},
353     {137451299150l, "137451299150", "2000bc614e"},
354     {-137451299150l, "-137451299150", "ffffffdfff439eb2"},
355 #endif  // !defined(ARCH_CPU_64_BITS)
356   };
358   for (size_t i = 0; i < arraysize(nsinteger_cases); ++i) {
359     EXPECT_EQ(nsinteger_cases[i].expected,
360               StringPrintf("%" PRIdNS, nsinteger_cases[i].value));
361     EXPECT_EQ(nsinteger_cases[i].expected_hex,
362               StringPrintf("%" PRIxNS, nsinteger_cases[i].value));
363   }
365   // Check that format specifier works correctly for NSUInteger.
366   const struct {
367     NSUInteger value;
368     const char* expected;
369     const char* expected_hex;
370   } nsuinteger_cases[] = {
371 #if !defined(ARCH_CPU_64_BITS)
372     {12345678u, "12345678", "bc614e"},
373     {4282621618u, "4282621618", "ff439eb2"},
374 #else
375     {12345678u, "12345678", "bc614e"},
376     {4282621618u, "4282621618", "ff439eb2"},
377     {137451299150ul, "137451299150", "2000bc614e"},
378     {18446743936258252466ul, "18446743936258252466", "ffffffdfff439eb2"},
379 #endif  // !defined(ARCH_CPU_64_BITS)
380   };
382   for (size_t i = 0; i < arraysize(nsuinteger_cases); ++i) {
383     EXPECT_EQ(nsuinteger_cases[i].expected,
384               StringPrintf("%" PRIuNS, nsuinteger_cases[i].value));
385     EXPECT_EQ(nsuinteger_cases[i].expected_hex,
386               StringPrintf("%" PRIxNS, nsuinteger_cases[i].value));
387   }
390 }  // namespace mac
391 }  // namespace base