Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[ios, macos] Case operator now has iOS 8 support.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-guerra committed Mar 23, 2018
1 parent 7439c42 commit a832f82
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 62 deletions.
54 changes: 27 additions & 27 deletions platform/darwin/src/NSExpression+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -464,36 +464,22 @@ + (instancetype)mgl_expressionWithJSONObject:(id)object {
} else if ([op isEqualToString:@"var"]) {
return [NSExpression expressionForVariable:argumentObjects.firstObject];
} else if ([op isEqualToString:@"case"]) {
NSPredicate *conditional = [NSPredicate mgl_predicateWithJSONObject:argumentObjects.firstObject];
NSExpression *trueExpression;
NSInteger rightBranchIndex = 2;

if ([argumentObjects[1] isKindOfClass:[NSArray class]] ) {
NSInteger length = 1;
for (NSInteger index = 1; index < argumentObjects.count - 2; index++) {
length++;
if (![argumentObjects[index] isKindOfClass:[NSArray class]] && ![argumentObjects[index + 1] isKindOfClass:[NSArray class]]) {
break;
}
}
NSArray *trueObjects = [@[@"case"] arrayByAddingObjectsFromArray:
[argumentObjects subarrayWithRange:NSMakeRange(1, length)]];
trueExpression = [NSExpression mgl_expressionWithJSONObject:trueObjects];
rightBranchIndex = length + 1;
} else {
trueExpression = [NSExpression mgl_expressionWithJSONObject:argumentObjects[1]];
}
NSArray *caseExpressions = argumentObjects;
NSExpression *firstConditional = [NSExpression expressionWithFormat:@"%@", [NSPredicate mgl_predicateWithJSONObject:caseExpressions[0]]];
NSMutableArray *arguments = [NSMutableArray array];

NSExpression *falseExpression;
if ([argumentObjects[rightBranchIndex] isKindOfClass:[NSArray class]] ) {
NSArray *falseObjects = [@[@"case"] arrayByAddingObjectsFromArray:
[argumentObjects subarrayWithRange:NSMakeRange(rightBranchIndex, argumentObjects.count - rightBranchIndex)]];
falseExpression = [NSExpression mgl_expressionWithJSONObject:falseObjects];
} else {
falseExpression = [NSExpression mgl_expressionWithJSONObject:argumentObjects[rightBranchIndex]];
for (NSUInteger index = 1; index < caseExpressions.count; index++) {
if ([caseExpressions[index] isKindOfClass:[NSArray class]]) {
NSPredicate *conditional = [NSPredicate mgl_predicateWithJSONObject:caseExpressions[index]];
NSExpression *argument = [NSExpression expressionWithFormat:@"%@", conditional];
[arguments addObject:argument];
} else {
[arguments addObject:[NSExpression mgl_expressionWithJSONObject:caseExpressions[index]]];
}

}

return [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression];
return [NSExpression expressionForFunction:firstConditional selectorName:@"mgl_case:" arguments:arguments];
} else {
[NSException raise:NSInvalidArgumentException
format:@"Expression operator %@ not yet implemented.", op];
Expand Down Expand Up @@ -684,6 +670,20 @@ - (id)mgl_jsonExpressionObject {
[expressionObject addObject:obj.mgl_jsonExpressionObject];
}];
[expressionObject addObject:self.operand.mgl_jsonExpressionObject];
return expressionObject;
} else if ([function isEqualToString:@"mgl_case:"]) {
NSPredicate *firstConditional = (NSPredicate *)self.operand.constantValue;
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"case", firstConditional.mgl_jsonExpressionObject, nil];

for (NSExpression *option in self.arguments) {
if ([option respondsToSelector:@selector(constantValue)] && [option.constantValue isKindOfClass:[NSComparisonPredicate class]]) {
NSPredicate *predicate = (NSPredicate *)option.constantValue;
[expressionObject addObject:predicate.mgl_jsonExpressionObject];
} else {
[expressionObject addObject:option.mgl_jsonExpressionObject];
}
}

return expressionObject;
} else if ([function isEqualToString:@"median:"] ||
[function isEqualToString:@"mode:"] ||
Expand Down
2 changes: 2 additions & 0 deletions platform/darwin/src/NSPredicate+MGLAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@

@property (nonatomic, readonly) id mgl_jsonExpressionObject;

- (id)mgl_case:(id)firstValue, ...;

@end
25 changes: 25 additions & 0 deletions platform/darwin/src/NSPredicate+MGLAdditions.mm
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,29 @@ - (id)mgl_jsonExpressionObject {
return nil;
}

- (id)mgl_case:(id)firstValue, ... {

if ([self evaluateWithObject:nil]) {
return firstValue;
}

id eachExpression;
va_list argumentList;
va_start(argumentList, firstValue);

while ((eachExpression = va_arg(argumentList, id))) {
if ([eachExpression isKindOfClass:[NSComparisonPredicate class]]) {
id valueExpression = va_arg(argumentList, id);
if ([eachExpression evaluateWithObject:nil]) {
return valueExpression;
}
} else {
return eachExpression;
}
}
va_end(argumentList);

return nil;
}

@end
57 changes: 22 additions & 35 deletions platform/darwin/test/MGLExpressionTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -573,42 +573,29 @@ - (void)testInterpolationExpressionObject {
}

- (void)testConditionalExpressionObject {
// FIXME: This test crashes because iOS 8 doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`.
// https://github.com/mapbox/mapbox-gl-native/issues/11007
if (@available(iOS 9.0, *)) {
{
NSPredicate *conditional = [NSPredicate predicateWithFormat:@"1 = 2"];
NSExpression *trueExpression = [NSExpression expressionForConstantValue:@YES];
NSExpression *falseExpression = [NSExpression expressionForConstantValue:@NO];
NSExpression *expression = [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression];
NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TERNARY(1 = 2, TRUE, FALSE)"].mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TRUE, TERNARY(1 = 2, TRUE, FALSE))"];
NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @YES, @[@"==", @1, @2], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TERNARY(1 = 2, TRUE, FALSE), TRUE)"];
NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @[@"==", @1, @2], @YES, @NO, @YES];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
{
NSExpression *nestedExpression = [NSExpression expressionWithFormat:@"TERNARY(1 == 2, TERNARY(0 == 1, FALSE, TERNARY(4 == 5, FALSE, FALSE)), TERNARY(1 == 1, TRUE, FALSE))"];
NSArray *nestedJSONExpression = @[@"case", @[@"==", @1, @2], @[@"==", @0, @1], @NO, @[@"==", @4, @5], @NO, @NO, @[@"==", @1, @1], @YES, @NO];
XCTAssertEqualObjects(nestedExpression.mgl_jsonExpressionObject, nestedJSONExpression);
XCTAssertEqualObjects([nestedExpression expressionValueWithObject:nil context:nil], @YES);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:nestedJSONExpression], nestedExpression);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@)",
[NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
MGLConstantExpression(@YES),
MGLConstantExpression(@NO)];
NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@, %@, %@)",
[NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
MGLConstantExpression(@YES),
[NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]],
MGLConstantExpression(@YES),
MGLConstantExpression(@NO)];
NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES);
}

}

@end

0 comments on commit a832f82

Please sign in to comment.