diff --git a/Foundation/CPArray/CPMutableArray.j b/Foundation/CPArray/CPMutableArray.j index df9eed7cc..58f978f6d 100644 --- a/Foundation/CPArray/CPMutableArray.j +++ b/Foundation/CPArray/CPMutableArray.j @@ -429,6 +429,9 @@ var sortArrayUsingFunction = function(array, aFunction, aContext) } } +// This is for speed +var CPMutableArrayNull = [CPNull null]; + // Observe that the sort descriptors has the reversed order by the caller var sortArrayUsingJSDescriptors = function(a, d) { @@ -451,7 +454,10 @@ var sortArrayUsingJSDescriptors = function(a, d) aUID, bUID, key, - dd; + dd, + value1, + value2, + cpNull = CPMutableArrayNull; if (dl < 0) return; @@ -519,7 +525,14 @@ var sortArrayUsingJSDescriptors = function(a, d) { dd = d[cn]; key = dd.k; - o = objj_msgSend(C1[key], dd.s, C2[key]); + value1 = C1[key]; + value2 = C2[key]; + if (value1 === nil || value1 === cpNull) + o = value2 === nil || value2 === cpNull ? CPOrderedSame : CPOrderedAscending; + else + { + o = value2 === nil || value2 === cpNull ? CPOrderedDescending : objj_msgSend(value1, dd.s, value2); + } if (o && !dd.a) o = -o; diff --git a/Tests/Foundation/CPMutableArrayTest.j b/Tests/Foundation/CPMutableArrayTest.j index 30090b564..e1bc667f5 100644 --- a/Tests/Foundation/CPMutableArrayTest.j +++ b/Tests/Foundation/CPMutableArrayTest.j @@ -470,6 +470,26 @@ [self assert:[5, 4, 4, 3, 2, 2, 1, 1, 1, 1] equals:target]; } +- (void)testThatCPArrayDoesSortCorrectWithNilAndCPNull +{ + var descriptors = [[CPSortDescriptor sortDescriptorWithKey:@"number" ascending:NO]], + target = [ + [[CPPrettyObject alloc] initWithValue:@"a" number:nil], + [[CPPrettyObject alloc] initWithValue:@"a" number:[CPNull null]], + [[CPPrettyObject alloc] initWithValue:@"a" number:@"Objective-J"], + [[CPPrettyObject alloc] initWithValue:@"a" number:[CPNull null]], + [[CPPrettyObject alloc] initWithValue:@"a" number:nil], + ]; + + [target sortUsingDescriptors:descriptors]; + + [self assert:@"Objective-J" equals:[target[0] number]]; + [self assert:nil equals:[target[1] number]]; + [self assert:[CPNull null] equals:[target[2] number]]; + [self assert:[CPNull null] equals:[target[3] number]]; + [self assert:nil equals:[target[4] number]]; +} + - (void)testMutableCopy { var normalArray = [],