• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
14namespace base {
15namespace mac {
16
17TEST(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
157TEST(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
268TEST(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
306TEST(FoundationUtilTest, FilePathToNSString) {
307  EXPECT_NSEQ(nil, FilePathToNSString(FilePath()));
308  EXPECT_NSEQ(@"/a/b", FilePathToNSString(FilePath("/a/b")));
309}
310
311TEST(FoundationUtilTest, NSStringToFilePath) {
312  EXPECT_EQ(FilePath(), NSStringToFilePath(nil));
313  EXPECT_EQ(FilePath(), NSStringToFilePath(@""));
314  EXPECT_EQ(FilePath("/a/b"), NSStringToFilePath(@"/a/b"));
315}
316
317}  // namespace mac
318}  // namespace base
319