summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra <fabian.guerra@mapbox.com>2018-04-11 22:15:04 -0400
committerFabian Guerra <fabian.guerra@mapbox.com>2018-04-12 10:11:53 -0400
commitda788073d6ea1251d5cbb89a1a00d00a65a75068 (patch)
tree6f59e8f0592161909520c2222cea80c609433a2a
parent36c95fc5bab9bb13f97576335d1a6a34fad1ad54 (diff)
downloadqtlocation-mapboxgl-da788073d6ea1251d5cbb89a1a00d00a65a75068.tar.gz
[ios, macos] Refactor NSPredicate operators.
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm32
-rw-r--r--platform/darwin/src/NSPredicate+MGLAdditions.mm37
-rw-r--r--platform/darwin/test/MGLPredicateTests.mm51
3 files changed, 89 insertions, 31 deletions
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index 3cc86258bd..89026f63c3 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -320,25 +320,25 @@
break;
case NSBetweenPredicateOperatorType: {
op = @"all";
- NSArray *arguments = self.rightExpression.constantValue;
- NSPredicate *leftHandPredicate = [NSComparisonPredicate predicateWithLeftExpression:arguments[0]
+ NSArray *limits = self.rightExpression.constantValue;
+ NSPredicate *leftHandPredicate = [NSComparisonPredicate predicateWithLeftExpression:limits[0]
rightExpression:self.leftExpression
modifier:NSAllPredicateModifier
type:NSLessThanOrEqualToPredicateOperatorType
options:0];
NSPredicate *rightHandPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.leftExpression
- rightExpression:arguments[1]
+ rightExpression:limits[1]
modifier:NSAllPredicateModifier
type:NSLessThanOrEqualToPredicateOperatorType
options:0];
return @[op, leftHandPredicate.mgl_jsonExpressionObject, rightHandPredicate.mgl_jsonExpressionObject];
}
- case NSInPredicateOperatorType:
- op = @"match";
- break;
- case NSContainsPredicateOperatorType:
- op = @"has";
- break;
+ case NSInPredicateOperatorType: {
+ return [self mgl_jsonMatchObjectWithExpression:self.leftExpression options:self.rightExpression];
+ }
+ case NSContainsPredicateOperatorType: {
+ return [self mgl_jsonMatchObjectWithExpression:self.rightExpression options:self.leftExpression];
+ }
case NSMatchesPredicateOperatorType:
case NSLikePredicateOperatorType:
case NSBeginsWithPredicateOperatorType:
@@ -353,4 +353,18 @@
return nil;
}
+- (id)mgl_jsonMatchObjectWithExpression:(NSExpression *)operand options:(NSExpression *)options {
+ NSMutableArray *elements = [NSMutableArray arrayWithObjects:@"match", operand.mgl_jsonExpressionObject, nil];
+ NSArray *optionsExpressions = options.constantValue;
+ NSEnumerator *optionsEnumerator = optionsExpressions.objectEnumerator;
+ while (id object = optionsEnumerator.nextObject) {
+ id option = ((NSExpression *)object).mgl_jsonExpressionObject;
+ [elements addObject:option];
+ [elements addObject:[NSExpression expressionForConstantValue:@YES].mgl_jsonExpressionObject];
+ }
+ [elements addObject:[NSExpression expressionForConstantValue:@NO].mgl_jsonExpressionObject];
+
+ return elements;
+}
+
@end
diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm
index 6ce46629af..34571ea847 100644
--- a/platform/darwin/src/NSPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm
@@ -304,12 +304,27 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
NSArray *rightCondition = jsonObjects[1];
NSString *leftOperator = leftCondition.firstObject;
NSString *rightOperator = rightCondition.firstObject;
- if ([leftOperator isEqualToString:@"<="] && [rightOperator isEqualToString:@"<="]) {
- return [NSPredicate predicateWithFormat:@"%@ BETWEEN %@", [NSExpression mgl_expressionWithJSONObject:leftCondition[2]], @[[NSExpression mgl_expressionWithJSONObject:leftCondition[1]], [NSExpression mgl_expressionWithJSONObject:rightCondition[2]]]];
- } else if([leftOperator isEqualToString:@">="] && [rightOperator isEqualToString:@"<="]) {
- return [NSPredicate predicateWithFormat:@"%@ BETWEEN %@", [NSExpression mgl_expressionWithJSONObject:leftCondition[1]], @[[NSExpression mgl_expressionWithJSONObject:leftCondition[2]], [NSExpression mgl_expressionWithJSONObject:rightCondition[2]]]];
+ NSArray *limits;
+ NSExpression *leftConditionExpression;
+ if([leftOperator isEqualToString:@">="] && [rightOperator isEqualToString:@"<="]) {
+ limits = @[[NSExpression mgl_expressionWithJSONObject:leftCondition[2]], [NSExpression mgl_expressionWithJSONObject:rightCondition[2]]];
+ leftConditionExpression = [NSExpression mgl_expressionWithJSONObject:leftCondition[1]];
+
+ } else if ([leftOperator isEqualToString:@"<="] && [rightOperator isEqualToString:@"<="]) {
+ limits = @[[NSExpression mgl_expressionWithJSONObject:leftCondition[1]], [NSExpression mgl_expressionWithJSONObject:rightCondition[2]]];
+ leftConditionExpression = [NSExpression mgl_expressionWithJSONObject:leftCondition[2]];
+
+ } else if([leftOperator isEqualToString:@"<="] && [rightOperator isEqualToString:@">="]) {
+ limits = @[[NSExpression mgl_expressionWithJSONObject:leftCondition[1]], [NSExpression mgl_expressionWithJSONObject:rightCondition[1]]];
+ leftConditionExpression = [NSExpression mgl_expressionWithJSONObject:leftCondition[2]];
+
} else if([leftOperator isEqualToString:@">="] && [rightOperator isEqualToString:@">="]) {
- return [NSPredicate predicateWithFormat:@"%@ BETWEEN %@", [NSExpression mgl_expressionWithJSONObject:leftCondition[1]], @[[NSExpression mgl_expressionWithJSONObject:leftCondition[2]], [NSExpression mgl_expressionWithJSONObject:rightCondition[1]]]];
+ limits = @[[NSExpression mgl_expressionWithJSONObject:leftCondition[2]], [NSExpression mgl_expressionWithJSONObject:rightCondition[1]]];
+ leftConditionExpression = [NSExpression mgl_expressionWithJSONObject:leftCondition[1]];
+ }
+
+ if (limits && limits) {
+ return [NSPredicate predicateWithFormat:@"%@ BETWEEN %@", leftConditionExpression, [NSExpression expressionForAggregate:limits]];
}
}
}
@@ -320,12 +335,12 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
return [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates];
}
if ([op isEqualToString:@"match"]) {
- NSArray *subpredicates = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ IN %@" argumentArray:subpredicates];
- }
- if ([op isEqualToString:@"has"]) {
- NSArray *subpredicates = MGLSubexpressionsWithJSONObjects([objects subarrayWithRange:NSMakeRange(1, objects.count - 1)]);
- return [NSPredicate predicateWithFormat:@"%@ CONTAINS %@" argumentArray:subpredicates];
+ NSExpression *expression = [NSExpression mgl_expressionWithJSONObject:object];
+ return [NSComparisonPredicate predicateWithLeftExpression:expression
+ rightExpression:[NSExpression expressionForConstantValue:@YES]
+ modifier:NSDirectPredicateModifier
+ type:NSNotEqualToPredicateOperatorType
+ options:0];
}
NSAssert(NO, @"Unrecognized expression conditional operator %@.", op);
diff --git a/platform/darwin/test/MGLPredicateTests.mm b/platform/darwin/test/MGLPredicateTests.mm
index f562415b28..dcbc7caaa5 100644
--- a/platform/darwin/test/MGLPredicateTests.mm
+++ b/platform/darwin/test/MGLPredicateTests.mm
@@ -578,18 +578,33 @@ namespace mbgl {
}
{
NSArray *expected = @[@"all", @[@"<=", @10, @[@"get", @"x"]], @[@"<=", @[@"get", @"x"], @100]];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", @[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN {10, 100}"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
}
{
NSArray *expected = @[@"all", @[@">=", @[@"get", @"x"], @10], @[@"<=", @[@"get", @"x"], @100]];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", @[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSExpression *limits = [NSExpression expressionForAggregate:@[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", limits];
+ XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
+ }
+ {
+ NSArray *expected = @[@"all", @[@"<=", @10, @[@"get", @"x"]], @[@"<=", @[@"get", @"x"], @100]];
+ NSExpression *limits = [NSExpression expressionForAggregate:@[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", limits];
+ XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
+ XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
+ }
+ {
+ NSArray *expected = @[@"all", @[@"<=", @10, @[@"get", @"x"]], @[@">=", @100, @[@"get", @"x"]]];
+ NSExpression *limits = [NSExpression expressionForAggregate:@[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", limits];
XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
}
{
NSArray *expected = @[@"all", @[@">=", @[@"get", @"x"], @10], @[@">=", @100, @[@"get", @"x"]]];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", @[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSExpression *limits = [NSExpression expressionForAggregate:@[[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]]];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x BETWEEN %@", limits];
XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
}
{
@@ -599,29 +614,43 @@ namespace mbgl {
XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
}
{
- NSArray *expected = @[@"match", @[@"id"], @[@"literal", @[@6, @5, @4, @3]]];
+ NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$mgl_featureIdentifier IN { 6, 5, 4, 3}"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
+ NSString *mglMatch = @"MGL_MATCH($mgl_featureIdentifier, 6, YES, 5, YES, 4, YES, 3, YES, NO)";
+ NSPredicate *predicateAfter = [self matchPredicateWithFormat:mglMatch];
+ XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicateAfter);
}
{
- NSArray *expected = @[@"!", @[@"match", @[@"get", @"x"], @[@"literal", @[@6, @5, @4, @3]]]];
+ NSArray *expected = @[@"!", @[@"match", @[@"get", @"x"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT x IN { 6, 5, 4, 3}"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
}
{
- NSArray *expected = @[@"has", @[@"literal", @[@6, @5, @4, @3]], @[@"get", @"x"]];
+ NSArray *expected = @[@"match", @[@"get", @"x"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS x"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
+ NSString *mglMatch = @"MGL_MATCH(x, 6, YES, 5, YES, 4, YES, 3, YES, NO)";
+ NSPredicate *predicateAfter = [self matchPredicateWithFormat:mglMatch];
+ XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicateAfter);
}
{
- NSArray *expected = @[@"has", @[@"literal", @[@6, @5, @4, @3]], @[@"id"]];
+ NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS $mgl_featureIdentifier"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicate);
+ NSString *mglMatch = @"MGL_MATCH($mgl_featureIdentifier, 6, YES, 5, YES, 4, YES, 3, YES, NO)";
+ NSPredicate *predicateAfter = [self matchPredicateWithFormat:mglMatch];
+ XCTAssertEqualObjects([NSPredicate mgl_predicateWithJSONObject:expected], predicateAfter);
}
}
+- (NSPredicate *)matchPredicateWithFormat:(NSString *)format {
+ NSPredicate *predicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionWithFormat:format]
+ rightExpression:[NSExpression expressionForConstantValue:@YES]
+ modifier:NSDirectPredicateModifier
+ type:NSNotEqualToPredicateOperatorType
+ options:0];
+ return predicate;
+}
+
@end