diff --git a/Foundation/CPArray/CPMutableArray.j b/Foundation/CPArray/CPMutableArray.j index eb87ce9cc..865879cb0 100644 --- a/Foundation/CPArray/CPMutableArray.j +++ b/Foundation/CPArray/CPMutableArray.j @@ -50,7 +50,11 @@ */ - (void)addObjectsFromArray:(CPArray)anArray { - splice.apply(self, [length, 0].concat(anArray)); + var index = 0, + count = [anArray count]; + + for (; index < count; ++index) + [self addObject:[anArray objectAtIndex:index]]; } /*! @@ -85,7 +89,7 @@ currentIndex = [indexes firstIndex]; for (; index < objectsCount; ++index, currentIndex = [indexes indexGreaterThanIndex:currentIndex]) - [self insertObject:objects[index] atIndex:currentIndex]; + [self insertObject:[objects objectAtIndex:index] atIndex:currentIndex]; } - (unsigned)insertObject:(id)anObject inArraySortedByDescriptors:(CPArray)descriptors @@ -178,10 +182,11 @@ */ - (void)setArray:(CPArray)anArray { - if (self == anArray) + if (self === anArray) return; - splice.apply(self, [0, length].concat(anArray)); + [self removeAllObjects]; + [self addObjectsFromArray:anArray]; } // Removing Objects @@ -190,7 +195,8 @@ */ - (void)removeAllObjects { - splice(0, length); + while ([self count]) + [self removeLastObject]; } /*! @@ -243,7 +249,7 @@ { var index = [anIndexSet lastIndex]; - while (index != CPNotFound) + while (index !== CPNotFound) { [self removeObjectAtIndex:index]; index = [anIndexSet indexLessThanIndex:index]; @@ -289,7 +295,7 @@ count = [anArray count]; for (; index < count; ++index) - [self removeObject:anArray[index]]; + [self removeObject:[anArray objectAtIndex:index]]; } /*! @@ -298,7 +304,11 @@ */ - (void)removeObjectsInRange:(CPRange)aRange { - splice(aRange.location, aRange.length); + var index = aRange.location, + count = CPMaxRange(aRange); + + while (count-- > index) + [self removeObjectAtIndex:index]; } // Rearranging objects diff --git a/Foundation/CPArray/_CPJavaScriptArray.j b/Foundation/CPArray/_CPJavaScriptArray.j index f79b4197d..f04b51beb 100644 --- a/Foundation/CPArray/_CPJavaScriptArray.j +++ b/Foundation/CPArray/_CPJavaScriptArray.j @@ -218,16 +218,45 @@ var concat = Array.prototype.concat, push.call(self, anObject); } +- (void)removeAllObjects +{ + splice.call(self, 0, self.length); +} + - (void)removeLastObject { pop.call(self); } +- (void)removeObjectsInRange:(CPRange)aRange +{ + splice.call(self, aRange.location, aRange.length); +} + - (void)replaceObjectAtIndex:(int)anIndex withObject:(id)anObject { self[anIndex] = anObject; } +- (void)setArray:(CPArray)anArray +{ + if (anArray.isa === _CPJavaScriptArray) + splice.apply(self, [0, self.length].concat(anArray)); + + else + [super setArray:anArray]; +} + +- (void)addObjectsFromArray:(CPArray)anArray +{ + if (anArray.isa === _CPJavaScriptArray) + splice.apply(self, [self.length, 0].concat(anArray)); + + else + [super addObjectsFromArray:anArray]; +} + + - (void)copy { return slice.call(self, 0); diff --git a/Tests/Foundation/CPArrayOldTest.j b/Tests/Foundation/CPArrayOldTest.j deleted file mode 100644 index 135b4be94..000000000 --- a/Tests/Foundation/CPArrayOldTest.j +++ /dev/null @@ -1,286 +0,0 @@ -@import - -@implementation CPArrayOldTest : OJTestCase - -- (void)testsInsertObjectsAtIndexes -{ - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], - newAdditions = [CPArray arrayWithObjects:@"a", @"b"], - indexes = [CPMutableIndexSet indexSetWithIndex:1]; - - [indexes addIndex:3]; - - [array insertObjects:newAdditions atIndexes:indexes]; - - [self assert:array equals:[@"one", @"a", @"two", @"b", @"three", @"four"]]; - - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], - newAdditions = [CPArray arrayWithObjects:@"a", @"b"], - indexes = [CPMutableIndexSet indexSetWithIndex:5]; - - [indexes addIndex:4]; - - [array insertObjects:newAdditions atIndexes:indexes]; - - [self assert:array equals:[@"one", @"two", @"three", @"four", @"a", @"b"]]; - - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], - newAdditions = [CPArray arrayWithObjects:@"a", @"b", @"c"], - indexes = [CPMutableIndexSet indexSetWithIndex:1]; - - [indexes addIndex:2]; - [indexes addIndex:4]; - - [array insertObjects:newAdditions atIndexes:indexes]; - - [self assert:array equals:[@"one", @"a", @"b", @"two", @"c", @"three", @"four"]]; - - - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], - newAdditions = [CPArray arrayWithObjects:@"a", @"b", @"c"], - indexes = [CPMutableIndexSet indexSetWithIndex:1]; - - [indexes addIndex:2]; - [indexes addIndex:6]; - - [array insertObjects:newAdditions atIndexes:indexes]; - - [self assert:array equals:[@"one", @"a", @"b", @"two", @"three", @"four", @"c"]]; - - - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four"], - newAdditions = [CPArray arrayWithObjects:@"a", @"b"], - indexes = [CPMutableIndexSet indexSetWithIndex:5]; - - [indexes addIndex:6]; - - try - { - [array insertObjects:newAdditions atIndexes:indexes]; - [self fail]; - } - catch (e) - { - if ((e.isa) && [e name] == AssertionFailedError) - throw e; - } -} - -- (void)testRemoveObjectsAtIndexes -{ - var array = [CPMutableArray arrayWithObjects:@"one", @"two", @"three", @"four", nil], - indexes = [CPMutableIndexSet indexSetWithIndex:2]; - - [array removeObjectsAtIndexes:indexes]; - - [self assert:array equals:[@"one", @"two", @"four"]]; -} - -- (void)testInsertObjectInArraySortedByDescriptors -{ - var descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:YES]], - array = [1, 3, 5]; - - [array insertObject:0 inArraySortedByDescriptors:descriptors]; - [self assert:[0, 1, 3, 5] equals:array]; - - array = [1, 3, 5]; - [array insertObject:2 inArraySortedByDescriptors:descriptors]; - [self assert:[1, 2, 3, 5] equals:array]; - - array = [1, 3, 5]; - [array insertObject:1 inArraySortedByDescriptors:descriptors]; - [self assert:[1, 1, 3, 5] equals:array]; - - array = [1, 3, 5]; - [array insertObject:6 inArraySortedByDescriptors:descriptors]; - [self assert:[1, 3, 5, 6] equals:array]; - - array = [1, 3, 5]; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[1, 3, 3, 5] equals:array]; - - array = []; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[3] equals:array]; - - descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]]; - - array = [5, 3, 1]; - [array insertObject:0 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 1, 0] equals:array]; - - array = [5, 3, 1]; - [array insertObject:2 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 2, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:1 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 1, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:6 inArraySortedByDescriptors:descriptors]; - [self assert:[6, 5, 3, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 3, 1] equals:array]; - - array = []; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[3] equals:array]; - - descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]]; - - array = [5, 3, 1]; - [array insertObject:0 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 1, 0] equals:array]; - - array = [5, 3, 1]; - [array insertObject:2 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 2, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:1 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 1, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:6 inArraySortedByDescriptors:descriptors]; - [self assert:[6, 5, 3, 1] equals:array]; - - array = [5, 3, 1]; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[5, 3, 3, 1] equals:array]; - - array = []; - [array insertObject:3 inArraySortedByDescriptors:descriptors]; - [self assert:[3] equals:array]; - -} - -- (void)testInitWithArrayCopyItems -{ - var a = [[CopyableObject new], 2, 3, {empty:true}], - b = [[CPArray alloc] initWithArray:a copyItems:YES]; - - [self assert:a notEqual:b]; - - [self assert:a[0] notEqual:b[0]]; - [self assert:a[1] equals:b[1]]; - [self assert:a[2] equals:b[2]]; - [self assertTrue:a[3] === b[3]]; -} - -- (void)testThatCPArrayDoesSortUsingDescriptorsForStrings -{ - var target = ["a", "b", "c", "d"], - pretty = []; - - for (var i = 0; i < target.length; i++) - pretty.push([[CPPrettyObject alloc] initWithValue:target[i] number:i]); - - [pretty sortUsingDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO]]]; - - [self assert:"(\n\t3:d, \n\t2:c, \n\t1:b, \n\t0:a\n)" equals:[pretty description]]; - - [pretty sortUsingDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"value" ascending:YES]]]; - - [self assert:"(\n\t0:a, \n\t1:b, \n\t2:c, \n\t3:d\n)" equals:[pretty description]] -} - -- (void)testThatCPArrayDoesSortUsingTwoDescriptors -{ - var descriptors = [ - [[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO], - [[CPSortDescriptor alloc] initWithKey:@"number" ascending:NO] - ], - target = [ - [[CPPrettyObject alloc] initWithValue:@"a" number:1], - [[CPPrettyObject alloc] initWithValue:@"a" number:2], - [[CPPrettyObject alloc] initWithValue:@"a" number:3], - [[CPPrettyObject alloc] initWithValue:@"b" number:1], - [[CPPrettyObject alloc] initWithValue:@"b" number:2], - [[CPPrettyObject alloc] initWithValue:@"b" number:3], - ]; - - [target sortUsingDescriptors:descriptors]; - - [self assert:@"3:b" equals:[target[0] description]]; - [self assert:@"2:b" equals:[target[1] description]]; - [self assert:@"1:b" equals:[target[2] description]]; - [self assert:@"3:a" equals:[target[3] description]]; - [self assert:@"2:a" equals:[target[4] description]]; - [self assert:@"1:a" equals:[target[5] description]]; -} - -- (void)testThatCPArrayDoesSortUsingTwoDescriptorsOpposite -{ - var descriptors = [ - [[CPSortDescriptor alloc] initWithKey:@"number" ascending:NO], - [[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO] - ], - target = [ - [[CPPrettyObject alloc] initWithValue:@"a" number:1], - [[CPPrettyObject alloc] initWithValue:@"a" number:2], - [[CPPrettyObject alloc] initWithValue:@"a" number:3], - [[CPPrettyObject alloc] initWithValue:@"b" number:1], - [[CPPrettyObject alloc] initWithValue:@"b" number:2], - [[CPPrettyObject alloc] initWithValue:@"b" number:3], - ]; - - [target sortUsingDescriptors:descriptors]; - - [self assert:@"3:b" equals:[target[0] description]]; - [self assert:@"3:a" equals:[target[1] description]]; - [self assert:@"2:b" equals:[target[2] description]]; - [self assert:@"2:a" equals:[target[3] description]]; - [self assert:@"1:b" equals:[target[4] description]]; - [self assert:@"1:a" equals:[target[5] description]]; -} - -- (void)testThatCPArrayDoesSortUsingDescriptorWithMultipleSameValues -{ - var descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]], - target = [1, 1, 2, 4, 3, 1, 2, 4, 5, 1]; - - [target sortUsingDescriptors:descriptors]; - - [self assert:[5, 4, 4, 3, 2, 2, 1, 1, 1, 1] equals:target]; -} - -@end - -@implementation CPPrettyObject : CPObject -{ - CPString value @accessors; - CPNumber number @accessors; -} - -- (id)initWithValue:(CPString)aValue number:(CPNumber)aNumber -{ - self = [super init]; - if (self) - { - number = aNumber; - value = aValue; - } - return self; -} - -- (CPString)description -{ - return number + ":" + value; -} - -@end - -@implementation CopyableObject : CPObject -{ -} - -- (id)copy -{ - return [[[self class] alloc] init]; -} - -@end diff --git a/Tests/Foundation/CPMutableArrayTest.j b/Tests/Foundation/CPMutableArrayTest.j new file mode 100644 index 000000000..379a9a9df --- /dev/null +++ b/Tests/Foundation/CPMutableArrayTest.j @@ -0,0 +1,477 @@ + +@import +@import "CPArrayTest.j" + + +@implementation CPMutableArrayTest : CPArrayTest + ++ (Class)arrayClass +{ + return ConcreteMutableArray; +} + +- (void)test_addObject_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array addObject:0]; + [self assert:array equals:[arrayClass arrayWithObjects:0]]; + + [array addObject:0]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 0]]; + + [array addObject:1]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 0, 1]]; + + [array addObject:[arrayClass arrayWithObjects:0, 1, 2]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 0, 1, [arrayClass arrayWithObjects:0, 1, 2]]]; +} + +- (void)test_addObjectsFromArray_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array addObjectsFromArray:[arrayClass arrayWithObjects:0, 1, 2]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2]]; + + [array addObjectsFromArray:[0, 1, 2]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2, 0, 1, 2]]; + + [array addObjectsFromArray:[arrayClass array]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2, 0, 1, 2]]; + + [array addObjectsFromArray:[]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2, 0, 1, 2]]; +} + +- (void)test_insertObjects_atIndexes_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array insertObjects:[arrayClass arrayWithObjects:2, 4] atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 2)]]; + + [self assert:array equals:[arrayClass arrayWithObjects:2, 4]]; + + [array insertObjects:[arrayClass arrayWithObjects:0] atIndexes:[CPIndexSet indexSetWithIndex:0]]; + + [self assert:array equals:[arrayClass arrayWithObjects:0, 2, 4]]; + + [array insertObjects:[arrayClass arrayWithObjects:5] atIndexes:[CPIndexSet indexSetWithIndex:3]]; + + [self assert:array equals:[arrayClass arrayWithObjects:0, 2, 4, 5]]; + + [array insertObjects:[arrayClass arrayWithObjects:6, 7] atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(4, 2)]]; + + [self assert:array equals:[arrayClass arrayWithObjects:0, 2, 4, 5, 6, 7]]; + + [array insertObjects:[arrayClass arrayWithObjects:-2, -1] atIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 2)]]; + + [self assert:array equals:[arrayClass arrayWithObjects:-2, -1, 0, 2, 4, 5, 6, 7]]; + + var indexSet = [CPMutableIndexSet indexSetWithIndex:3]; + + [indexSet addIndex:5]; + + [array insertObjects:[arrayClass arrayWithObjects:1, 3] atIndexes:indexSet]; + + [self assert:array equals:[arrayClass arrayWithObjects:-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]]; + + [self assertThrows:function() + { + [array insertObjects:[arrayClass array] atIndexes:[CPIndexSet indexSetWithIndex:13]]; + }]; +} + +- (void)test_removeObjectsAtIndexes_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]; + + [array removeObjectsAtIndexes:[CPIndexSet indexSet]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]]; + + [array removeObjectsAtIndexes:[CPIndexSet indexSetWithIndex:2]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 3, 4, 5, 6]]; + + [array removeObjectsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(3, 2)]]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 3, 6]]; + + [array removeObjectsAtIndexes:[CPIndexSet indexSetWithIndexesInRange:CPMakeRange(0, 4)]]; + [self assert:array equals:[arrayClass array]]; +} + +- (void)test_removeAllObjects +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; + + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; + + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6, [arrayClass arrayWithObjects:0, 1, 2]]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; +} + +- (void)test_removeObjectsInRange_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]; + + [array removeObjectsInRange:CPMakeRange(0, 0)]; + [self assert:array equals:[arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]]; + + [array removeObjectsInRange:CPMakeRange(0, 1)]; + [self assert:array equals:[arrayClass arrayWithObjects:1, 2, 3, 4, 5, 6]]; + + [array removeObjectsInRange:CPMakeRange(2, 3)]; + [self assert:array equals:[arrayClass arrayWithObjects:1, 2, 6]]; + + [array removeObjectsInRange:CPMakeRange(2, 1)]; + [self assert:array equals:[arrayClass arrayWithObjects:1, 2]]; + + [array removeObjectsInRange:CPMakeRange(0, 2)]; + [self assert:array equals:[arrayClass array]]; +} + +- (void)test_removeAllObjects +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; + + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; + + array = [arrayClass arrayWithObjects:0, 1, 2, 3, 4, 5, 6, [arrayClass arrayWithObjects:0, 1, 2]]; + + [array removeAllObjects]; + [self assert:0 same:[array count]]; + [self assert:[arrayClass array] equals:array]; +} + +- (void)test_setArray_ +{ + var arrayClass = [[self class] arrayClass], + array = [arrayClass array]; + + [array setArray:[arrayClass array]]; + [self assert:[arrayClass array] equals:array]; + + [array setArray:[arrayClass arrayWithObjects:0, 1, 2, 3]]; + [self assert:[arrayClass arrayWithObjects:0, 1, 2, 3] equals:array]; + + [array setArray:[arrayClass array]]; + [self assert:[arrayClass array] equals:array]; + + [array setArray:[-1, 0, 1]]; + [self assert:[arrayClass arrayWithObjects:-1, 0, 1] equals:array]; +} + +// Old tests +- (void)testInsertObjectInArraySortedByDescriptors +{ + var descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:YES]], + array = [1, 3, 5]; + + [array insertObject:0 inArraySortedByDescriptors:descriptors]; + [self assert:[0, 1, 3, 5] equals:array]; + + array = [1, 3, 5]; + [array insertObject:2 inArraySortedByDescriptors:descriptors]; + [self assert:[1, 2, 3, 5] equals:array]; + + array = [1, 3, 5]; + [array insertObject:1 inArraySortedByDescriptors:descriptors]; + [self assert:[1, 1, 3, 5] equals:array]; + + array = [1, 3, 5]; + [array insertObject:6 inArraySortedByDescriptors:descriptors]; + [self assert:[1, 3, 5, 6] equals:array]; + + array = [1, 3, 5]; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[1, 3, 3, 5] equals:array]; + + array = []; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[3] equals:array]; + + descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]]; + + array = [5, 3, 1]; + [array insertObject:0 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 1, 0] equals:array]; + + array = [5, 3, 1]; + [array insertObject:2 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 2, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:1 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 1, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:6 inArraySortedByDescriptors:descriptors]; + [self assert:[6, 5, 3, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 3, 1] equals:array]; + + array = []; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[3] equals:array]; + + descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]]; + + array = [5, 3, 1]; + [array insertObject:0 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 1, 0] equals:array]; + + array = [5, 3, 1]; + [array insertObject:2 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 2, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:1 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 1, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:6 inArraySortedByDescriptors:descriptors]; + [self assert:[6, 5, 3, 1] equals:array]; + + array = [5, 3, 1]; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[5, 3, 3, 1] equals:array]; + + array = []; + [array insertObject:3 inArraySortedByDescriptors:descriptors]; + [self assert:[3] equals:array]; + +} + +- (void)testInitWithArrayCopyItems +{ + var a = [[CopyableObject new], 2, 3, {empty:true}], + b = [[CPArray alloc] initWithArray:a copyItems:YES]; + + [self assert:a notEqual:b]; + + [self assert:a[0] notEqual:b[0]]; + [self assert:a[1] equals:b[1]]; + [self assert:a[2] equals:b[2]]; + [self assertTrue:a[3] === b[3]]; +} + +- (void)testThatCPArrayDoesSortUsingDescriptorsForStrings +{ + var target = ["a", "b", "c", "d"], + pretty = []; + + for (var i = 0; i < target.length; i++) + pretty.push([[CPPrettyObject alloc] initWithValue:target[i] number:i]); + + [pretty sortUsingDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO]]]; + + [self assert:"(\n\t3:d, \n\t2:c, \n\t1:b, \n\t0:a\n)" equals:[pretty description]]; + + [pretty sortUsingDescriptors:[[[CPSortDescriptor alloc] initWithKey:@"value" ascending:YES]]]; + + [self assert:"(\n\t0:a, \n\t1:b, \n\t2:c, \n\t3:d\n)" equals:[pretty description]] +} + +- (void)testThatCPArrayDoesSortUsingTwoDescriptors +{ + var descriptors = [ + [[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO], + [[CPSortDescriptor alloc] initWithKey:@"number" ascending:NO] + ], + target = [ + [[CPPrettyObject alloc] initWithValue:@"a" number:1], + [[CPPrettyObject alloc] initWithValue:@"a" number:2], + [[CPPrettyObject alloc] initWithValue:@"a" number:3], + [[CPPrettyObject alloc] initWithValue:@"b" number:1], + [[CPPrettyObject alloc] initWithValue:@"b" number:2], + [[CPPrettyObject alloc] initWithValue:@"b" number:3], + ]; + + [target sortUsingDescriptors:descriptors]; + + [self assert:@"3:b" equals:[target[0] description]]; + [self assert:@"2:b" equals:[target[1] description]]; + [self assert:@"1:b" equals:[target[2] description]]; + [self assert:@"3:a" equals:[target[3] description]]; + [self assert:@"2:a" equals:[target[4] description]]; + [self assert:@"1:a" equals:[target[5] description]]; +} + +- (void)testThatCPArrayDoesSortUsingTwoDescriptorsOpposite +{ + var descriptors = [ + [[CPSortDescriptor alloc] initWithKey:@"number" ascending:NO], + [[CPSortDescriptor alloc] initWithKey:@"value" ascending:NO] + ], + target = [ + [[CPPrettyObject alloc] initWithValue:@"a" number:1], + [[CPPrettyObject alloc] initWithValue:@"a" number:2], + [[CPPrettyObject alloc] initWithValue:@"a" number:3], + [[CPPrettyObject alloc] initWithValue:@"b" number:1], + [[CPPrettyObject alloc] initWithValue:@"b" number:2], + [[CPPrettyObject alloc] initWithValue:@"b" number:3], + ]; + + [target sortUsingDescriptors:descriptors]; + + [self assert:@"3:b" equals:[target[0] description]]; + [self assert:@"3:a" equals:[target[1] description]]; + [self assert:@"2:b" equals:[target[2] description]]; + [self assert:@"2:a" equals:[target[3] description]]; + [self assert:@"1:b" equals:[target[4] description]]; + [self assert:@"1:a" equals:[target[5] description]]; +} + +- (void)testThatCPArrayDoesSortUsingDescriptorWithMultipleSameValues +{ + var descriptors = [[[CPSortDescriptor alloc] initWithKey:@"intValue" ascending:NO]], + target = [1, 1, 2, 4, 3, 1, 2, 4, 5, 1]; + + [target sortUsingDescriptors:descriptors]; + + [self assert:[5, 4, 4, 3, 2, 2, 1, 1, 1, 1] equals:target]; +} + +@end + +@implementation CPPrettyObject : CPObject +{ + CPString value @accessors; + CPNumber number @accessors; +} + +- (id)initWithValue:(CPString)aValue number:(CPNumber)aNumber +{ + self = [super init]; + if (self) + { + number = aNumber; + value = aValue; + } + return self; +} + +- (CPString)description +{ + return number + ":" + value; +} + +@end + +@implementation CopyableObject : CPObject +{ +} + +- (id)copy +{ + return [[[self class] alloc] init]; +} + +@end + +@implementation ConcreteMutableArray : CPMutableArray +{ + Array array; +} + +- (id)initWithObjects:(id)anObject, ... +{ + // The arguments array contains self and _cmd, so the first object is at position 2. + var index = 2, + count = arguments.length; + + for (; index < count; ++index) + if (arguments[index] === nil) + break; + + array = Array.prototype.slice.call(arguments, 2, index); + + return self; +} + +- (id)init +{ + self = [super init]; + + if (self) + array = []; + + return self; +} + +- (id)initWithArray:(CPArray)anArray +{ + self = [super init]; + + if (self) + array = [anArray copy]; + + return self; +} + +- (CPUInteger)count +{ + return array.length; +} + +- (id)objectAtIndex:(CPUInteger)anIndex +{ + if (anIndex < 0 || anIndex >= [self count]) + throw "range error"; + + return array[anIndex]; +} + +- (void)insertObject:(id)anObject atIndex:(CPUInteger)anIndex +{ + array.splice(anIndex, 0, anObject); +} + +- (void)removeObjectAtIndex:(CPUInteger)anIndex +{ + array.splice(anIndex, 1); +} + +- (void)addObject:(id)anObject +{ + array.push(anObject); +} + +- (void)removeLastObject +{ + array.pop(); +} + +- (void)replaceObjectAtIndex:(CPUInteger)anIndex withObject:(id)anObject +{ + array[anIndex] = anObject; +} + +@end diff --git a/Tests/Foundation/_CPJavaScriptArrayTest.j b/Tests/Foundation/_CPJavaScriptArrayTest.j index ee92f210a..14fd9fdf0 100644 --- a/Tests/Foundation/_CPJavaScriptArrayTest.j +++ b/Tests/Foundation/_CPJavaScriptArrayTest.j @@ -1,10 +1,10 @@ @import -@import "CPArrayTest.j" +@import "CPMutableArrayTest.j" -@implementation _CPJavaScriptArrayTest : CPArrayTest +@implementation _CPJavaScriptArrayTest : CPMutableArrayTest { }