[ios, macos] Add match expressions support. (#11464)

* [ios, macos] Add match expressions support.

* [ios, macos] Add coalesce operator support.

* [ios, macos] Add coalesce operator test.

* [ios, macos] Match operator implementation is moved to NSPredicate.

* [ios, macos] Match operator function implementation refactor.

* [ios, macos] Address merge conflicts.
This commit is contained in:
Fabian Guerra Soto
2018-03-26 15:22:54 -04:00
committed by GitHub
parent 9eff2c52fb
commit 9a663fb479
5 changed files with 87 additions and 3 deletions

View File

@@ -258,6 +258,12 @@
return [self valueForKeyPath:@"mgl_jsonExpressionObject"];
}
- (id)mgl_coalesce {
[NSException raise:NSInvalidArgumentException
format:@"Coalesce expressions lack underlying Objective-C implementations."];
return nil;
}
@end
@implementation NSDictionary (MGLExpressionAdditions)
@@ -476,11 +482,31 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
} else {
[arguments addObject:[NSExpression mgl_expressionWithJSONObject:caseExpressions[index]]];
}
}
return [NSExpression expressionForFunction:firstConditional selectorName:@"mgl_case:" arguments:arguments];
} else {
} else if ([op isEqualToString:@"match"]) {
NSExpression *operand = [NSExpression mgl_expressionWithJSONObject:argumentObjects[0]];
NSArray *matchOptions = [argumentObjects subarrayWithRange:NSMakeRange(1, argumentObjects.count - 1)];
NSMutableArray *optionsArray = [NSMutableArray array];
NSEnumerator *optionsEnumerator = matchOptions.objectEnumerator;
while (id object = optionsEnumerator.nextObject) {
NSExpression *option = [NSExpression mgl_expressionWithJSONObject:object];
[optionsArray addObject:option];
}
return [NSExpression expressionForFunction:operand
selectorName:@"mgl_match:"
arguments:optionsArray];
} else if ([op isEqualToString:@"coalesce"]) {
NSMutableArray *expressions = [NSMutableArray array];
for (id operand in argumentObjects) {
[expressions addObject:[NSExpression mgl_expressionWithJSONObject:operand]];
}
return [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')", expressions];
}else {
[NSException raise:NSInvalidArgumentException
format:@"Expression operator %@ not yet implemented.", op];
}
@@ -674,7 +700,7 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
} 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;
@@ -683,6 +709,23 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
[expressionObject addObject:option.mgl_jsonExpressionObject];
}
}
return expressionObject;
} else if ([function isEqualToString:@"mgl_match:"]) {
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"match", self.operand.mgl_jsonExpressionObject, nil];
for (NSExpression *option in self.arguments) {
[expressionObject addObject:option.mgl_jsonExpressionObject];
}
return expressionObject;
} else if ([function isEqualToString:@"mgl_coalesce"]) {
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"coalesce", nil];
for (NSExpression *expression in self.operand.constantValue) {
[expressionObject addObject:[expression mgl_jsonExpressionObject]];
}
return expressionObject;
} else if ([function isEqualToString:@"median:"] ||

View File

@@ -54,6 +54,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) id mgl_jsonExpressionObject;
@property (nonatomic, readonly) id mgl_coalesce;
@end
@interface NSDictionary (MGLExpressionAdditions)

View File

@@ -18,4 +18,6 @@
- (id)mgl_case:(id)firstValue, ...;
- (id)mgl_match:(NSExpression *)firstCase, ...;
@end

View File

@@ -349,4 +349,10 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
return nil;
}
- (id)mgl_match:(NSExpression *)firstCase, ... {
[NSException raise:NSInvalidArgumentException
format:@"Match expressions lack underlying Objective-C implementations."];
return nil;
}
@end

View File

@@ -572,6 +572,37 @@ using namespace std::string_literals;
}
}
- (void)testMatchExpressionObject {
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(2 - 1, 'mgl_match:', %@, %@, %@, %@, 'default')", MGLConstantExpression(@1),
MGLConstantExpression(@"one"),
MGLConstantExpression(@0),
MGLConstantExpression(@"zero")];
NSArray *jsonExpression = @[@"match", @[@"-", @2, @1], @1, @"one", @0, @"zero", @"default"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(2 * 1, 'mgl_match:', %@, %@, 'default')", MGLConstantExpression(@1), MGLConstantExpression(@"one")];
NSArray *jsonExpression = @[@"match", @[@"*", @2, @1], @1, @"one", @"default"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
}
- (void)testCoalesceExpressionObject {
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')", @[[NSExpression expressionForKeyPath:@"x"],
[NSExpression expressionForKeyPath:@"y"],
[NSExpression expressionForKeyPath:@"z"],
[NSExpression expressionForConstantValue:@0]]];
NSArray *jsonExpression = @[@"coalesce", @[@"get", @"x"], @[@"get", @"y"], @[@"get", @"z"], @0];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
}
}
- (void)testConditionalExpressionObject {
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@)",