blob: 4653006b9ea97d08c2c91f727f76c1ee729289e5 [file] [log] [blame]
// 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/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"
TEST(FoundationUtilTest, CFCast) {
// Build out the CF types to be tested as empty containers.
base::mac::ScopedCFTypeRef<CFTypeRef> test_array(
CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_array_mutable(
CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_bag(
CFBagCreate(NULL, NULL, 0, &kCFTypeBagCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_bag_mutable(
CFBagCreateMutable(NULL, 0, &kCFTypeBagCallBacks));
CFTypeRef test_bool = kCFBooleanTrue;
base::mac::ScopedCFTypeRef<CFTypeRef> test_data(
CFDataCreate(NULL, NULL, 0));
base::mac::ScopedCFTypeRef<CFTypeRef> test_data_mutable(
CFDataCreateMutable(NULL, 0));
base::mac::ScopedCFTypeRef<CFTypeRef> test_date(
CFDateCreate(NULL, 0));
base::mac::ScopedCFTypeRef<CFTypeRef> test_dict(
CFDictionaryCreate(NULL, NULL, NULL, 0,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_dict_mutable(
CFDictionaryCreateMutable(NULL, 0,
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
int int_val = 256;
base::mac::ScopedCFTypeRef<CFTypeRef> test_number(
CFNumberCreate(NULL, kCFNumberIntType, &int_val));
CFTypeRef test_null = kCFNull;
base::mac::ScopedCFTypeRef<CFTypeRef> test_set(
CFSetCreate(NULL, NULL, 0, &kCFTypeSetCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_set_mutable(
CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks));
base::mac::ScopedCFTypeRef<CFTypeRef> test_str(
CFStringCreateWithBytes(NULL, NULL, 0, kCFStringEncodingASCII,
false));
CFTypeRef test_str_const = CFSTR("hello");
base::mac::ScopedCFTypeRef<CFTypeRef> 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, base::mac::CFCast<CFArrayRef>(test_array));
EXPECT_EQ(test_array_mutable,
base::mac::CFCast<CFArrayRef>(test_array_mutable));
EXPECT_EQ(test_bag, base::mac::CFCast<CFBagRef>(test_bag));
EXPECT_EQ(test_bag_mutable,
base::mac::CFCast<CFBagRef>(test_bag_mutable));
EXPECT_EQ(test_bool, base::mac::CFCast<CFBooleanRef>(test_bool));
EXPECT_EQ(test_data, base::mac::CFCast<CFDataRef>(test_data));
EXPECT_EQ(test_data_mutable,
base::mac::CFCast<CFDataRef>(test_data_mutable));
EXPECT_EQ(test_date, base::mac::CFCast<CFDateRef>(test_date));
EXPECT_EQ(test_dict, base::mac::CFCast<CFDictionaryRef>(test_dict));
EXPECT_EQ(test_dict_mutable,
base::mac::CFCast<CFDictionaryRef>(test_dict_mutable));
EXPECT_EQ(test_number, base::mac::CFCast<CFNumberRef>(test_number));
EXPECT_EQ(test_null, base::mac::CFCast<CFNullRef>(test_null));
EXPECT_EQ(test_set, base::mac::CFCast<CFSetRef>(test_set));
EXPECT_EQ(test_set_mutable, base::mac::CFCast<CFSetRef>(test_set_mutable));
EXPECT_EQ(test_str, base::mac::CFCast<CFStringRef>(test_str));
EXPECT_EQ(test_str_const, base::mac::CFCast<CFStringRef>(test_str_const));
EXPECT_EQ(test_str_mutable,
base::mac::CFCast<CFStringRef>(test_str_mutable));
// When given an incorrect CF cast, provide NULL.
EXPECT_FALSE(base::mac::CFCast<CFStringRef>(test_array));
EXPECT_FALSE(base::mac::CFCast<CFStringRef>(test_array_mutable));
EXPECT_FALSE(base::mac::CFCast<CFStringRef>(test_bag));
EXPECT_FALSE(base::mac::CFCast<CFSetRef>(test_bag_mutable));
EXPECT_FALSE(base::mac::CFCast<CFSetRef>(test_bool));
EXPECT_FALSE(base::mac::CFCast<CFNullRef>(test_data));
EXPECT_FALSE(base::mac::CFCast<CFDictionaryRef>(test_data_mutable));
EXPECT_FALSE(base::mac::CFCast<CFDictionaryRef>(test_date));
EXPECT_FALSE(base::mac::CFCast<CFNumberRef>(test_dict));
EXPECT_FALSE(base::mac::CFCast<CFDateRef>(test_dict_mutable));
EXPECT_FALSE(base::mac::CFCast<CFDataRef>(test_number));
EXPECT_FALSE(base::mac::CFCast<CFDataRef>(test_null));
EXPECT_FALSE(base::mac::CFCast<CFBooleanRef>(test_set));
EXPECT_FALSE(base::mac::CFCast<CFBagRef>(test_set_mutable));
EXPECT_FALSE(base::mac::CFCast<CFBagRef>(test_str));
EXPECT_FALSE(base::mac::CFCast<CFArrayRef>(test_str_const));
EXPECT_FALSE(base::mac::CFCast<CFArrayRef>(test_str_mutable));
// Giving a NULL provides a NULL.
EXPECT_FALSE(base::mac::CFCast<CFArrayRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFBagRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFBooleanRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFDataRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFDateRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFDictionaryRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFNullRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFNumberRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFSetRef>(NULL));
EXPECT_FALSE(base::mac::CFCast<CFStringRef>(NULL));
// CFCastStrict: correct cast results in correct pointer being returned.
EXPECT_EQ(test_array, base::mac::CFCastStrict<CFArrayRef>(test_array));
EXPECT_EQ(test_array_mutable,
base::mac::CFCastStrict<CFArrayRef>(test_array_mutable));
EXPECT_EQ(test_bag, base::mac::CFCastStrict<CFBagRef>(test_bag));
EXPECT_EQ(test_bag_mutable,
base::mac::CFCastStrict<CFBagRef>(test_bag_mutable));
EXPECT_EQ(test_bool, base::mac::CFCastStrict<CFBooleanRef>(test_bool));
EXPECT_EQ(test_data, base::mac::CFCastStrict<CFDataRef>(test_data));
EXPECT_EQ(test_data_mutable,
base::mac::CFCastStrict<CFDataRef>(test_data_mutable));
EXPECT_EQ(test_date, base::mac::CFCastStrict<CFDateRef>(test_date));
EXPECT_EQ(test_dict, base::mac::CFCastStrict<CFDictionaryRef>(test_dict));
EXPECT_EQ(test_dict_mutable,
base::mac::CFCastStrict<CFDictionaryRef>(test_dict_mutable));
EXPECT_EQ(test_number, base::mac::CFCastStrict<CFNumberRef>(test_number));
EXPECT_EQ(test_null, base::mac::CFCastStrict<CFNullRef>(test_null));
EXPECT_EQ(test_set, base::mac::CFCastStrict<CFSetRef>(test_set));
EXPECT_EQ(test_set_mutable,
base::mac::CFCastStrict<CFSetRef>(test_set_mutable));
EXPECT_EQ(test_str, base::mac::CFCastStrict<CFStringRef>(test_str));
EXPECT_EQ(test_str_const,
base::mac::CFCastStrict<CFStringRef>(test_str_const));
EXPECT_EQ(test_str_mutable,
base::mac::CFCastStrict<CFStringRef>(test_str_mutable));
// CFCastStrict: Giving a NULL provides a NULL.
EXPECT_FALSE(base::mac::CFCastStrict<CFArrayRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFBagRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFBooleanRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFDataRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFDateRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFDictionaryRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFNullRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFNumberRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFSetRef>(NULL));
EXPECT_FALSE(base::mac::CFCastStrict<CFStringRef>(NULL));
}
TEST(FoundationUtilTest, ObjCCast) {
base::mac::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, base::mac::ObjCCast<NSArray>(test_array));
EXPECT_EQ(test_array_mutable,
base::mac::ObjCCast<NSArray>(test_array_mutable));
EXPECT_EQ(test_data, base::mac::ObjCCast<NSData>(test_data));
EXPECT_EQ(test_data_mutable,
base::mac::ObjCCast<NSData>(test_data_mutable));
EXPECT_EQ(test_date, base::mac::ObjCCast<NSDate>(test_date));
EXPECT_EQ(test_dict, base::mac::ObjCCast<NSDictionary>(test_dict));
EXPECT_EQ(test_dict_mutable,
base::mac::ObjCCast<NSDictionary>(test_dict_mutable));
EXPECT_EQ(test_number, base::mac::ObjCCast<NSNumber>(test_number));
EXPECT_EQ(test_null, base::mac::ObjCCast<NSNull>(test_null));
EXPECT_EQ(test_set, base::mac::ObjCCast<NSSet>(test_set));
EXPECT_EQ(test_set_mutable, base::mac::ObjCCast<NSSet>(test_set_mutable));
EXPECT_EQ(test_str, base::mac::ObjCCast<NSString>(test_str));
EXPECT_EQ(test_str_const, base::mac::ObjCCast<NSString>(test_str_const));
EXPECT_EQ(test_str_mutable,
base::mac::ObjCCast<NSString>(test_str_mutable));
// When given an incorrect ObjC cast, provide nil.
EXPECT_FALSE(base::mac::ObjCCast<NSString>(test_array));
EXPECT_FALSE(base::mac::ObjCCast<NSString>(test_array_mutable));
EXPECT_FALSE(base::mac::ObjCCast<NSString>(test_data));
EXPECT_FALSE(base::mac::ObjCCast<NSString>(test_data_mutable));
EXPECT_FALSE(base::mac::ObjCCast<NSSet>(test_date));
EXPECT_FALSE(base::mac::ObjCCast<NSSet>(test_dict));
EXPECT_FALSE(base::mac::ObjCCast<NSNumber>(test_dict_mutable));
EXPECT_FALSE(base::mac::ObjCCast<NSNull>(test_number));
EXPECT_FALSE(base::mac::ObjCCast<NSDictionary>(test_null));
EXPECT_FALSE(base::mac::ObjCCast<NSDictionary>(test_set));
EXPECT_FALSE(base::mac::ObjCCast<NSDate>(test_set_mutable));
EXPECT_FALSE(base::mac::ObjCCast<NSData>(test_str));
EXPECT_FALSE(base::mac::ObjCCast<NSData>(test_str_const));
EXPECT_FALSE(base::mac::ObjCCast<NSArray>(test_str_mutable));
// Giving a nil provides a nil.
EXPECT_FALSE(base::mac::ObjCCast<NSArray>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSData>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSDate>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSDictionary>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSNull>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSNumber>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSSet>(nil));
EXPECT_FALSE(base::mac::ObjCCast<NSString>(nil));
// ObjCCastStrict: correct cast results in correct pointer being returned.
EXPECT_EQ(test_array, base::mac::ObjCCastStrict<NSArray>(test_array));
EXPECT_EQ(test_array_mutable,
base::mac::ObjCCastStrict<NSArray>(test_array_mutable));
EXPECT_EQ(test_data, base::mac::ObjCCastStrict<NSData>(test_data));
EXPECT_EQ(test_data_mutable,
base::mac::ObjCCastStrict<NSData>(test_data_mutable));
EXPECT_EQ(test_date, base::mac::ObjCCastStrict<NSDate>(test_date));
EXPECT_EQ(test_dict, base::mac::ObjCCastStrict<NSDictionary>(test_dict));
EXPECT_EQ(test_dict_mutable,
base::mac::ObjCCastStrict<NSDictionary>(test_dict_mutable));
EXPECT_EQ(test_number, base::mac::ObjCCastStrict<NSNumber>(test_number));
EXPECT_EQ(test_null, base::mac::ObjCCastStrict<NSNull>(test_null));
EXPECT_EQ(test_set, base::mac::ObjCCastStrict<NSSet>(test_set));
EXPECT_EQ(test_set_mutable,
base::mac::ObjCCastStrict<NSSet>(test_set_mutable));
EXPECT_EQ(test_str, base::mac::ObjCCastStrict<NSString>(test_str));
EXPECT_EQ(test_str_const,
base::mac::ObjCCastStrict<NSString>(test_str_const));
EXPECT_EQ(test_str_mutable,
base::mac::ObjCCastStrict<NSString>(test_str_mutable));
// ObjCCastStrict: Giving a nil provides a nil.
EXPECT_FALSE(base::mac::ObjCCastStrict<NSArray>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSData>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSDate>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSDictionary>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSNull>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSNumber>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSSet>(nil));
EXPECT_FALSE(base::mac::ObjCCastStrict<NSString>(nil));
}
TEST(FoundationUtilTest, GetValueFromDictionary) {
int one = 1, two = 2, three = 3;
base::mac::ScopedCFTypeRef<CFNumberRef> cf_one(
CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &one));
base::mac::ScopedCFTypeRef<CFNumberRef> cf_two(
CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &two));
base::mac::ScopedCFTypeRef<CFNumberRef> 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);
base::mac::ScopedCFTypeRef<CFDictionaryRef> test_dict(
CFDictionaryCreate(kCFAllocatorDefault,
reinterpret_cast<const void**>(keys),
reinterpret_cast<const void**>(values),
arraysize(values),
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks));
// base::mac::GetValueFromDictionary<>(_, _) should produce the correct
// expected output.
EXPECT_EQ(values[0],
base::mac::GetValueFromDictionary<CFNumberRef>(test_dict,
CFSTR("one")));
EXPECT_EQ(values[1],
base::mac::GetValueFromDictionary<CFNumberRef>(test_dict,
CFSTR("two")));
EXPECT_EQ(values[2],
base::mac::GetValueFromDictionary<CFNumberRef>(test_dict,
CFSTR("three")));
// Bad input should produce bad output.
EXPECT_FALSE(base::mac::GetValueFromDictionary<CFNumberRef>(test_dict,
CFSTR("four")));
EXPECT_FALSE(base::mac::GetValueFromDictionary<CFStringRef>(test_dict,
CFSTR("one")));
}
TEST(FoundationUtilTest, FilePathToNSString) {
EXPECT_NSEQ(nil, base::mac::FilePathToNSString(FilePath()));
EXPECT_NSEQ(@"/a/b", base::mac::FilePathToNSString(FilePath("/a/b")));
}
TEST(FoundationUtilTest, NSStringToFilePath) {
EXPECT_EQ(FilePath(), base::mac::NSStringToFilePath(nil));
EXPECT_EQ(FilePath(), base::mac::NSStringToFilePath(@""));
EXPECT_EQ(FilePath("/a/b"), base::mac::NSStringToFilePath(@"/a/b"));
}