diff --git a/AppKit/CPArrayController.j b/AppKit/CPArrayController.j index 61713ccc1..fe377ade8 100644 --- a/AppKit/CPArrayController.j +++ b/AppKit/CPArrayController.j @@ -365,29 +365,29 @@ //Moving selection --(BOOL)canSelectPrevious +- (BOOL)canSelectPrevious { return [[self selectionIndexes] firstIndex] > 0 } --(BOOL)canSelectNext +-(void)selectPrevious:(id)sender { - return [[self selectionIndexes] firstIndex] < [[self arrangedObjects] count] -1; -} + var index = [[self selectionIndexes] firstIndex] - 1; --(void)selectNext:(id)sender -{ - var index = [[self selectionIndexes] firstIndex] + 1 || 0; - - if (index < [[self arrangedObjects] count]) + if (index >= 0) [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]]; } --(void)selectPrevious:(id)sender +- (BOOL)canSelectNext { - var index = [[self selectionIndexes] firstIndex] - 1 || [[self arrangedObjects] count] - 1; + return [[self selectionIndexes] firstIndex] < [[self arrangedObjects] count] - 1; +} - if (index >= 0) +- (void)selectNext:(id)sender +{ + var index = [[self selectionIndexes] firstIndex] + 1; + + if (index < [[self arrangedObjects] count]) [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:index]]; } @@ -431,6 +431,33 @@ [self rearrangeObjects]; } +- (void)insertObject:(id)anObject atArrangedObjectIndex:(int)anIndex +{ + if (![self canAdd]) + return; + + [self willChangeValueForKey:@"content"]; + [_contentObject insertObject:anObject atIndex:anIndex]; + [self didChangeValueForKey:@"content"]; + + if (_clearsFilterPredicateOnInsertion) + [self setFilterPredicate:nil]; + + [[self arrangedObjects] insertObject:anObject atIndex:anIndex]; + + if ([self selectsInsertedObjects]) + [self setSelectionIndex:anIndex]; + else + { + [self willChangeValueForKey:@"selectionIndexes"] + [[self selectionIndexes] shiftIndexesStartingAtIndex:anIndex by:1]; + [self didChangeValueForKey:@"selectionIndexes"]; + } + + if ([self avoidsEmptySelection] && [[self selectionIndexes] count] <= 0 && [_contentObject count] > 0) + [self setSelectionIndexes:[CPIndexSet indexSetWithIndex:0]]; +} + - (void)removeObject:(id)object { if (![self canRemove]) diff --git a/Foundation/CPIndexSet.j b/Foundation/CPIndexSet.j index bd3be224e..157cad253 100644 --- a/Foundation/CPIndexSet.j +++ b/Foundation/CPIndexSet.j @@ -130,6 +130,17 @@ return self; } +- (BOOL)isEqual:(id)anObject +{ + if (self === anObject) + return YES; + + if (!anObject || ![anObject isKindOfClass:[CPIndexSet class]]) + return NO; + + return [self isEqualToIndexSet:anObject]; +} + // Querying an Index Set /*! Compares the receiver with the provided index set. diff --git a/Tests/AppKit/CPArrayControllerTest.j b/Tests/AppKit/CPArrayControllerTest.j new file mode 100644 index 000000000..c7bf08a96 --- /dev/null +++ b/Tests/AppKit/CPArrayControllerTest.j @@ -0,0 +1,123 @@ +@implementation CPArrayControllerTest : OJTestCase +{ + CPArrayController _arrayController @accessors(property=arrayController); + CPArray _contentArray @accessors(property=contentArray); +} + +- (void)setUp +{ + _contentArray = []; + + [_contentArray addObject:[Person personWithName:@"Francisco" age:21]]; + [_contentArray addObject:[Person personWithName:@"Ross" age:30]]; + [_contentArray addObject:[Person personWithName:@"Tom" age:15]]; + + _arrayController = [[CPArrayController alloc] initWithContent:[self contentArray]]; +} + +- (void)testInitWithContent +{ + [self assert:[self contentArray] equals:[[self arrayController] contentArray]]; + [self assert:[_CPObservableArray class] equals:[[[self arrayController] arrangedObjects] class]]; +} + +- (void)testSetContent +{ + otherContent = [@"5", @"6"]; + [[self arrayController] setContent:otherContent]; + + [self assert:otherContent equals:[[self arrayController] contentArray]]; + [self assert:[_CPObservableArray class] equals:[[[self arrayController] arrangedObjects] class]]; +} + +- (void)testInsertObjectAtArrangedObjectIndex +{ + var object = [Person personWithName:@"Klaas Pieter" age:24], + arrayController = [self arrayController]; + + [arrayController setSortDescriptors:[[CPSortDescriptor sortDescriptorWithKey:@"age" ascending:YES]]]; + [arrayController insertObject:object atArrangedObjectIndex:1]; + + [self assert:object equals:[[arrayController arrangedObjects] objectAtIndex:1]]; +} + +- (void)testSelectPrevious +{ + var arrayController = [self arrayController]; + + // Selection index: 1 + [arrayController setSelectionIndexes:[CPIndexSet indexSetWithIndex:1]]; + [self assertTrue:[arrayController canSelectPrevious] message:@"index > 0; canSelectPrevious should return YES"] + + [arrayController selectPrevious:self]; + [self assert:[CPIndexSet indexSetWithIndex:0] equals:[arrayController selectionIndexes]]; + + // Selection index: 0 + [self assertFalse:[arrayController canSelectPrevious] message:@"index <= 0; canSelectPrevious should return NO"]; + + [arrayController selectPrevious:self]; + [self assert:[CPIndexSet indexSetWithIndex:0] equals:[arrayController selectionIndexes]]; +} + +- (void)testSelectNext +{ + var arrayController = [self arrayController], + count = [[arrayController arrangedObjects] count]; + + // Selection index: count - 2 + [arrayController setSelectionIndexes:[CPIndexSet indexSetWithIndex:count - 2]]; + [self assertTrue:[arrayController canSelectNext] message:@"index < (count - 1); canSelectNext should return YES"]; + + [arrayController selectNext:self]; + [self assert:[CPIndexSet indexSetWithIndex:count - 1] equals:[arrayController selectionIndexes]]; + + // Selection index: count - 1 + [self assertFalse:[arrayController canSelectNext] message:@"index >= (count - 1) canSelectNext should return NO"]; + + [arrayController selectNext:self]; + [self assert:[CPIndexSet indexSetWithIndex:count - 1] equals:[arrayController selectionIndexes]]; +} + +- (void)testContentBinding +{ + [[self arrayController] bind:@"contentArray" toObject:self withKeyPath:@"contentArray" options:0]; + + [self assert:[[self arrayController] contentArray] equals:[self contentArray]]; + + [[self mutableArrayValueForKey:@"contentArray"] addObject:@"4"]; + [self assert:[self contentArray] equals:[[self arrayController] contentArray]]; + + [[self arrayController] insertObject:@"2" atArrangedObjectIndex:1]; + [self assert:[[self arrayController] contentArray] equals:[self contentArray]]; +} + +@end + +@implementation Person : CPObject +{ + CPString _name @accessors(property=name); + int _age @accessors(property=age); +} + ++ (id)personWithName:(CPString)aName age:(int)anAge +{ + return [[self alloc] initWithName:aName age:anAge]; +} + +- (id)initWithName:(CPString)aName age:(int)anAge +{ + if (self = [super init]) + { + _name = aName; + _age = anAge; + } + + return self; +} + +- (CPString)description +{ + return [CPString stringWithFormat:@"%@ : %@", [self name], [self age]]; +} + +@end \ No newline at end of file diff --git a/Tests/Foundation/CPIndexSetTest.j b/Tests/Foundation/CPIndexSetTest.j index fed4726b9..3b547d8a8 100644 --- a/Tests/Foundation/CPIndexSetTest.j +++ b/Tests/Foundation/CPIndexSetTest.j @@ -389,6 +389,27 @@ function descriptionWithoutEntity(aString) [self assertTrue:[_set lastIndex] === 0]; } +- (void)testIsEqual +{ + var differentSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 11)], + equalSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 10)]; + + [self assertFalse:[_set isEqual:nil]]; + [self assertFalse:[_set isEqual:differentSet]]; + [self assertTrue:[_set isEqual:equalSet]]; + [self assertTrue:[_set isEqual:_set]]; +} + +- (void)testIsEqualToIndexSet +{ + var differentSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 11)], + equalSet = [CPIndexSet indexSetWithIndexesInRange:CPMakeRange(10, 10)]; + + [self assertFalse:[_set isEqualToIndexSet:differentSet]]; + [self assertTrue:[_set isEqualToIndexSet:equalSet]]; + [self assertTrue:[_set isEqualToIndexSet:_set]]; +} + - (void)tearDown { _set = nil;