1. Adds caching of the calculated fullName value (which will slightly improve performance) 2. Incorporates fullNames that respect the first-name-first rules of the currently unmerged PR #22 3. Adds two new fullName properties that can be used for sorting comparators 4. Move the comparator into the model object for easy testing Includes tests to ensure that the first name first and last name first sorts are behaving as expected. // FREEBIE
120 lines
5.6 KiB
Objective-C
120 lines
5.6 KiB
Objective-C
// Created by Russ Shanahan on 11/25/16.
|
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
|
|
|
#import "Contact.h"
|
|
#import <XCTest/XCTest.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@interface ContactSortingTest : XCTestCase
|
|
|
|
@end
|
|
|
|
@implementation ContactSortingTest
|
|
|
|
- (void)setUp
|
|
{
|
|
srandom((unsigned int)time(NULL));
|
|
}
|
|
|
|
- (void)testSortingNamesByFirstLast
|
|
{
|
|
NSComparator comparator = [Contact comparatorSortingNamesByFirstThenLast:YES];
|
|
NSArray<Contact *>*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) {
|
|
XCTAssert(@"Contacts failed to sort names by first, last");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)testSortingNamesByLastFirst
|
|
{
|
|
NSComparator comparator = [Contact comparatorSortingNamesByFirstThenLast:NO];
|
|
NSArray<Contact *>*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) {
|
|
XCTAssert(@"Contacts failed to sort names by last, first");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ (NSArray<Contact *> *)contactArrayForNames:(NSArray<NSArray<NSString *>*>*)namePairs
|
|
{
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
|
ABRecordID fakeRecordId = 0;
|
|
#pragma clang diagnostic pop
|
|
NSMutableArray<Contact *>*contacts = [[NSMutableArray alloc] initWithCapacity:namePairs.count];
|
|
for (NSArray<NSString *>*namePair in namePairs) {
|
|
Contact *c = [[Contact alloc] initWithContactWithFirstName:namePair[0]
|
|
andLastName:namePair[1]
|
|
andUserTextPhoneNumbers:@[]
|
|
andImage:nil
|
|
andContactID:fakeRecordId++];
|
|
[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
|