diff --git a/Foundation/CPArray+KVO.j b/Foundation/CPArray+KVO.j index 4c56931a3..15b787405 100644 --- a/Foundation/CPArray+KVO.j +++ b/Foundation/CPArray+KVO.j @@ -352,9 +352,17 @@ if (aKeyPath.indexOf("@") === 0) { var dotIndex = aKeyPath.indexOf("."), - operator = aKeyPath.substring(1, dotIndex), - parameter = aKeyPath.substring(dotIndex+1); + operator, + parameter; + if (dotIndex !== -1) + { + operator = aKeyPath.substring(1, dotIndex); + parameter = aKeyPath.substring(dotIndex+1); + } + else + operator = aKeyPath.substring(1); + if (kvoOperators[operator]) return kvoOperators[operator](self, _cmd, parameter); diff --git a/Foundation/CPKeyValueCoding.j b/Foundation/CPKeyValueCoding.j index 140153c45..8e00497ee 100644 --- a/Foundation/CPKeyValueCoding.j +++ b/Foundation/CPKeyValueCoding.j @@ -174,17 +174,16 @@ CPUnknownUserInfoKey = @"CPUnknownUserInfoKey"; - (id)valueForKeyPath:(CPString)aKeyPath { - var keys = aKeyPath.split("."), - - index = 0, - count = keys.length, - - value = self; + var firstDotIndex = aKeyPath.indexOf("."); - for(; index < count; ++index) - value = [value valueForKey:keys[index]]; + if (firstDotIndex === -1) + return [self valueForKey:aKeyPath]; - return value; + var firstKeyComponent = aKeyPath.substring(0, firstDotIndex), + remainingKeyPath = aKeyPath.substring(firstDotIndex+1), + value = [self valueForKey:firstKeyComponent]; + + return [value valueForKeyPath:remainingKeyPath]; } - (CPDictionary)dictionaryWithValuesForKeys:(CPArray)keys diff --git a/Tests/Foundation/CPKVOTest.j b/Tests/Foundation/CPKVOTest.j index 9244db558..3667efca4 100644 --- a/Tests/Foundation/CPKVOTest.j +++ b/Tests/Foundation/CPKVOTest.j @@ -371,11 +371,16 @@ var one = [1, 1, 1, 1, 1, 1, 1, 1], two = [1, 2, 3, 4, 8, 0]; - [self assertTrue:[one valueForKey:"@count"]===8 message:@"expected count of 8, got: "+[one valueForKey:@"@count"]] - [self assertTrue:[one valueForKeyPath:@"@sum.intValue"]===8 message:@"expected sum of 8, got: "+[one valueForKeyPath:@"@sum.intValue"]]; - [self assertTrue:[two valueForKeyPath:@"@avg.intValue"]===3 message:@"expected avg of 3, got: "+[two valueForKeyPath:@"@avg.intValue"]]; - [self assertTrue:[two valueForKeyPath:@"@max.intValue"]===8 message:@"expected max of 8, got: "+[two valueForKeyPath:@"@max.intValue"]]; - [self assertTrue:[two valueForKeyPath:@"@min.intValue"]===0 message:@"expected min of 0, got: "+[two valueForKeyPath:@"@min.intValue"]]; + [self assert:[one valueForKey:"@count"] equals:8]; + [self assert:[one valueForKeyPath:"@sum.intValue"] equals:8]; + [self assert:[two valueForKeyPath:"@avg.intValue"] equals:3]; + [self assert:[two valueForKeyPath:"@max.intValue"] equals:8]; + [self assert:[two valueForKeyPath:"@min.intValue"] equals:0]; + + var a = [A new]; + [a setValue:one forKey:"b"]; + [self assert:[a valueForKeyPath:"b.@count"] equals:8]; + [self assert:[a valueForKeyPath:"b.@sum.intValue"] equals:8]; } - (void)testPerformance