// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/mac/foundation_util.h" #include "base/basictypes.h" #include "base/files/file_path.h" #include "base/mac/scoped_cftyperef.h" #include "base/mac/scoped_nsautorelease_pool.h" #include "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" namespace base { namespace mac { TEST(FoundationUtilTest, CFCast) { // Build out the CF types to be tested as empty containers. ScopedCFTypeRef test_array( CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks)); ScopedCFTypeRef test_array_mutable( CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)); ScopedCFTypeRef test_bag( CFBagCreate(NULL, NULL, 0, &kCFTypeBagCallBacks)); ScopedCFTypeRef test_bag_mutable( CFBagCreateMutable(NULL, 0, &kCFTypeBagCallBacks)); CFTypeRef test_bool = kCFBooleanTrue; ScopedCFTypeRef test_data( CFDataCreate(NULL, NULL, 0)); ScopedCFTypeRef test_data_mutable( CFDataCreateMutable(NULL, 0)); ScopedCFTypeRef test_date( CFDateCreate(NULL, 0)); ScopedCFTypeRef test_dict( CFDictionaryCreate(NULL, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); ScopedCFTypeRef test_dict_mutable( CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); int int_val = 256; ScopedCFTypeRef test_number( CFNumberCreate(NULL, kCFNumberIntType, &int_val)); CFTypeRef test_null = kCFNull; ScopedCFTypeRef test_set( CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks)); ScopedCFTypeRef test_set_mutable( CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks)); ScopedCFTypeRef test_str( CFStringCreateWithBytes(NULL, NULL, 0, kCFStringEncodingASCII, false)); CFTypeRef test_str_const = CFSTR("hello"); ScopedCFTypeRef test_str_mutable(CFStringCreateMutable(NULL, 0)); // Make sure the allocations of CF types are good. EXPECT_TRUE(test_array); EXPECT_TRUE(test_array_mutable); EXPECT_TRUE(test_bag); EXPECT_TRUE(test_bag_mutable); EXPECT_TRUE(test_bool); EXPECT_TRUE(test_data); EXPECT_TRUE(test_data_mutable); EXPECT_TRUE(test_date); EXPECT_TRUE(test_dict); EXPECT_TRUE(test_dict_mutable); EXPECT_TRUE(test_number); EXPECT_TRUE(test_null); EXPECT_TRUE(test_set); EXPECT_TRUE(test_set_mutable); EXPECT_TRUE(test_str); EXPECT_TRUE(test_str_const); EXPECT_TRUE(test_str_mutable); // Casting the CFTypeRef objects correctly provides the same pointer. EXPECT_EQ(test_array, CFCast(test_array)); EXPECT_EQ(test_array_mutable, CFCast(test_array_mutable)); EXPECT_EQ(test_bag, CFCast(test_bag)); EXPECT_EQ(test_bag_mutable, CFCast(test_bag_mutable)); EXPECT_EQ(test_bool, CFCast(test_bool)); EXPECT_EQ(test_data, CFCast(test_data)); EXPECT_EQ(test_data_mutable, CFCast(test_data_mutable)); EXPECT_EQ(test_date, CFCast(test_date)); EXPECT_EQ(test_dict, CFCast(test_dict)); EXPECT_EQ(test_dict_mutable, CFCast(test_dict_mutable)); EXPECT_EQ(test_number, CFCast(test_number)); EXPECT_EQ(test_null, CFCast(test_null)); EXPECT_EQ(test_set, CFCast(test_set)); EXPECT_EQ(test_set_mutable, CFCast(test_set_mutable)); EXPECT_EQ(test_str, CFCast(test_str)); EXPECT_EQ(test_str_const, CFCast(test_str_const)); EXPECT_EQ(test_str_mutable, CFCast(test_str_mutable)); // When given an incorrect CF cast, provide NULL. EXPECT_FALSE(CFCast(test_array)); EXPECT_FALSE(CFCast(test_array_mutable)); EXPECT_FALSE(CFCast(test_bag)); EXPECT_FALSE(CFCast(test_bag_mutable)); EXPECT_FALSE(CFCast(test_bool)); EXPECT_FALSE(CFCast(test_data)); EXPECT_FALSE(CFCast(test_data_mutable)); EXPECT_FALSE(CFCast(test_date)); EXPECT_FALSE(CFCast(test_dict)); EXPECT_FALSE(CFCast(test_dict_mutable)); EXPECT_FALSE(CFCast(test_number)); EXPECT_FALSE(CFCast(test_null)); EXPECT_FALSE(CFCast(test_set)); EXPECT_FALSE(CFCast(test_set_mutable)); EXPECT_FALSE(CFCast(test_str)); EXPECT_FALSE(CFCast(test_str_const)); EXPECT_FALSE(CFCast(test_str_mutable)); // Giving a NULL provides a NULL. EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); EXPECT_FALSE(CFCast(NULL)); // CFCastStrict: correct cast results in correct pointer being returned. EXPECT_EQ(test_array, CFCastStrict(test_array)); EXPECT_EQ(test_array_mutable, CFCastStrict(test_array_mutable)); EXPECT_EQ(test_bag, CFCastStrict(test_bag)); EXPECT_EQ(test_bag_mutable, CFCastStrict(test_bag_mutable)); EXPECT_EQ(test_bool, CFCastStrict(test_bool)); EXPECT_EQ(test_data, CFCastStrict(test_data)); EXPECT_EQ(test_data_mutable, CFCastStrict(test_data_mutable)); EXPECT_EQ(test_date, CFCastStrict(test_date)); EXPECT_EQ(test_dict, CFCastStrict(test_dict)); EXPECT_EQ(test_dict_mutable, CFCastStrict(test_dict_mutable)); EXPECT_EQ(test_number, CFCastStrict(test_number)); EXPECT_EQ(test_null, CFCastStrict(test_null)); EXPECT_EQ(test_set, CFCastStrict(test_set)); EXPECT_EQ(test_set_mutable, CFCastStrict(test_set_mutable)); EXPECT_EQ(test_str, CFCastStrict(test_str)); EXPECT_EQ(test_str_const, CFCastStrict(test_str_const)); EXPECT_EQ(test_str_mutable, CFCastStrict(test_str_mutable)); // CFCastStrict: Giving a NULL provides a NULL. EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); EXPECT_FALSE(CFCastStrict(NULL)); } TEST(FoundationUtilTest, ObjCCast) { ScopedNSAutoreleasePool pool; id test_array = [NSArray array]; id test_array_mutable = [NSMutableArray array]; id test_data = [NSData data]; id test_data_mutable = [NSMutableData dataWithCapacity:10]; id test_date = [NSDate date]; id test_dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42] forKey:@"meaning"]; id test_dict_mutable = [NSMutableDictionary dictionaryWithCapacity:10]; id test_number = [NSNumber numberWithInt:42]; id test_null = [NSNull null]; id test_set = [NSSet setWithObject:@"string object"]; id test_set_mutable = [NSMutableSet setWithCapacity:10]; id test_str = [NSString string]; id test_str_const = @"bonjour"; id test_str_mutable = [NSMutableString stringWithCapacity:10]; // Make sure the allocations of NS types are good. EXPECT_TRUE(test_array); EXPECT_TRUE(test_array_mutable); EXPECT_TRUE(test_data); EXPECT_TRUE(test_data_mutable); EXPECT_TRUE(test_date); EXPECT_TRUE(test_dict); EXPECT_TRUE(test_dict_mutable); EXPECT_TRUE(test_number); EXPECT_TRUE(test_null); EXPECT_TRUE(test_set); EXPECT_TRUE(test_set_mutable); EXPECT_TRUE(test_str); EXPECT_TRUE(test_str_const); EXPECT_TRUE(test_str_mutable); // Casting the id correctly provides the same pointer. EXPECT_EQ(test_array, ObjCCast(test_array)); EXPECT_EQ(test_array_mutable, ObjCCast(test_array_mutable)); EXPECT_EQ(test_data, ObjCCast(test_data)); EXPECT_EQ(test_data_mutable, ObjCCast(test_data_mutable)); EXPECT_EQ(test_date, ObjCCast(test_date)); EXPECT_EQ(test_dict, ObjCCast(test_dict)); EXPECT_EQ(test_dict_mutable, ObjCCast(test_dict_mutable)); EXPECT_EQ(test_number, ObjCCast(test_number)); EXPECT_EQ(test_null, ObjCCast(test_null)); EXPECT_EQ(test_set, ObjCCast(test_set)); EXPECT_EQ(test_set_mutable, ObjCCast(test_set_mutable)); EXPECT_EQ(test_str, ObjCCast(test_str)); EXPECT_EQ(test_str_const, ObjCCast(test_str_const)); EXPECT_EQ(test_str_mutable, ObjCCast(test_str_mutable)); // When given an incorrect ObjC cast, provide nil. EXPECT_FALSE(ObjCCast(test_array)); EXPECT_FALSE(ObjCCast(test_array_mutable)); EXPECT_FALSE(ObjCCast(test_data)); EXPECT_FALSE(ObjCCast(test_data_mutable)); EXPECT_FALSE(ObjCCast(test_date)); EXPECT_FALSE(ObjCCast(test_dict)); EXPECT_FALSE(ObjCCast(test_dict_mutable)); EXPECT_FALSE(ObjCCast(test_number)); EXPECT_FALSE(ObjCCast(test_null)); EXPECT_FALSE(ObjCCast(test_set)); EXPECT_FALSE(ObjCCast(test_set_mutable)); EXPECT_FALSE(ObjCCast(test_str)); EXPECT_FALSE(ObjCCast(test_str_const)); EXPECT_FALSE(ObjCCast(test_str_mutable)); // Giving a nil provides a nil. EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); EXPECT_FALSE(ObjCCast(nil)); // ObjCCastStrict: correct cast results in correct pointer being returned. EXPECT_EQ(test_array, ObjCCastStrict(test_array)); EXPECT_EQ(test_array_mutable, ObjCCastStrict(test_array_mutable)); EXPECT_EQ(test_data, ObjCCastStrict(test_data)); EXPECT_EQ(test_data_mutable, ObjCCastStrict(test_data_mutable)); EXPECT_EQ(test_date, ObjCCastStrict(test_date)); EXPECT_EQ(test_dict, ObjCCastStrict(test_dict)); EXPECT_EQ(test_dict_mutable, ObjCCastStrict(test_dict_mutable)); EXPECT_EQ(test_number, ObjCCastStrict(test_number)); EXPECT_EQ(test_null, ObjCCastStrict(test_null)); EXPECT_EQ(test_set, ObjCCastStrict(test_set)); EXPECT_EQ(test_set_mutable, ObjCCastStrict(test_set_mutable)); EXPECT_EQ(test_str, ObjCCastStrict(test_str)); EXPECT_EQ(test_str_const, ObjCCastStrict(test_str_const)); EXPECT_EQ(test_str_mutable, ObjCCastStrict(test_str_mutable)); // ObjCCastStrict: Giving a nil provides a nil. EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); EXPECT_FALSE(ObjCCastStrict(nil)); } TEST(FoundationUtilTest, GetValueFromDictionary) { int one = 1, two = 2, three = 3; ScopedCFTypeRef cf_one( CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &one)); ScopedCFTypeRef cf_two( CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &two)); ScopedCFTypeRef cf_three( CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &three)); CFStringRef keys[] = { CFSTR("one"), CFSTR("two"), CFSTR("three") }; CFNumberRef values[] = { cf_one, cf_two, cf_three }; COMPILE_ASSERT(arraysize(keys) == arraysize(values), keys_and_values_arraysizes_are_different); ScopedCFTypeRef test_dict( CFDictionaryCreate(kCFAllocatorDefault, reinterpret_cast(keys), reinterpret_cast(values), arraysize(values), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); // GetValueFromDictionary<>(_, _) should produce the correct // expected output. EXPECT_EQ(values[0], GetValueFromDictionary(test_dict, CFSTR("one"))); EXPECT_EQ(values[1], GetValueFromDictionary(test_dict, CFSTR("two"))); EXPECT_EQ(values[2], GetValueFromDictionary(test_dict, CFSTR("three"))); // Bad input should produce bad output. EXPECT_FALSE(GetValueFromDictionary(test_dict, CFSTR("four"))); EXPECT_FALSE(GetValueFromDictionary(test_dict, CFSTR("one"))); } TEST(FoundationUtilTest, FilePathToNSString) { EXPECT_NSEQ(nil, FilePathToNSString(FilePath())); EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b"))); } // http://crbug.com/173983 Fails consistently under Mac ASAN. TEST(FoundationUtilTest, DISABLED_NSStringToFilePath) { EXPECT_EQ(FilePath(), NSStringToFilePath(nil)); EXPECT_EQ(FilePath(), NSStringToFilePath(@"")); EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b")); } } // namespace mac } // namespace base