PageRenderTime 126ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/externals/google-toolbox-for-mac/AddressBook/GTMABAddressBookTest.m

http://macfuse.googlecode.com/
Objective C | 695 lines | 552 code | 69 blank | 74 comment | 30 complexity | b8098fd9faf5c8bdc7712b2871acda5d MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. //
  2. // GTMAddressBookTest.m
  3. //
  4. // Copyright 2008 Google Inc.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7. // use this file except in compliance with the License. You may obtain a copy
  8. // of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. // License for the specific language governing permissions and limitations under
  16. // the License.
  17. //
  18. #import "GTMSenTestCase.h"
  19. #import "GTMABAddressBook.h"
  20. #if GTM_IPHONE_SDK
  21. #import "UIKit/UIKit.h"
  22. #else
  23. #import <AppKit/AppKit.h>
  24. #endif // GTM_IPHONE_SDK
  25. static NSString *const kGTMABTestFirstName = @"GTMABAddressBookTestFirstName";
  26. static NSString *const kGTMABTestLastName = @"GTMABAddressBookTestLastName";
  27. static NSString *const kGTMABTestGroupName = @"GTMABAddressBookTestGroupName";
  28. @interface GTMABAddressBookTest : GTMTestCase {
  29. @private
  30. GTMABAddressBook *book_;
  31. }
  32. @end
  33. @implementation GTMABAddressBookTest
  34. - (void)setUp {
  35. // Create a book forcing it out of it's autorelease pool.
  36. // I force it out of the release pool, so that we will see any errors
  37. // for it immediately at teardown, and it will be clear which release
  38. // caused us problems.
  39. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  40. book_ = [[GTMABAddressBook addressBook] retain];
  41. [pool release];
  42. STAssertNotNil(book_, nil);
  43. NSArray *people
  44. = [book_ peopleWithCompositeNameWithPrefix:kGTMABTestFirstName];
  45. GTMABPerson *person;
  46. GTM_FOREACH_OBJECT(person, people) {
  47. [book_ removeRecord:person];
  48. }
  49. NSArray *groups
  50. = [book_ groupsWithCompositeNameWithPrefix:kGTMABTestGroupName];
  51. GTMABGroup *group;
  52. GTM_FOREACH_OBJECT(group, groups) {
  53. [book_ removeRecord:group];
  54. }
  55. [book_ save];
  56. }
  57. - (void)tearDown {
  58. [book_ release];
  59. }
  60. - (void)testGenericAddressBook {
  61. STAssertEqualObjects([GTMABAddressBook localizedLabel:(NSString *)kABHomeLabel],
  62. @"home",
  63. nil);
  64. STAssertThrows([GTMABRecord recordWithRecord:nil], nil);
  65. }
  66. - (void)testAddingAndRemovingPerson {
  67. // Create a person
  68. GTMABPerson *person = [GTMABPerson personWithFirstName:kGTMABTestFirstName
  69. lastName:kGTMABTestLastName];
  70. STAssertNotNil(person, nil);
  71. // Add person
  72. NSArray *people = [book_ people];
  73. STAssertFalse([people containsObject:person], nil);
  74. STAssertTrue([book_ addRecord:person], nil);
  75. #if GTM_IPHONE_SDK && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2)
  76. // Normally this next line would be STAssertTrue, however due to
  77. // Radar 6200638: ABAddressBookHasUnsavedChanges doesn't work
  78. // We will check to make sure it stays broken ;-)
  79. STAssertFalse([book_ hasUnsavedChanges], nil);
  80. #else // GTM_IPHONE_SDK
  81. STAssertTrue([book_ hasUnsavedChanges], nil);
  82. #endif // GTM_IPHONE_SDK
  83. people = [book_ people];
  84. STAssertNotNil(people, nil);
  85. #if GTM_IPHONE_SDK
  86. // Normally this next line would be STAssertTrue, however due to
  87. // Radar 6200703: ABAddressBookAddRecord doesn't add an item to the people
  88. // array until it's saved
  89. // We will check to make sure it stays broken ;-)
  90. STAssertFalse([people containsObject:person], nil);
  91. #else // GTM_IPHONE_SDK
  92. STAssertTrue([people containsObject:person], nil);
  93. #endif // GTM_IPHONE_SDK
  94. // Save book_
  95. STAssertTrue([book_ save], nil);
  96. people = [book_ people];
  97. STAssertNotNil(people, nil);
  98. STAssertTrue([people containsObject:person], nil);
  99. people = [book_ peopleWithCompositeNameWithPrefix:kGTMABTestFirstName];
  100. STAssertEqualObjects([people objectAtIndex:0], person, nil);
  101. GTMABRecordID recordID = [person recordID];
  102. STAssertNotEquals(recordID, kGTMABRecordInvalidID, nil);
  103. GTMABRecord *record = [book_ personForId:recordID];
  104. STAssertEqualObjects(record, person, nil);
  105. // Remove person
  106. STAssertTrue([book_ removeRecord:person], nil);
  107. people = [book_ peopleWithCompositeNameWithPrefix:kGTMABTestFirstName];
  108. STAssertEquals([people count], (NSUInteger)0, nil);
  109. #if GTM_IPHONE_SDK && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2)
  110. // Normally this next line would be STAssertTrue, however due to
  111. // Radar 6200638: ABAddressBookHasUnsavedChanges doesn't work
  112. // We will check to make sure it stays broken ;-)
  113. STAssertFalse([book_ hasUnsavedChanges], nil);
  114. #else // GTM_IPHONE_SDK
  115. STAssertTrue([book_ hasUnsavedChanges], nil);
  116. #endif // GTM_IPHONE_SDK
  117. people = [book_ people];
  118. STAssertFalse([people containsObject:person], nil);
  119. // Save Book
  120. STAssertTrue([book_ save], nil);
  121. people = [book_ people];
  122. STAssertFalse([book_ hasUnsavedChanges], nil);
  123. STAssertFalse([people containsObject:person], nil);
  124. record = [book_ personForId:recordID];
  125. STAssertNil(record, nil);
  126. // Bogus data
  127. STAssertFalse([book_ addRecord:nil], nil);
  128. STAssertFalse([book_ removeRecord:nil], nil);
  129. STAssertNotNULL([book_ addressBookRef], nil);
  130. }
  131. - (void)testAddingAndRemovingGroup {
  132. // Create a group
  133. GTMABGroup *group = [GTMABGroup groupNamed:kGTMABTestGroupName];
  134. STAssertNotNil(group, nil);
  135. // Add group
  136. NSArray *groups = [book_ groups];
  137. STAssertFalse([groups containsObject:group], nil);
  138. STAssertTrue([book_ addRecord:group], nil);
  139. #if GTM_IPHONE_SDK && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2)
  140. // Normally this next line would be STAssertTrue, however due to
  141. // Radar 6200638: ABAddressBookHasUnsavedChanges doesn't work
  142. // We will check to make sure it stays broken ;-)
  143. STAssertFalse([book_ hasUnsavedChanges], nil);
  144. #else // GTM_IPHONE_SDK
  145. STAssertTrue([book_ hasUnsavedChanges], nil);
  146. #endif // GTM_IPHONE_SDK
  147. groups = [book_ groups];
  148. STAssertNotNil(groups, nil);
  149. #if GTM_IPHONE_SDK
  150. // Normally this next line would be STAssertTrue, however due to
  151. // Radar 6200703: ABAddressBookAddRecord doesn't add an item to the groups
  152. // array until it's saved
  153. // We will check to make sure it stays broken ;-)
  154. STAssertFalse([groups containsObject:group], nil);
  155. #else // GTM_IPHONE_SDK
  156. STAssertTrue([groups containsObject:group], nil);
  157. #endif // GTM_IPHONE_SDK
  158. // Save book_
  159. STAssertTrue([book_ save], nil);
  160. groups = [book_ groups];
  161. STAssertNotNil(groups, nil);
  162. STAssertTrue([groups containsObject:group], nil);
  163. groups = [book_ groupsWithCompositeNameWithPrefix:kGTMABTestGroupName];
  164. STAssertEqualObjects([groups objectAtIndex:0], group, nil);
  165. GTMABRecordID recordID = [group recordID];
  166. STAssertNotEquals(recordID, kGTMABRecordInvalidID, nil);
  167. GTMABRecord *record = [book_ groupForId:recordID];
  168. STAssertEqualObjects(record, group, nil);
  169. // Remove group
  170. STAssertTrue([book_ removeRecord:group], nil);
  171. #if GTM_IPHONE_SDK && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_3_2)
  172. // Normally this next line would be STAssertTrue, however due to
  173. // Radar 6200638: ABAddressBookHasUnsavedChanges doesn't work
  174. // We will check to make sure it stays broken ;-)
  175. STAssertFalse([book_ hasUnsavedChanges], nil);
  176. #else // GTM_IPHONE_SDK
  177. STAssertTrue([book_ hasUnsavedChanges], nil);
  178. #endif // GTM_IPHONE_SDK
  179. groups = [book_ groups];
  180. STAssertFalse([groups containsObject:group], nil);
  181. // Save Book
  182. STAssertTrue([book_ save], nil);
  183. groups = [book_ groups];
  184. STAssertFalse([book_ hasUnsavedChanges], nil);
  185. STAssertFalse([groups containsObject:group], nil);
  186. groups = [book_ groupsWithCompositeNameWithPrefix:kGTMABTestGroupName];
  187. STAssertEquals([groups count], (NSUInteger)0, nil);
  188. record = [book_ groupForId:recordID];
  189. STAssertNil(record, nil);
  190. }
  191. - (void)testPerson {
  192. GTMABPerson *person = [[[GTMABPerson alloc] initWithRecord:nil] autorelease];
  193. STAssertNil(person, nil);
  194. person = [GTMABPerson personWithFirstName:kGTMABTestFirstName
  195. lastName:nil];
  196. STAssertNotNil(person, nil);
  197. STAssertEqualObjects([person compositeName], kGTMABTestFirstName, nil);
  198. NSString *firstName = [person valueForProperty:kGTMABPersonFirstNameProperty];
  199. STAssertEqualObjects(firstName, kGTMABTestFirstName, nil);
  200. NSString *lastName = [person valueForProperty:kGTMABPersonLastNameProperty];
  201. STAssertNil(lastName, nil);
  202. STAssertTrue([person removeValueForProperty:kGTMABPersonFirstNameProperty], nil);
  203. STAssertFalse([person removeValueForProperty:kGTMABPersonFirstNameProperty], nil);
  204. STAssertFalse([person removeValueForProperty:kGTMABPersonLastNameProperty], nil);
  205. STAssertFalse([person setValue:nil forProperty:kGTMABPersonFirstNameProperty], nil);
  206. STAssertFalse([person setValue:[NSNumber numberWithInt:1]
  207. forProperty:kGTMABPersonFirstNameProperty], nil);
  208. STAssertFalse([person setValue:@"Bart"
  209. forProperty:kGTMABPersonBirthdayProperty], nil);
  210. GTMABPropertyType property
  211. = [GTMABPerson typeOfProperty:kGTMABPersonLastNameProperty];
  212. STAssertEquals(property, (GTMABPropertyType)kGTMABStringPropertyType, nil);
  213. NSString *string
  214. = [GTMABPerson localizedPropertyName:kGTMABPersonLastNameProperty];
  215. STAssertEqualObjects(string, @"Last", nil);
  216. string = [GTMABPerson localizedPropertyName:kGTMABRecordInvalidID];
  217. #if GTM_IPHONE_SDK
  218. STAssertEqualObjects(string, kGTMABUnknownPropertyName, nil);
  219. #else // GTM_IPHONE_SDK
  220. STAssertEqualObjects(string, kGTMABRecordInvalidID, nil);
  221. #endif // GTM_IPHONE_SDK
  222. string = [person description];
  223. STAssertNotNil(string, nil);
  224. GTMABPersonCompositeNameFormat format = [GTMABPerson compositeNameFormat];
  225. STAssertTrue(format == kABPersonCompositeNameFormatFirstNameFirst ||
  226. format == kABPersonCompositeNameFormatLastNameFirst, nil);
  227. NSData *data = [person imageData];
  228. STAssertNil(data, nil);
  229. STAssertTrue([person setImageData:nil], nil);
  230. data = [person imageData];
  231. STAssertNil(data, nil);
  232. NSBundle *bundle = [NSBundle bundleForClass:[self class]];
  233. NSString *phonePath = [bundle pathForResource:@"phone" ofType:@"png"];
  234. STAssertNotNil(phonePath, nil);
  235. GTMABImage *image
  236. = [[[GTMABImage alloc] initWithContentsOfFile:phonePath] autorelease];
  237. STAssertNotNil(image, nil);
  238. #if GTM_IPHONE_SDK
  239. data = UIImagePNGRepresentation(image);
  240. #else // GTM_IPHONE_SDK
  241. data = [image TIFFRepresentation];
  242. #endif // GTM_IPHONE_SDK
  243. STAssertTrue([person setImageData:data], nil);
  244. NSData *data2 = [person imageData];
  245. STAssertEqualObjects(data, data2, nil);
  246. STAssertTrue([person setImageData:nil], nil);
  247. data = [person imageData];
  248. STAssertNil(data, nil);
  249. STAssertTrue([person setImage:image], nil);
  250. GTMABImage *image2 = [person image];
  251. STAssertNotNil(image2, nil);
  252. #if GTM_IPHONE_SDK
  253. STAssertEqualObjects(UIImagePNGRepresentation(image),
  254. UIImagePNGRepresentation(image2), nil);
  255. #else // GTM_IPHONE_SDK
  256. STAssertEqualObjects([image TIFFRepresentation],
  257. [image2 TIFFRepresentation], nil);
  258. #endif // GTM_IPHONE_SDK
  259. person = [GTMABPerson personWithFirstName:kGTMABTestFirstName
  260. lastName:kGTMABTestLastName];
  261. data = [NSData dataWithBytes:"a" length:1];
  262. STAssertFalse([person setImageData:data], nil);
  263. GTMABMutableMultiValue *value
  264. = [GTMABMutableMultiValue valueWithPropertyType:kGTMABStringPropertyType];
  265. STAssertNotNil(value, nil);
  266. STAssertNotEquals([value addValue:@"222-222-2222"
  267. withLabel:(CFStringRef)kABHomeLabel],
  268. kGTMABMultiValueInvalidIdentifier, nil);
  269. STAssertNotEquals([value addValue:@"333-333-3333"
  270. withLabel:(CFStringRef)kABWorkLabel],
  271. kGTMABMultiValueInvalidIdentifier, nil);
  272. STAssertTrue([person setValue:value
  273. forProperty:kGTMABPersonPhoneProperty], nil);
  274. id value2 = [person valueForProperty:kGTMABPersonPhoneProperty];
  275. STAssertNotNil(value2, nil);
  276. STAssertEqualObjects(value, value2, nil);
  277. STAssertEquals([value hash], [value2 hash], nil);
  278. STAssertNotEquals([person hash], (NSUInteger)0, nil);
  279. }
  280. - (void)testGroup {
  281. GTMABGroup *group = [[[GTMABGroup alloc] initWithRecord:nil] autorelease];
  282. STAssertNil(group, nil);
  283. group = [GTMABGroup groupNamed:kGTMABTestGroupName];
  284. STAssertNotNil(group, nil);
  285. STAssertEqualObjects([group compositeName], kGTMABTestGroupName, nil);
  286. NSString *name = [group valueForProperty:kABGroupNameProperty];
  287. STAssertEqualObjects(name, kGTMABTestGroupName, nil);
  288. NSString *lastName = [group valueForProperty:kGTMABPersonLastNameProperty];
  289. STAssertNil(lastName, nil);
  290. STAssertTrue([group removeValueForProperty:kABGroupNameProperty], nil);
  291. STAssertFalse([group removeValueForProperty:kABGroupNameProperty], nil);
  292. STAssertFalse([group removeValueForProperty:kGTMABPersonLastNameProperty], nil);
  293. STAssertFalse([group setValue:nil forProperty:kABGroupNameProperty], nil);
  294. STAssertFalse([group setValue:[NSNumber numberWithInt:1]
  295. forProperty:kABGroupNameProperty], nil);
  296. STAssertFalse([group setValue:@"Bart"
  297. forProperty:kGTMABPersonBirthdayProperty], nil);
  298. ABPropertyType property = [GTMABGroup typeOfProperty:kABGroupNameProperty];
  299. STAssertEquals(property, (ABPropertyType)kGTMABStringPropertyType, nil);
  300. property = [GTMABGroup typeOfProperty:kGTMABPersonLastNameProperty];
  301. STAssertEquals(property, (ABPropertyType)kGTMABInvalidPropertyType, nil);
  302. NSString *string = [GTMABGroup localizedPropertyName:kABGroupNameProperty];
  303. STAssertEqualObjects(string, @"Name", nil);
  304. string = [GTMABGroup localizedPropertyName:kGTMABPersonLastNameProperty];
  305. STAssertEqualObjects(string, kGTMABUnknownPropertyName, nil);
  306. string = [GTMABGroup localizedPropertyName:kGTMABRecordInvalidID];
  307. STAssertEqualObjects(string, kGTMABUnknownPropertyName, nil);
  308. string = [group description];
  309. STAssertNotNil(string, nil);
  310. // Adding and removing members
  311. group = [GTMABGroup groupNamed:kGTMABTestGroupName];
  312. NSArray *members = [group members];
  313. STAssertEquals([members count], (NSUInteger)0, @"Members: %@", members);
  314. STAssertFalse([group addMember:nil], nil);
  315. members = [group members];
  316. STAssertEquals([members count], (NSUInteger)0, @"Members: %@", members);
  317. GTMABPerson *person = [GTMABPerson personWithFirstName:kGTMABTestFirstName
  318. lastName:kGTMABTestLastName];
  319. STAssertNotNil(person, nil);
  320. STAssertTrue([book_ addRecord:person], nil);
  321. STAssertTrue([book_ save], nil);
  322. STAssertTrue([book_ addRecord:group], nil);
  323. STAssertTrue([book_ save], nil);
  324. STAssertTrue([group addMember:person], nil);
  325. STAssertTrue([book_ save], nil);
  326. members = [group members];
  327. STAssertEquals([members count], (NSUInteger)1, @"Members: %@", members);
  328. STAssertTrue([group removeMember:person], nil);
  329. STAssertFalse([group removeMember:person], nil);
  330. STAssertFalse([group removeMember:nil], nil);
  331. STAssertTrue([book_ removeRecord:group], nil);
  332. STAssertTrue([book_ removeRecord:person], nil);
  333. STAssertTrue([book_ save], nil);
  334. }
  335. - (void)testMultiValues {
  336. STAssertThrows([[GTMABMultiValue alloc] init], nil);
  337. STAssertThrows([[GTMABMutableMultiValue alloc] init], nil);
  338. GTMABMultiValue *value = [[GTMABMultiValue alloc] initWithMultiValue:nil];
  339. STAssertNil(value, nil);
  340. GTMABMutableMultiValue *mutValue
  341. = [GTMABMutableMultiValue valueWithPropertyType:kGTMABInvalidPropertyType];
  342. STAssertNil(mutValue, nil);
  343. mutValue
  344. = [[[GTMABMutableMultiValue alloc]
  345. initWithMutableMultiValue:nil] autorelease];
  346. STAssertNil(mutValue, nil);
  347. mutValue
  348. = [[[GTMABMutableMultiValue alloc]
  349. initWithMultiValue:nil] autorelease];
  350. STAssertNil(mutValue, nil);
  351. #if GTM_IPHONE_SDK
  352. // Only the IPhone version actually allows you to check types of a multivalue
  353. // before you stick anything in it
  354. const GTMABPropertyType types[] = {
  355. kGTMABStringPropertyType,
  356. kGTMABIntegerPropertyType,
  357. kGTMABRealPropertyType,
  358. kGTMABDateTimePropertyType,
  359. kGTMABDictionaryPropertyType,
  360. kGTMABMultiStringPropertyType,
  361. kGTMABMultiIntegerPropertyType,
  362. kGTMABMultiRealPropertyType,
  363. kGTMABMultiDateTimePropertyType,
  364. kGTMABMultiDictionaryPropertyType
  365. };
  366. for (size_t i = 0; i < sizeof(types) / sizeof(GTMABPropertyType); ++i) {
  367. mutValue = [GTMABMutableMultiValue valueWithPropertyType:types[i]];
  368. STAssertNotNil(mutValue, nil);
  369. // Oddly the Apple APIs allow you to create a mutable multi value with
  370. // either a property type of kABFooPropertyType or kABMultiFooPropertyType
  371. // and apparently you get back basically the same thing. However if you
  372. // ask a type that you created with kABMultiFooPropertyType for it's type
  373. // it returns just kABFooPropertyType.
  374. STAssertEquals([mutValue propertyType],
  375. (GTMABPropertyType)(types[i] & ~kABMultiValueMask), nil);
  376. }
  377. #endif // GTM_IPHONE_SDK
  378. mutValue
  379. = [GTMABMutableMultiValue valueWithPropertyType:kGTMABStringPropertyType];
  380. STAssertNotNil(mutValue, nil);
  381. value = [[mutValue copy] autorelease];
  382. STAssertEqualObjects([value class], [GTMABMultiValue class], nil);
  383. mutValue = [[value mutableCopy] autorelease];
  384. STAssertEqualObjects([mutValue class], [GTMABMutableMultiValue class], nil);
  385. STAssertEquals([mutValue count], (NSUInteger)0, nil);
  386. STAssertNil([mutValue valueAtIndex:0], nil);
  387. STAssertNil([mutValue labelAtIndex:0], nil);
  388. #if GTM_IPHONE_SDK
  389. STAssertEquals([mutValue identifierAtIndex:0],
  390. kGTMABMultiValueInvalidIdentifier, nil);
  391. STAssertEquals([mutValue propertyType],
  392. (GTMABPropertyType)kGTMABStringPropertyType, nil);
  393. #else // GTM_IPHONE_SDK
  394. STAssertEqualObjects([mutValue identifierAtIndex:0],
  395. kGTMABMultiValueInvalidIdentifier, nil);
  396. #endif // GTM_IPHONE_SDK
  397. GTMABMultiValueIdentifier ident
  398. = [mutValue addValue:nil withLabel:(CFStringRef)kABHomeLabel];
  399. #if GTM_IPHONE_SDK
  400. STAssertEquals(ident, kGTMABMultiValueInvalidIdentifier, nil);
  401. #else // GTM_IPHONE_SDK
  402. STAssertEqualObjects(ident, kGTMABMultiValueInvalidIdentifier, nil);
  403. #endif // GTM_IPHONE_SDK
  404. ident = [mutValue addValue:@"val1"
  405. withLabel:nil];
  406. #if GTM_IPHONE_SDK
  407. STAssertEquals(ident, kGTMABMultiValueInvalidIdentifier, nil);
  408. #else // GTM_IPHONE_SDK
  409. STAssertEqualObjects(ident, kGTMABMultiValueInvalidIdentifier, nil);
  410. #endif // GTM_IPHONE_SDK
  411. ident = [mutValue insertValue:@"val1"
  412. withLabel:nil
  413. atIndex:0];
  414. #if GTM_IPHONE_SDK
  415. STAssertEquals(ident, kGTMABMultiValueInvalidIdentifier, nil);
  416. #else // GTM_IPHONE_SDK
  417. STAssertEqualObjects(ident, kGTMABMultiValueInvalidIdentifier, nil);
  418. #endif // GTM_IPHONE_SDK
  419. ident = [mutValue insertValue:nil
  420. withLabel:(CFStringRef)kABHomeLabel
  421. atIndex:0];
  422. #if GTM_IPHONE_SDK
  423. STAssertEquals(ident, kGTMABMultiValueInvalidIdentifier, nil);
  424. #else // GTM_IPHONE_SDK
  425. STAssertEqualObjects(ident, kGTMABMultiValueInvalidIdentifier, nil);
  426. #endif // GTM_IPHONE_SDK
  427. ident = [mutValue addValue:@"val1"
  428. withLabel:(CFStringRef)kABHomeLabel];
  429. #if GTM_IPHONE_SDK
  430. STAssertNotEquals(ident, kGTMABMultiValueInvalidIdentifier, nil);
  431. #else // GTM_IPHONE_SDK
  432. STAssertNotEqualObjects(ident, kGTMABMultiValueInvalidIdentifier, nil);
  433. #endif // GTM_IPHONE_SDK
  434. GTMABMultiValueIdentifier identCheck = [mutValue identifierAtIndex:0];
  435. #if GTM_IPHONE_SDK
  436. STAssertEquals(ident, identCheck, nil);
  437. #else // GTM_IPHONE_SDK
  438. STAssertEqualObjects(ident, identCheck, nil);
  439. #endif // GTM_IPHONE_SDK
  440. NSUInteger idx = [mutValue indexForIdentifier:ident];
  441. STAssertEquals(idx, (NSUInteger)0, nil);
  442. STAssertTrue([mutValue replaceLabelAtIndex:0
  443. withLabel:(CFStringRef)kABWorkLabel], nil);
  444. STAssertFalse([mutValue replaceLabelAtIndex:10
  445. withLabel:(CFStringRef)kABWorkLabel], nil);
  446. STAssertTrue([mutValue replaceValueAtIndex:0
  447. withValue:@"newVal1"], nil);
  448. STAssertFalse([mutValue replaceValueAtIndex:10
  449. withValue:@"newVal1"], nil);
  450. STAssertEqualObjects([mutValue valueForIdentifier:ident], @"newVal1", nil);
  451. STAssertEqualObjects([mutValue labelForIdentifier:ident],
  452. (NSString *)kABWorkLabel, nil);
  453. GTMABMultiValueIdentifier ident2
  454. = [mutValue insertValue:@"val2"
  455. withLabel:(CFStringRef)kABOtherLabel
  456. atIndex:0];
  457. STAssertNotEquals(ident2, kGTMABMultiValueInvalidIdentifier, nil);
  458. STAssertNotEquals(ident2, ident, nil);
  459. GTMABMultiValueIdentifier ident3
  460. = [mutValue insertValue:@"val3"
  461. withLabel:(CFStringRef)kGTMABPersonPhoneMainLabel
  462. atIndex:10];
  463. #if GTM_IPHONE_SDK
  464. STAssertEquals(ident3, kGTMABMultiValueInvalidIdentifier, nil);
  465. #else // GTM_IPHONE_SDK
  466. STAssertEqualObjects(ident3, kGTMABMultiValueInvalidIdentifier, nil);
  467. #endif // GTM_IPHONE_SDK
  468. NSUInteger idx3 = [mutValue indexForIdentifier:ident3];
  469. STAssertEquals(idx3, (NSUInteger)NSNotFound, nil);
  470. STAssertTrue([mutValue removeValueAndLabelAtIndex:1], nil);
  471. STAssertFalse([mutValue removeValueAndLabelAtIndex:1], nil);
  472. NSUInteger idx4
  473. = [mutValue indexForIdentifier:kGTMABMultiValueInvalidIdentifier];
  474. STAssertEquals(idx4, (NSUInteger)NSNotFound, nil);
  475. STAssertNotNULL([mutValue multiValueRef], nil);
  476. // Enumerator test
  477. mutValue
  478. = [GTMABMutableMultiValue valueWithPropertyType:kGTMABIntegerPropertyType];
  479. STAssertNotNil(mutValue, nil);
  480. for (int i = 0; i < 100; i++) {
  481. NSString *label = [NSString stringWithFormat:@"label %d", i];
  482. NSNumber *val = [NSNumber numberWithInt:i];
  483. STAssertNotEquals([mutValue addValue:val
  484. withLabel:(CFStringRef)label],
  485. kGTMABMultiValueInvalidIdentifier, nil);
  486. }
  487. int count = 0;
  488. NSString *label;
  489. GTM_FOREACH_ENUMEREE(label, [mutValue labelEnumerator]) {
  490. NSString *testLabel = [NSString stringWithFormat:@"label %d", count++];
  491. STAssertEqualObjects(label, testLabel, nil);
  492. }
  493. count = 0;
  494. value = [[mutValue copy] autorelease];
  495. NSNumber *val;
  496. GTM_FOREACH_ENUMEREE(val, [value valueEnumerator]) {
  497. STAssertEqualObjects(val, [NSNumber numberWithInt:count++], nil);
  498. }
  499. // Test messing with the values while we're enumerating them
  500. NSEnumerator *labelEnum = [mutValue labelEnumerator];
  501. NSEnumerator *valueEnum = [mutValue valueEnumerator];
  502. STAssertNotNil(labelEnum, nil);
  503. STAssertNotNil(valueEnum, nil);
  504. STAssertNotNil([labelEnum nextObject], nil);
  505. STAssertNotNil([valueEnum nextObject], nil);
  506. STAssertTrue([mutValue removeValueAndLabelAtIndex:0], nil);
  507. STAssertThrows([labelEnum nextObject], nil);
  508. STAssertThrows([valueEnum nextObject], nil);
  509. // Test messing with the values while we're fast enumerating them
  510. // Should throw an exception on the second access.
  511. BOOL exceptionThrown = NO;
  512. // Start at one because we removed index 0 above.
  513. count = 1;
  514. @try {
  515. GTM_FOREACH_ENUMEREE(label, [mutValue labelEnumerator]) {
  516. NSString *testLabel = [NSString stringWithFormat:@"label %d", count++];
  517. STAssertEqualObjects(label, testLabel, nil);
  518. STAssertTrue([mutValue removeValueAndLabelAtIndex:50], nil);
  519. }
  520. } @catch(NSException *e) {
  521. STAssertEqualObjects([e name], NSGenericException, @"Got %@ instead", e);
  522. STAssertEquals(count, 2,
  523. @"Should have caught it on the second access");
  524. exceptionThrown = YES;
  525. } // COV_NF_LINE - because we always catch, this brace doesn't get exec'd
  526. STAssertTrue(exceptionThrown, @"We should have thrown an exception"
  527. @" because the values under the enumerator were modified");
  528. }
  529. #if GTM_IPHONE_SDK
  530. - (void)testRadar6208390 {
  531. GTMABPropertyType types[] = {
  532. kGTMABStringPropertyType,
  533. kGTMABIntegerPropertyType,
  534. kGTMABRealPropertyType,
  535. kGTMABDateTimePropertyType,
  536. kGTMABDictionaryPropertyType
  537. };
  538. for (size_t j = 0; j < sizeof(types) / sizeof(ABPropertyType); ++j) {
  539. ABPropertyType type = types[j];
  540. #if GTM_IPHONE_SDK
  541. ABMultiValueRef ref = ABMultiValueCreateMutable(type);
  542. #else // GTM_IPHONE_SDK
  543. ABMutableMultiValueRef ref = ABMultiValueCreateMutable();
  544. #endif // GTM_IPHONE_SDK
  545. STAssertNotNULL(ref, nil);
  546. NSString *label = [[NSString alloc] initWithString:@"label"];
  547. STAssertNotNil(label, nil);
  548. id val = nil;
  549. if (type == kGTMABDictionaryPropertyType) {
  550. val = [[NSDictionary alloc] initWithObjectsAndKeys:@"1", @"1", nil];
  551. } else if (type == kGTMABStringPropertyType) {
  552. val = [[NSString alloc] initWithFormat:@"value %zu", j];
  553. } else if (type == kGTMABIntegerPropertyType
  554. || type == kGTMABRealPropertyType ) {
  555. val = [[NSNumber alloc] initWithInt:143];
  556. } else if (type == kGTMABDateTimePropertyType) {
  557. val = [[NSDate alloc] init];
  558. }
  559. STAssertNotNil(val,
  560. @"Testing type %d, %@", type, val);
  561. NSUInteger firstRetainCount = [val retainCount];
  562. STAssertNotEquals(firstRetainCount,
  563. (NSUInteger)0,
  564. @"Testing type %d, %@", type, val);
  565. GTMABMultiValueIdentifier identifier;
  566. STAssertTrue(ABMultiValueAddValueAndLabel(ref,
  567. val,
  568. (CFStringRef)label,
  569. &identifier),
  570. @"Testing type %d, %@", type, val);
  571. NSUInteger secondRetainCount = [val retainCount];
  572. STAssertEquals(firstRetainCount + 1,
  573. secondRetainCount,
  574. @"Testing type %d, %@", type, val);
  575. [label release];
  576. [val release];
  577. NSUInteger thirdRetainCount = [val retainCount];
  578. STAssertEquals(firstRetainCount,
  579. thirdRetainCount,
  580. @"Testing type %d, %@", type, val);
  581. id oldVal = val;
  582. val = (id)ABMultiValueCopyValueAtIndex(ref, 0);
  583. NSUInteger fourthRetainCount = [val retainCount];
  584. // kABDictionaryPropertyTypes appear to do an actual copy, so the retain
  585. // count checking trick won't work. We only check the retain count if
  586. // we didn't get a new version.
  587. if (val == oldVal) {
  588. if (type == kGTMABIntegerPropertyType
  589. || type == kGTMABRealPropertyType) {
  590. // We are verifying that yes indeed 6208390 is still broken
  591. STAssertEquals(fourthRetainCount,
  592. thirdRetainCount,
  593. @"Testing type %d, %@. If you see this error it may "
  594. @"be time to update the code to change retain behaviors"
  595. @"with this os version", type, val);
  596. } else {
  597. STAssertEquals(fourthRetainCount,
  598. thirdRetainCount + 1,
  599. @"Testing type %d, %@", type, val);
  600. [val release];
  601. }
  602. } else {
  603. [val release];
  604. }
  605. CFRelease(ref);
  606. }
  607. }
  608. // Globals used by testRadar6240394.
  609. static GTMABPropertyID gGTMTestID;
  610. static const GTMABPropertyID *gGTMTestIDPtr;
  611. void __attribute__((constructor))SetUpIDForTestRadar6240394(void) {
  612. // These must be set up BEFORE ABAddressBookCreate is called.
  613. gGTMTestID = kGTMABPersonLastNameProperty;
  614. gGTMTestIDPtr = &kGTMABPersonLastNameProperty;
  615. }
  616. - (void)testRadar6240394 {
  617. // As of iPhone SDK 2.1, the property IDs aren't initialized until
  618. // ABAddressBookCreate is actually called. They will return zero until
  619. // then. Logged as radar 6240394.
  620. STAssertEquals(gGTMTestID, 0, @"If this isn't zero, Apple has fixed 6240394");
  621. (void)ABAddressBookCreate();
  622. STAssertEquals(*gGTMTestIDPtr, kGTMABPersonLastNameProperty,
  623. @"If this doesn't work, something else has broken");
  624. }
  625. #endif // GTM_IPHONE_SDK
  626. @end