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