Home | History | Annotate | Download | only in mac
      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.
      4 
      5 #include "base/mac/foundation_util.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/files/file_path.h"
      9 #include "base/mac/scoped_cftyperef.h"
     10 #include "base/mac/scoped_nsautorelease_pool.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 #import "testing/gtest_mac.h"
     13 
     14 namespace base {
     15 namespace mac {
     16 
     17 TEST(FoundationUtilTest, CFCast) {
     18   // Build out the CF types to be tested as empty containers.
     19   ScopedCFTypeRef<CFTypeRef> test_array(
     20       CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks));
     21   ScopedCFTypeRef<CFTypeRef> test_array_mutable(
     22       CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
     23   ScopedCFTypeRef<CFTypeRef> test_bag(
     24       CFBagCreate(NULL, NULL, 0, &kCFTypeBagCallBacks));
     25   ScopedCFTypeRef<CFTypeRef> test_bag_mutable(
     26       CFBagCreateMutable(NULL, 0, &kCFTypeBagCallBacks));
     27   CFTypeRef test_bool = kCFBooleanTrue;
     28   ScopedCFTypeRef<CFTypeRef> test_data(
     29       CFDataCreate(NULL, NULL, 0));
     30   ScopedCFTypeRef<CFTypeRef> test_data_mutable(
     31       CFDataCreateMutable(NULL, 0));
     32   ScopedCFTypeRef<CFTypeRef> test_date(
     33       CFDateCreate(NULL, 0));
     34   ScopedCFTypeRef<CFTypeRef> test_dict(
     35       CFDictionaryCreate(NULL, NULL, NULL, 0,
     36                          &kCFCopyStringDictionaryKeyCallBacks,
     37                          &kCFTypeDictionaryValueCallBacks));
     38   ScopedCFTypeRef<CFTypeRef> test_dict_mutable(
     39       CFDictionaryCreateMutable(NULL, 0,
     40                                 &kCFCopyStringDictionaryKeyCallBacks,
     41                                 &kCFTypeDictionaryValueCallBacks));
     42   int int_val = 256;
     43   ScopedCFTypeRef<CFTypeRef> test_number(
     44       CFNumberCreate(NULL, kCFNumberIntType, &int_val));
     45   CFTypeRef test_null = kCFNull;
     46   ScopedCFTypeRef<CFTypeRef> test_set(
     47       CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks));
     48   ScopedCFTypeRef<CFTypeRef> test_set_mutable(
     49       CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks));
     50   ScopedCFTypeRef<CFTypeRef> test_str(
     51       CFStringCreateWithBytes(NULL, NULL, 0, kCFStringEncodingASCII, false));
     52   CFTypeRef test_str_const = CFSTR("hello");
     53   ScopedCFTypeRef<CFTypeRef> test_str_mutable(CFStringCreateMutable(NULL, 0));
     54 
     55   // Make sure the allocations of CF types are good.
     56   EXPECT_TRUE(test_array);
     57   EXPECT_TRUE(test_array_mutable);
     58   EXPECT_TRUE(test_bag);
     59   EXPECT_TRUE(test_bag_mutable);
     60   EXPECT_TRUE(test_bool);
     61   EXPECT_TRUE(test_data);
     62   EXPECT_TRUE(test_data_mutable);
     63   EXPECT_TRUE(test_date);
     64   EXPECT_TRUE(test_dict);
     65   EXPECT_TRUE(test_dict_mutable);
     66   EXPECT_TRUE(test_number);
     67   EXPECT_TRUE(test_null);
     68   EXPECT_TRUE(test_set);
     69   EXPECT_TRUE(test_set_mutable);
     70   EXPECT_TRUE(test_str);
     71   EXPECT_TRUE(test_str_const);
     72   EXPECT_TRUE(test_str_mutable);
     73 
     74   // Casting the CFTypeRef objects correctly provides the same pointer.
     75   EXPECT_EQ(test_array, CFCast<CFArrayRef>(test_array));
     76   EXPECT_EQ(test_array_mutable, CFCast<CFArrayRef>(test_array_mutable));
     77   EXPECT_EQ(test_bag, CFCast<CFBagRef>(test_bag));
     78   EXPECT_EQ(test_bag_mutable, CFCast<CFBagRef>(test_bag_mutable));
     79   EXPECT_EQ(test_bool, CFCast<CFBooleanRef>(test_bool));
     80   EXPECT_EQ(test_data, CFCast<CFDataRef>(test_data));
     81   EXPECT_EQ(test_data_mutable, CFCast<CFDataRef>(test_data_mutable));
     82   EXPECT_EQ(test_date, CFCast<CFDateRef>(test_date));
     83   EXPECT_EQ(test_dict, CFCast<CFDictionaryRef>(test_dict));
     84   EXPECT_EQ(test_dict_mutable, CFCast<CFDictionaryRef>(test_dict_mutable));
     85   EXPECT_EQ(test_number, CFCast<CFNumberRef>(test_number));
     86   EXPECT_EQ(test_null, CFCast<CFNullRef>(test_null));
     87   EXPECT_EQ(test_set, CFCast<CFSetRef>(test_set));
     88   EXPECT_EQ(test_set_mutable, CFCast<CFSetRef>(test_set_mutable));
     89   EXPECT_EQ(test_str, CFCast<CFStringRef>(test_str));
     90   EXPECT_EQ(test_str_const, CFCast<CFStringRef>(test_str_const));
     91   EXPECT_EQ(test_str_mutable, CFCast<CFStringRef>(test_str_mutable));
     92 
     93   // When given an incorrect CF cast, provide NULL.
     94   EXPECT_FALSE(CFCast<CFStringRef>(test_array));
     95   EXPECT_FALSE(CFCast<CFStringRef>(test_array_mutable));
     96   EXPECT_FALSE(CFCast<CFStringRef>(test_bag));
     97   EXPECT_FALSE(CFCast<CFSetRef>(test_bag_mutable));
     98   EXPECT_FALSE(CFCast<CFSetRef>(test_bool));
     99   EXPECT_FALSE(CFCast<CFNullRef>(test_data));
    100   EXPECT_FALSE(CFCast<CFDictionaryRef>(test_data_mutable));
    101   EXPECT_FALSE(CFCast<CFDictionaryRef>(test_date));
    102   EXPECT_FALSE(CFCast<CFNumberRef>(test_dict));
    103   EXPECT_FALSE(CFCast<CFDateRef>(test_dict_mutable));
    104   EXPECT_FALSE(CFCast<CFDataRef>(test_number));
    105   EXPECT_FALSE(CFCast<CFDataRef>(test_null));
    106   EXPECT_FALSE(CFCast<CFBooleanRef>(test_set));
    107   EXPECT_FALSE(CFCast<CFBagRef>(test_set_mutable));
    108   EXPECT_FALSE(CFCast<CFBagRef>(test_str));
    109   EXPECT_FALSE(CFCast<CFArrayRef>(test_str_const));
    110   EXPECT_FALSE(CFCast<CFArrayRef>(test_str_mutable));
    111 
    112   // Giving a NULL provides a NULL.
    113   EXPECT_FALSE(CFCast<CFArrayRef>(NULL));
    114   EXPECT_FALSE(CFCast<CFBagRef>(NULL));
    115   EXPECT_FALSE(CFCast<CFBooleanRef>(NULL));
    116   EXPECT_FALSE(CFCast<CFDataRef>(NULL));
    117   EXPECT_FALSE(CFCast<CFDateRef>(NULL));
    118   EXPECT_FALSE(CFCast<CFDictionaryRef>(NULL));
    119   EXPECT_FALSE(CFCast<CFNullRef>(NULL));
    120   EXPECT_FALSE(CFCast<CFNumberRef>(NULL));
    121   EXPECT_FALSE(CFCast<CFSetRef>(NULL));
    122   EXPECT_FALSE(CFCast<CFStringRef>(NULL));
    123 
    124   // CFCastStrict: correct cast results in correct pointer being returned.
    125   EXPECT_EQ(test_array, CFCastStrict<CFArrayRef>(test_array));
    126   EXPECT_EQ(test_array_mutable, CFCastStrict<CFArrayRef>(test_array_mutable));
    127   EXPECT_EQ(test_bag, CFCastStrict<CFBagRef>(test_bag));
    128   EXPECT_EQ(test_bag_mutable, CFCastStrict<CFBagRef>(test_bag_mutable));
    129   EXPECT_EQ(test_bool, CFCastStrict<CFBooleanRef>(test_bool));
    130   EXPECT_EQ(test_data, CFCastStrict<CFDataRef>(test_data));
    131   EXPECT_EQ(test_data_mutable, CFCastStrict<CFDataRef>(test_data_mutable));
    132   EXPECT_EQ(test_date, CFCastStrict<CFDateRef>(test_date));
    133   EXPECT_EQ(test_dict, CFCastStrict<CFDictionaryRef>(test_dict));
    134   EXPECT_EQ(test_dict_mutable,
    135             CFCastStrict<CFDictionaryRef>(test_dict_mutable));
    136   EXPECT_EQ(test_number, CFCastStrict<CFNumberRef>(test_number));
    137   EXPECT_EQ(test_null, CFCastStrict<CFNullRef>(test_null));
    138   EXPECT_EQ(test_set, CFCastStrict<CFSetRef>(test_set));
    139   EXPECT_EQ(test_set_mutable, CFCastStrict<CFSetRef>(test_set_mutable));
    140   EXPECT_EQ(test_str, CFCastStrict<CFStringRef>(test_str));
    141   EXPECT_EQ(test_str_const, CFCastStrict<CFStringRef>(test_str_const));
    142   EXPECT_EQ(test_str_mutable, CFCastStrict<CFStringRef>(test_str_mutable));
    143 
    144   // CFCastStrict: Giving a NULL provides a NULL.
    145   EXPECT_FALSE(CFCastStrict<CFArrayRef>(NULL));
    146   EXPECT_FALSE(CFCastStrict<CFBagRef>(NULL));
    147   EXPECT_FALSE(CFCastStrict<CFBooleanRef>(NULL));
    148   EXPECT_FALSE(CFCastStrict<CFDataRef>(NULL));
    149   EXPECT_FALSE(CFCastStrict<CFDateRef>(NULL));
    150   EXPECT_FALSE(CFCastStrict<CFDictionaryRef>(NULL));
    151   EXPECT_FALSE(CFCastStrict<CFNullRef>(NULL));
    152   EXPECT_FALSE(CFCastStrict<CFNumberRef>(NULL));
    153   EXPECT_FALSE(CFCastStrict<CFSetRef>(NULL));
    154   EXPECT_FALSE(CFCastStrict<CFStringRef>(NULL));
    155 }
    156 
    157 TEST(FoundationUtilTest, ObjCCast) {
    158   ScopedNSAutoreleasePool pool;
    159 
    160   id test_array = [NSArray array];
    161   id test_array_mutable = [NSMutableArray array];
    162   id test_data = [NSData data];
    163   id test_data_mutable = [NSMutableData dataWithCapacity:10];
    164   id test_date = [NSDate date];
    165   id test_dict =
    166       [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42]
    167                                   forKey:@"meaning"];
    168   id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10];
    169   id test_number = [NSNumber numberWithInt:42];
    170   id test_null = [NSNull null];
    171   id test_set = [NSSet setWithObject:@"string object"];
    172   id test_set_mutable = [NSMutableSet setWithCapacity:10];
    173   id test_str = [NSString string];
    174   id test_str_const = @"bonjour";
    175   id test_str_mutable = [NSMutableString stringWithCapacity:10];
    176 
    177   // Make sure the allocations of NS types are good.
    178   EXPECT_TRUE(test_array);
    179   EXPECT_TRUE(test_array_mutable);
    180   EXPECT_TRUE(test_data);
    181   EXPECT_TRUE(test_data_mutable);
    182   EXPECT_TRUE(test_date);
    183   EXPECT_TRUE(test_dict);
    184   EXPECT_TRUE(test_dict_mutable);
    185   EXPECT_TRUE(test_number);
    186   EXPECT_TRUE(test_null);
    187   EXPECT_TRUE(test_set);
    188   EXPECT_TRUE(test_set_mutable);
    189   EXPECT_TRUE(test_str);
    190   EXPECT_TRUE(test_str_const);
    191   EXPECT_TRUE(test_str_mutable);
    192 
    193   // Casting the id correctly provides the same pointer.
    194   EXPECT_EQ(test_array, ObjCCast<NSArray>(test_array));
    195   EXPECT_EQ(test_array_mutable, ObjCCast<NSArray>(test_array_mutable));
    196   EXPECT_EQ(test_data, ObjCCast<NSData>(test_data));
    197   EXPECT_EQ(test_data_mutable, ObjCCast<NSData>(test_data_mutable));
    198   EXPECT_EQ(test_date, ObjCCast<NSDate>(test_date));
    199   EXPECT_EQ(test_dict, ObjCCast<NSDictionary>(test_dict));
    200   EXPECT_EQ(test_dict_mutable, ObjCCast<NSDictionary>(test_dict_mutable));
    201   EXPECT_EQ(test_number, ObjCCast<NSNumber>(test_number));
    202   EXPECT_EQ(test_null, ObjCCast<NSNull>(test_null));
    203   EXPECT_EQ(test_set, ObjCCast<NSSet>(test_set));
    204   EXPECT_EQ(test_set_mutable, ObjCCast<NSSet>(test_set_mutable));
    205   EXPECT_EQ(test_str, ObjCCast<NSString>(test_str));
    206   EXPECT_EQ(test_str_const, ObjCCast<NSString>(test_str_const));
    207   EXPECT_EQ(test_str_mutable, ObjCCast<NSString>(test_str_mutable));
    208 
    209   // When given an incorrect ObjC cast, provide nil.
    210   EXPECT_FALSE(ObjCCast<NSString>(test_array));
    211   EXPECT_FALSE(ObjCCast<NSString>(test_array_mutable));
    212   EXPECT_FALSE(ObjCCast<NSString>(test_data));
    213   EXPECT_FALSE(ObjCCast<NSString>(test_data_mutable));
    214   EXPECT_FALSE(ObjCCast<NSSet>(test_date));
    215   EXPECT_FALSE(ObjCCast<NSSet>(test_dict));
    216   EXPECT_FALSE(ObjCCast<NSNumber>(test_dict_mutable));
    217   EXPECT_FALSE(ObjCCast<NSNull>(test_number));
    218   EXPECT_FALSE(ObjCCast<NSDictionary>(test_null));
    219   EXPECT_FALSE(ObjCCast<NSDictionary>(test_set));
    220   EXPECT_FALSE(ObjCCast<NSDate>(test_set_mutable));
    221   EXPECT_FALSE(ObjCCast<NSData>(test_str));
    222   EXPECT_FALSE(ObjCCast<NSData>(test_str_const));
    223   EXPECT_FALSE(ObjCCast<NSArray>(test_str_mutable));
    224 
    225   // Giving a nil provides a nil.
    226   EXPECT_FALSE(ObjCCast<NSArray>(nil));
    227   EXPECT_FALSE(ObjCCast<NSData>(nil));
    228   EXPECT_FALSE(ObjCCast<NSDate>(nil));
    229   EXPECT_FALSE(ObjCCast<NSDictionary>(nil));
    230   EXPECT_FALSE(ObjCCast<NSNull>(nil));
    231   EXPECT_FALSE(ObjCCast<NSNumber>(nil));
    232   EXPECT_FALSE(ObjCCast<NSSet>(nil));
    233   EXPECT_FALSE(ObjCCast<NSString>(nil));
    234 
    235   // ObjCCastStrict: correct cast results in correct pointer being returned.
    236   EXPECT_EQ(test_array, ObjCCastStrict<NSArray>(test_array));
    237   EXPECT_EQ(test_array_mutable,
    238             ObjCCastStrict<NSArray>(test_array_mutable));
    239   EXPECT_EQ(test_data, ObjCCastStrict<NSData>(test_data));
    240   EXPECT_EQ(test_data_mutable,
    241             ObjCCastStrict<NSData>(test_data_mutable));
    242   EXPECT_EQ(test_date, ObjCCastStrict<NSDate>(test_date));
    243   EXPECT_EQ(test_dict, ObjCCastStrict<NSDictionary>(test_dict));
    244   EXPECT_EQ(test_dict_mutable,
    245             ObjCCastStrict<NSDictionary>(test_dict_mutable));
    246   EXPECT_EQ(test_number, ObjCCastStrict<NSNumber>(test_number));
    247   EXPECT_EQ(test_null, ObjCCastStrict<NSNull>(test_null));
    248   EXPECT_EQ(test_set, ObjCCastStrict<NSSet>(test_set));
    249   EXPECT_EQ(test_set_mutable,
    250             ObjCCastStrict<NSSet>(test_set_mutable));
    251   EXPECT_EQ(test_str, ObjCCastStrict<NSString>(test_str));
    252   EXPECT_EQ(test_str_const,
    253             ObjCCastStrict<NSString>(test_str_const));
    254   EXPECT_EQ(test_str_mutable,
    255             ObjCCastStrict<NSString>(test_str_mutable));
    256 
    257   // ObjCCastStrict: Giving a nil provides a nil.
    258   EXPECT_FALSE(ObjCCastStrict<NSArray>(nil));
    259   EXPECT_FALSE(ObjCCastStrict<NSData>(nil));
    260   EXPECT_FALSE(ObjCCastStrict<NSDate>(nil));
    261   EXPECT_FALSE(ObjCCastStrict<NSDictionary>(nil));
    262   EXPECT_FALSE(ObjCCastStrict<NSNull>(nil));
    263   EXPECT_FALSE(ObjCCastStrict<NSNumber>(nil));
    264   EXPECT_FALSE(ObjCCastStrict<NSSet>(nil));
    265   EXPECT_FALSE(ObjCCastStrict<NSString>(nil));
    266 }
    267 
    268 TEST(FoundationUtilTest, GetValueFromDictionary) {
    269   int one = 1, two = 2, three = 3;
    270 
    271   ScopedCFTypeRef<CFNumberRef> cf_one(
    272       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &one));
    273   ScopedCFTypeRef<CFNumberRef> cf_two(
    274       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &two));
    275   ScopedCFTypeRef<CFNumberRef> cf_three(
    276       CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &three));
    277 
    278   CFStringRef keys[] = { CFSTR("one"), CFSTR("two"), CFSTR("three") };
    279   CFNumberRef values[] = { cf_one, cf_two, cf_three };
    280 
    281   COMPILE_ASSERT(arraysize(keys) == arraysize(values),
    282                  keys_and_values_arraysizes_are_different);
    283 
    284   ScopedCFTypeRef<CFDictionaryRef> test_dict(
    285       CFDictionaryCreate(kCFAllocatorDefault,
    286                          reinterpret_cast<const void**>(keys),
    287                          reinterpret_cast<const void**>(values),
    288                          arraysize(values),
    289                          &kCFCopyStringDictionaryKeyCallBacks,
    290                          &kCFTypeDictionaryValueCallBacks));
    291 
    292   // GetValueFromDictionary<>(_, _) should produce the correct
    293   // expected output.
    294   EXPECT_EQ(values[0],
    295             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("one")));
    296   EXPECT_EQ(values[1],
    297             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("two")));
    298   EXPECT_EQ(values[2],
    299             GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("three")));
    300 
    301   // Bad input should produce bad output.
    302   EXPECT_FALSE(GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("four")));
    303   EXPECT_FALSE(GetValueFromDictionary<CFStringRef>(test_dict, CFSTR("one")));
    304 }
    305 
    306 TEST(FoundationUtilTest, FilePathToNSString) {
    307   EXPECT_NSEQ(nil, FilePathToNSString(FilePath()));
    308   EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b")));
    309 }
    310 
    311 // http://crbug.com/173983 Fails consistently under Mac ASAN.
    312 TEST(FoundationUtilTest, DISABLED_NSStringToFilePath) {
    313   EXPECT_EQ(FilePath(), NSStringToFilePath(nil));
    314   EXPECT_EQ(FilePath(), NSStringToFilePath(@""));
    315   EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b"));
    316 }
    317 
    318 }  // namespace mac
    319 }  // namespace base
    320