[ios, macos] Aggregate equality predicates
Added support for “ANY … =” and “ALL … !=” as synonyms for “IN” and “NOT IN”, respectively.
This commit is contained in:
committed by
Minh Nguyễn
parent
bc6f434a88
commit
fb559ea8d4
@@ -79,6 +79,52 @@
|
||||
@implementation NSComparisonPredicate (MGLExpressionAdditions)
|
||||
|
||||
- (id)mgl_jsonExpressionObject {
|
||||
switch (self.comparisonPredicateModifier) {
|
||||
case NSDirectPredicateModifier:
|
||||
break;
|
||||
|
||||
case NSAllPredicateModifier:
|
||||
// “ALL x != y” is logically equivalent to “NOT y IN x”.
|
||||
if (self.predicateOperatorType == NSNotEqualToPredicateOperatorType) {
|
||||
// https://github.com/mapbox/mapbox-gl-js/issues/9339
|
||||
if (self.options) {
|
||||
[NSException raise:NSInvalidArgumentException format:@"NSComparisonPredicateOptions not supported for “ALL … !=” comparisons."];
|
||||
}
|
||||
|
||||
NSPredicate *directPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.rightExpression
|
||||
rightExpression:self.leftExpression
|
||||
modifier:NSDirectPredicateModifier
|
||||
type:NSInPredicateOperatorType
|
||||
options:self.options];
|
||||
NSPredicate *invertedPredicate = [NSCompoundPredicate notPredicateWithSubpredicate:directPredicate];
|
||||
return invertedPredicate.mgl_jsonExpressionObject;
|
||||
} else {
|
||||
[NSException raise:NSInvalidArgumentException format:@"“ALL” is only supported for the “!=” operator."];
|
||||
}
|
||||
|
||||
case NSAnyPredicateModifier:
|
||||
// “ANY x = y” is logically equivalent to “y IN x”.
|
||||
if (self.predicateOperatorType == NSEqualToPredicateOperatorType) {
|
||||
// https://github.com/mapbox/mapbox-gl-js/issues/9339
|
||||
if (self.options) {
|
||||
[NSException raise:NSInvalidArgumentException format:@"NSComparisonPredicateOptions not supported for “ANY … =” comparisons."];
|
||||
}
|
||||
|
||||
NSPredicate *directPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.rightExpression
|
||||
rightExpression:self.leftExpression
|
||||
modifier:NSDirectPredicateModifier
|
||||
type:NSInPredicateOperatorType
|
||||
options:self.options];
|
||||
return directPredicate.mgl_jsonExpressionObject;
|
||||
} else {
|
||||
[NSException raise:NSInvalidArgumentException format:@"“ANY” or “SOME” is only supported for the “=” operator."];
|
||||
}
|
||||
|
||||
default:
|
||||
[NSException raise:NSInvalidArgumentException
|
||||
format:@"NSComparisonPredicateModifier:%lu is not supported.", (unsigned long)self.comparisonPredicateModifier];
|
||||
}
|
||||
|
||||
NSString *op;
|
||||
switch (self.predicateOperatorType) {
|
||||
case NSLessThanPredicateOperatorType:
|
||||
|
||||
@@ -315,6 +315,53 @@
|
||||
XCTAssertEqualObjects([NSPredicate predicateWithMGLJSONObject:expected], predicateAfter);
|
||||
XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:predicate.mgl_filter], [NSPredicate predicateWithValue:NO]);
|
||||
}
|
||||
{
|
||||
NSArray *expected = @[@"in", @[@"id"], @[@"literal", @[@6, @5, @4, @3]]];
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY {6, 5, 4, 3} = $featureIdentifier"];
|
||||
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
||||
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"$featureIdentifier IN {6, 5, 4, 3}"];
|
||||
XCTAssertEqualObjects([NSPredicate predicateWithMGLJSONObject:expected], predicateAfter);
|
||||
[self testSymmetryWithPredicate:[NSPredicate predicateWithMGLJSONObject:expected]
|
||||
mustRoundTrip:YES];
|
||||
}
|
||||
{
|
||||
NSArray *expected = @[@"!", @[@"in", @[@"id"], @[@"literal", @[@6, @5, @4, @3]]]];
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NONE {6, 5, 4, 3} = $featureIdentifier"];
|
||||
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
||||
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"NOT $featureIdentifier IN {6, 5, 4, 3}"];
|
||||
XCTAssertEqualObjects([NSPredicate predicateWithMGLJSONObject:expected], predicateAfter);
|
||||
[self testSymmetryWithPredicate:[NSPredicate predicateWithMGLJSONObject:expected]
|
||||
mustRoundTrip:YES];
|
||||
}
|
||||
{
|
||||
NSArray *expected = @[@"!", @[@"in", @[@"id"], @[@"literal", @[@6, @5, @4, @3]]]];
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ALL {6, 5, 4, 3} != $featureIdentifier"];
|
||||
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
||||
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"NOT $featureIdentifier IN {6, 5, 4, 3}"];
|
||||
XCTAssertEqualObjects([NSPredicate predicateWithMGLJSONObject:expected], predicateAfter);
|
||||
[self testSymmetryWithPredicate:[NSPredicate predicateWithMGLJSONObject:expected]
|
||||
mustRoundTrip:YES];
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY {6, 5, 4, 3} != $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY {6, 5, 4, 3} > $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NONE {6, 5, 4, 3} != $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ALL {6, 5, 4, 3} = $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ALL {6, 5, 4, 3} < $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testComparisonPredicatesWithOptions {
|
||||
@@ -388,6 +435,20 @@
|
||||
@"locale": @"tlh"}]];
|
||||
XCTAssertEqualObjects([predicate.mgl_jsonExpressionObject lastObject], jsonExpression);
|
||||
}
|
||||
|
||||
// https://github.com/mapbox/mapbox-gl-js/issues/9339
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY {6, 5, 4, 3} =[c] $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NONE {6, 5, 4, 3} =[d] $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
{
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ALL {6, 5, 4, 3} !=[cd] $featureIdentifier"];
|
||||
XCTAssertThrowsSpecificNamed(predicate.mgl_jsonExpressionObject, NSException, NSInvalidArgumentException);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)testCompoundPredicates {
|
||||
|
||||
Reference in New Issue
Block a user