diff --git a/Foundation/CPArray+KVO.j b/Foundation/CPArray+KVO.j index ccc8efcda..ff17444f8 100644 --- a/Foundation/CPArray+KVO.j +++ b/Foundation/CPArray+KVO.j @@ -311,12 +311,13 @@ if (_removeMany) { var indexes = [CPIndexSet indexSet], - index = [theObjects count]; + index = [theObjects count], + position = 0, + count = [self count]; while (index--) { - var position = [self indexOfObject:[theObjects objectAtIndex:index]]; - if (position !== CPNotFound) + while ((position = [self indexOfObject:[theObjects objectAtIndex:index] inRange:_CPMakeRange(position + 1, count)]) !== CPNotFound) [indexes addIndex:position]; } @@ -324,11 +325,11 @@ } else if (_remove) { - var index = [theObjects count]; + var index = [theObjects count], + position; while (index--) { - var position = [self indexOfObject:[theObjects objectAtIndex:index]]; - if (position !== CPNotFound) + while ((position = [self indexOfObject:[theObjects objectAtIndex:index]]) !== CPNotFound) _remove(_proxyObject, _removeSEL, position); } } diff --git a/Tests/Foundation/CPKVCArrayTest.j b/Tests/Foundation/CPKVCArrayTest.j index 57f750455..12e5edd52 100644 --- a/Tests/Foundation/CPKVCArrayTest.j +++ b/Tests/Foundation/CPKVCArrayTest.j @@ -215,30 +215,33 @@ var COUNTER; - (void)testRemoveObjectsInArrayUsesRemoveKeyAtIndex { + [[self object] setValues:[3, 1, 1, 3, 6]]; [self _patchSelector:@selector(removeObjectFromValuesAtIndex:)]; [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[3, 6]]; - [self assert:[0, 1, 2, 4, 5, 7, 8, 9] equals:[[self object] values]]; - [self assert:2 equals:COUNTER message:"removeObjectFromValuesAtIndex: should have been called twice"] + // Note that all instances of the specified values are removed, not just the first one. + [self assert:[1, 1] equals:[[self object] values]]; + [self assert:3 equals:COUNTER message:"removeObjectFromValuesAtIndex: should have been called thrice"] // Try to remove something that doesn't exist. Should not crash. [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[3, 6]]; - [self assert:[0, 1, 2, 4, 5, 7, 8, 9] equals:[[self object] values]]; + [self assert:[1, 1] equals:[[self object] values]]; } - (void)testRemoveObjectsInArrayUsesRemoveKeyAtIndexes { + [[self object] setValues:[3, 1, 1, 3, 6]]; [self _patchSelector:@selector(removeValuesAtIndexes:)]; - [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[0, 9]]; + [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[3, 6]]; - [self assert:[1, 2, 3, 4, 5, 6, 7, 8] equals:[[self object] values]]; + [self assert:[1, 1] equals:[[self object] values]]; [self assert:1 equals:COUNTER message:@"removeValuesAtIndexes: should have been called once"]; // Try to remove something that doesn't exist. Should not crash. - [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[0, 9]]; - [self assert:[1, 2, 3, 4, 5, 6, 7, 8] equals:[[self object] values]]; + [[[self object] mutableArrayValueForKey:@"values"] removeObjectsInArray:[3, 6]]; + [self assert:[1, 1] equals:[[self object] values]]; } - (void)testRemoveLastObjectUsesRemoveKeyAtIndex