// // Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "Contact.h" #import "SSKBaseTestObjC.h" @import Contacts; NS_ASSUME_NONNULL_BEGIN @interface ContactSortingTest : SSKBaseTestObjC @end @implementation ContactSortingTest - (void)setUp { [super setUp]; srandom((unsigned int)time(NULL)); } - (void)testSortingNamesByFirstLast { NSComparator comparator = [Contact comparatorSortingNamesByFirstThenLast:YES]; NSArray*sortedContacts = [self.class contactArrayForNames:@[@[@"Adam", @"Smith"], @[@"Adam", @"West"], @[@"", @"Daisy"], @[@"Daisy", @"Chain"], @[@"Daisy", @"Duke"], @[@"James", @"Smith"], @[@"James", @"Van"], @[@"James", @"Van Der Beek"], @[@"Kevin", @"Smith"], @[@"Mae", @"West"], @[@"Mary", @"Oliver"], @[@"Mary Jo", @"Catlett"], ]]; NSUInteger numContacts = sortedContacts.count; for (NSUInteger i = 0; i < 20; i++) { NSArray *shuffledContacts = [self.class shuffleArray:sortedContacts]; NSArray *resortedContacts = [shuffledContacts sortedArrayUsingComparator:comparator]; for (NSUInteger j = 0; j < numContacts; j++) { Contact *a = sortedContacts[j]; Contact *b = resortedContacts[j]; BOOL correct = ([a.firstName isEqualToString:b.firstName] && [a.lastName isEqualToString:b.lastName]); if (!correct) { XCTFail(@"Contacts failed to sort names by first, last"); break; } } } } - (void)testSortingNamesByLastFirst { NSComparator comparator = [Contact comparatorSortingNamesByFirstThenLast:NO]; NSArray*sortedContacts = [self.class contactArrayForNames:@[@[@"Mary Jo", @"Catlett"], @[@"Daisy", @"Chain"], @[@"", @"Daisy"], @[@"Daisy", @"Duke"], @[@"Mary", @"Oliver"], @[@"Adam", @"Smith"], @[@"James", @"Smith"], @[@"Kevin", @"Smith"], @[@"James", @"Van"], @[@"James", @"Van Der Beek"], @[@"Adam", @"West"], @[@"Mae", @"West"], ]]; NSUInteger numContacts = sortedContacts.count; for (NSUInteger i = 0; i < 20; i++) { NSArray *shuffledContacts = [self.class shuffleArray:sortedContacts]; NSArray *resortedContacts = [shuffledContacts sortedArrayUsingComparator:comparator]; for (NSUInteger j = 0; j < numContacts; j++) { Contact *a = sortedContacts[j]; Contact *b = resortedContacts[j]; BOOL correct = ([a.firstName isEqualToString:b.firstName] && [a.lastName isEqualToString:b.lastName]); if (!correct) { XCTFail(@"Contacts failed to sort names by last, first"); break; } } } } + (NSArray *)contactArrayForNames:(NSArray*>*)namePairs { NSMutableArray*contacts = [[NSMutableArray alloc] initWithCapacity:namePairs.count]; for (NSArray*namePair in namePairs) { CNMutableContact *cnContact = [CNMutableContact new]; cnContact.givenName = namePair[0]; cnContact.familyName = namePair[1]; Contact *c = [[Contact alloc] initWithSystemContact:cnContact]; [contacts addObject:c]; } return [contacts copy]; // Return an immutable for good hygene } + (NSArray*)shuffleArray:(NSArray *)array { NSMutableArray *shuffled = [[NSMutableArray alloc] initWithArray:array]; for(NSUInteger i = [array count]; i > 1; i--) { NSUInteger j = arc4random_uniform((uint32_t)i); [shuffled exchangeObjectAtIndex:(i - 1) withObjectAtIndex:j]; } return [shuffled copy]; // Return an immutable for good hygene } @end NS_ASSUME_NONNULL_END