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/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"
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));
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));
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);
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));
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));
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));
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));
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));
157 TEST(FoundationUtilTest, ObjCCast) {
158 ScopedNSAutoreleasePool pool;
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];
166 [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:42]
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];
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);
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));
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));
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));
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));
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));
268 TEST(FoundationUtilTest, GetValueFromDictionary) {
269 int one = 1, two = 2, three = 3;
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));
278 CFStringRef keys[] = { CFSTR("one"), CFSTR("two"), CFSTR("three") };
279 CFNumberRef values[] = { cf_one, cf_two, cf_three };
281 COMPILE_ASSERT(arraysize(keys) == arraysize(values),
282 keys_and_values_arraysizes_are_different);
284 ScopedCFTypeRef<CFDictionaryRef> test_dict(
285 CFDictionaryCreate(kCFAllocatorDefault,
286 reinterpret_cast<const void**>(keys),
287 reinterpret_cast<const void**>(values),
289 &kCFCopyStringDictionaryKeyCallBacks,
290 &kCFTypeDictionaryValueCallBacks));
292 // GetValueFromDictionary<>(_, _) should produce the correct
295 GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("one")));
297 GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("two")));
299 GetValueFromDictionary<CFNumberRef>(test_dict, CFSTR("three")));
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")));
306 TEST(FoundationUtilTest, FilePathToNSString) {
307 EXPECT_NSEQ(nil, FilePathToNSString(FilePath()));
308 EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b")));
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"));