715 lines
34 KiB
Plaintext
715 lines
34 KiB
Plaintext
#import <Mapbox.h>
|
|
#import <XCTest/XCTest.h>
|
|
|
|
#import "MLNValueEvaluator.h"
|
|
#import "NSPredicate+MLNPrivateAdditions.h"
|
|
|
|
@implementation NSString (MLNAdditions)
|
|
|
|
- (NSString *)stringByRemovingPointerAddresses {
|
|
return [self stringByReplacingOccurrencesOfString:@"\\b0x[0-9a-f]+\\b"
|
|
withString:@"0xdeadbeef"
|
|
options:NSRegularExpressionSearch
|
|
range:NSMakeRange(0, self.length)];
|
|
}
|
|
|
|
@end
|
|
|
|
@interface MLNPredicateTests : XCTestCase
|
|
@end
|
|
|
|
@implementation MLNPredicateTests
|
|
|
|
- (void)testUnsupportedFilterPredicates {
|
|
XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a BEGINSWITH 'L'"].mgl_filter,
|
|
NSException, NSInvalidArgumentException);
|
|
XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"a ENDSWITH 'itude'"].mgl_filter,
|
|
NSException, NSInvalidArgumentException);
|
|
XCTAssertThrowsSpecificNamed(
|
|
[NSPredicate predicateWithFormat:@"a LIKE 'glob?trotter'"].mgl_filter, NSException,
|
|
NSInvalidArgumentException);
|
|
XCTAssertThrowsSpecificNamed(
|
|
[NSPredicate predicateWithFormat:@"a MATCHES 'i\\w{18}n'"].mgl_filter, NSException,
|
|
NSInvalidArgumentException);
|
|
NSPredicate *selectorPredicate =
|
|
[NSPredicate predicateWithFormat:@"(SELF isKindOfClass: %@)", [MLNPolyline class]];
|
|
XCTAssertThrowsSpecificNamed(selectorPredicate.mgl_filter, NSException,
|
|
NSInvalidArgumentException);
|
|
|
|
XCTAssertThrowsSpecificNamed(
|
|
[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject,
|
|
NSDictionary<NSString *, id> *_Nullable bindings) {
|
|
XCTAssertTrue(NO, @"Predicate block should not be evaluated.");
|
|
return NO;
|
|
}].mgl_filter,
|
|
NSException, NSInvalidArgumentException);
|
|
}
|
|
|
|
- (void)testComparisonPredicates {
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"x == YES"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"get", @"x" ], @YES ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') < 5"];
|
|
NSArray *jsonExpression = @[ @"<", @[ @"to-number", @[ @"get", @"x" ] ], @5 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') > 5"];
|
|
NSArray *jsonExpression = @[ @">", @[ @"to-number", @[ @"get", @"x" ] ], @5 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') <= 5"];
|
|
NSArray *jsonExpression = @[ @"<=", @[ @"to-number", @[ @"get", @"x" ] ], @5 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') >= 5"];
|
|
NSArray *jsonExpression = @[ @">=", @[ @"to-number", @[ @"get", @"x" ] ], @5 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(x, 'NSString') > 'value'"];
|
|
NSArray *jsonExpression = @[ @">", @[ @"to-string", @[ @"get", @"x" ] ], @"value" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a = 'b'"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"get", @"a" ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$geometryType = 'Point'"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"geometry-type" ], @"Point" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = 67086180"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"id" ], @67086180 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier = nil"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"id" ], [NSNull null] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a = nil"];
|
|
NSArray *jsonExpression = @[ @"==", @[ @"get", @"a" ], [NSNull null] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$geometryType != 'Point'"];
|
|
NSArray *jsonExpression = @[ @"!=", @[ @"geometry-type" ], @"Point" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier != 67086180"];
|
|
NSArray *jsonExpression = @[ @"!=", @[ @"id" ], @67086180 ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier != nil"];
|
|
NSArray *jsonExpression = @[ @"!=", @[ @"id" ], [NSNull null] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a != 'b'"];
|
|
NSArray *jsonExpression = @[ @"!=", @[ @"get", @"a" ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a != nil"];
|
|
NSArray *jsonExpression = @[ @"!=", @[ @"get", @"a" ], [NSNull null] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') < 'b'"];
|
|
NSArray *jsonExpression = @[ @"<", @[ @"to-string", @[ @"get", @"a" ] ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') <= 'b'"];
|
|
NSArray *jsonExpression = @[ @"<=", @[ @"to-string", @[ @"get", @"a" ] ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') > 'b'"];
|
|
NSArray *jsonExpression = @[ @">", @[ @"to-string", @[ @"get", @"a" ] ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') >= 'b'"];
|
|
NSArray *jsonExpression = @[ @">=", @[ @"to-string", @[ @"get", @"a" ] ], @"b" ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST(a, 'NSString') BETWEEN {'b', 'z'}"];
|
|
NSArray *jsonExpression = @[
|
|
@"all", @[ @"<=", @"b", @[ @"to-string", @[ @"get", @"a" ] ] ],
|
|
@[ @"<=", @[ @"to-string", @[ @"get", @"a" ] ], @"z" ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSExpression *limits = [NSExpression expressionForAggregate:@[
|
|
[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]
|
|
]];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') BETWEEN %@", limits];
|
|
NSArray *jsonExpression = @[
|
|
@"all", @[ @">=", @[ @"to-number", @[ @"get", @"x" ] ], @10 ],
|
|
@[ @"<=", @[ @"to-number", @[ @"get", @"x" ] ], @100 ]
|
|
];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"all", @[ @"<=", @10, @[ @"to-number", @[ @"get", @"x" ] ] ],
|
|
@[ @"<=", @[ @"to-number", @[ @"get", @"x" ] ], @100 ]
|
|
];
|
|
NSExpression *limits = [NSExpression expressionForAggregate:@[
|
|
[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]
|
|
]];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') BETWEEN %@", limits];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"all", @[ @"<=", @10, @[ @"to-number", @[ @"get", @"x" ] ] ],
|
|
@[ @">=", @100, @[ @"to-number", @[ @"get", @"x" ] ] ]
|
|
];
|
|
NSExpression *limits = [NSExpression expressionForAggregate:@[
|
|
[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]
|
|
]];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') BETWEEN %@", limits];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"all", @[ @">=", @[ @"to-number", @[ @"get", @"x" ] ], @10 ],
|
|
@[ @">=", @100, @[ @"to-number", @[ @"get", @"x" ] ] ]
|
|
];
|
|
NSExpression *limits = [NSExpression expressionForAggregate:@[
|
|
[NSExpression expressionForConstantValue:@10], [NSExpression expressionForConstantValue:@100]
|
|
]];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST(x, 'NSNumber') BETWEEN %@", limits];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @[ @"id" ], @[ @"literal", @[ @6, @5, @4, @3 ] ] ];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"$featureIdentifier IN { 6, 5, 4, 3}"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"in", @[ @"to-number", @[ @"id" ] ],
|
|
@[ @"literal", @[ @3002970001, @3004140052, @3002950027, @3002970033 ] ]
|
|
];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"CAST($featureIdentifier, 'NSNumber') IN { 3002970001, "
|
|
@"3004140052, 3002950027, 3002970033 }"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected =
|
|
@[ @"!", @[ @"in", @[ @"get", @"x" ], @[ @"literal", @[ @6, @5, @4, @3 ] ] ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT x IN { 6, 5, 4, 3}"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @[ @"get", @"a" ], @[ @"literal", @[ @"b", @"c" ] ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a IN { 'b', 'c' }"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected =
|
|
@[ @"in", @[ @"geometry-type" ], @[ @"literal", @[ @"LineString", @"Polygon" ] ] ];
|
|
NSPredicate *predicate = [NSPredicate
|
|
predicateWithFormat:@"%@ IN %@", [NSExpression expressionForVariable:@"geometryType"],
|
|
@[ @"LineString", @"Polygon" ]];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter =
|
|
[NSPredicate predicateWithFormat:@"%@ IN {'LineString', 'Polygon'}",
|
|
[NSExpression expressionForVariable:@"geometryType"]];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @[ @"get", @"x" ], @[ @"literal", @[ @6, @5, @4, @3 ] ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3 } CONTAINS x"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"x IN { 6, 5, 4, 3 }"];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected =
|
|
@[ @"in", @[ @"geometry-type" ], @[ @"literal", @[ @"LineString", @"Polygon" ] ] ];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[ @"LineString", @"Polygon" ],
|
|
[NSExpression expressionForVariable:@"geometryType"]];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter =
|
|
[NSPredicate predicateWithFormat:@"%@ IN {'LineString', 'Polygon'}",
|
|
[NSExpression expressionForVariable:@"geometryType"]];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @[ @"id" ], @[ @"literal", @[ @6, @5, @4, @3 ] ] ];
|
|
NSPredicate *predicate =
|
|
[NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS $featureIdentifier"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter =
|
|
[NSPredicate predicateWithFormat:@"$featureIdentifier IN {6, 5, 4, 3}"];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @"📍", @[ @"get", @"name" ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"'📍' IN name"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @"📍", @[ @"get", @"name" ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name CONTAINS '📍'"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"'📍' IN name"];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @"📍", @[ @"literal", @"Pinole" ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"'📍' IN 'Pinole'"];
|
|
#if TARGET_OS_IPHONE
|
|
XCTExpectFailure(@"Awaiting unit test refactoring for "
|
|
@"https://github.com/maplibre/maplibre-native/issues/331");
|
|
#endif
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
XCTAssertEqualObjects([NSPredicate mgl_predicateWithFilter:predicate.mgl_filter],
|
|
[NSPredicate predicateWithValue:NO]);
|
|
}
|
|
{
|
|
NSArray *expected = @[ @"in", @"📍", @[ @"literal", @"Pinole" ] ];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"'Pinole' CONTAINS '📍'"];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"'📍' IN 'Pinole'"];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject: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 predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject: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 predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject: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 predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject: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);
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"within",
|
|
@{
|
|
@"type" : @"Polygon",
|
|
@"coordinates" : @[
|
|
@[
|
|
@[ @0, @0 ],
|
|
@[ @0, @1 ],
|
|
@[ @1, @1 ],
|
|
@[ @1, @0 ],
|
|
],
|
|
],
|
|
},
|
|
];
|
|
CLLocationCoordinate2D coordinates[] = {
|
|
{.latitude = 0, .longitude = 0},
|
|
{.latitude = 1, .longitude = 0},
|
|
{.latitude = 1, .longitude = 1},
|
|
{.latitude = 0, .longitude = 1},
|
|
};
|
|
MLNPolygon *shape =
|
|
[MLNPolygon polygonWithCoordinates:coordinates
|
|
count:sizeof(coordinates) / sizeof(coordinates[0])];
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", shape];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
{
|
|
NSArray *expected = @[
|
|
@"within",
|
|
@{
|
|
@"type" : @"Feature",
|
|
@"id" : @"unit",
|
|
@"properties" : @{},
|
|
@"geometry" : @{
|
|
@"type" : @"Polygon",
|
|
@"coordinates" : @[
|
|
@[
|
|
@[ @0, @0 ],
|
|
@[ @0, @1 ],
|
|
@[ @1, @1 ],
|
|
@[ @1, @0 ],
|
|
],
|
|
],
|
|
},
|
|
},
|
|
];
|
|
CLLocationCoordinate2D coordinates[] = {
|
|
{.latitude = 0, .longitude = 0},
|
|
{.latitude = 1, .longitude = 0},
|
|
{.latitude = 1, .longitude = 1},
|
|
{.latitude = 0, .longitude = 1},
|
|
};
|
|
MLNPolygonFeature *feature =
|
|
[MLNPolygonFeature polygonWithCoordinates:coordinates
|
|
count:sizeof(coordinates) / sizeof(coordinates[0])];
|
|
feature.identifier = @"unit";
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS SELF", feature];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
|
|
NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"SELF IN %@", feature];
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:expected], predicateAfter);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:expected]
|
|
mustRoundTrip:YES];
|
|
}
|
|
}
|
|
|
|
- (void)testComparisonPredicatesWithOptions {
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a =[c] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"==", @[ @"get", @"a" ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @YES} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
#if TARGET_OS_IPHONE
|
|
XCTExpectFailure(@"Awaiting unit test refactoring for "
|
|
@"https://github.com/maplibre/maplibre-native/issues/331");
|
|
#endif
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a =[d] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"==", @[ @"get", @"a" ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @YES,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a =[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"==", @[ @"get", @"a" ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a !=[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"!=", @[ @"get", @"a" ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') <[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"<", @[ @"to-string", @[ @"get", @"a" ] ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') <=[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@"<=", @[ @"to-string", @[ @"get", @"a" ] ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') >[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@">", @[ @"to-string", @[ @"get", @"a" ] ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"CAST(a, 'NSString') >=[cd] 'b'"];
|
|
NSArray *jsonExpression = @[
|
|
@">=", @[ @"to-string", @[ @"get", @"a" ] ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO} ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate
|
|
predicateWithFormat:@"TRUE = MLN_FUNCTION('==', a, 'b', MLN_FUNCTION('collator', %@))", @{
|
|
@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO,
|
|
@"locale" : @"tlh",
|
|
}];
|
|
NSArray *jsonExpression = @[
|
|
@"==", @[ @"get", @"a" ], @"b",
|
|
@[ @"collator",
|
|
@{@"case-sensitive" : @NO,
|
|
@"diacritic-sensitive" : @NO,
|
|
@"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 {
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a == 'b' AND c == 'd'"];
|
|
NSArray *jsonExpression =
|
|
@[ @"all", @[ @"==", @[ @"get", @"a" ], @"b" ], @[ @"==", @[ @"get", @"c" ], @"d" ] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a == 'b' OR c == 'd'"];
|
|
NSArray *jsonExpression =
|
|
@[ @"any", @[ @"==", @[ @"get", @"a" ], @"b" ], @[ @"==", @[ @"get", @"c" ], @"d" ] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(a == 'b' AND c == 'd')"];
|
|
NSArray *jsonExpression = @[
|
|
@"!", @[ @"all", @[ @"==", @[ @"get", @"a" ], @"b" ], @[ @"==", @[ @"get", @"c" ], @"d" ] ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT(a == 'b' OR c == 'd')"];
|
|
NSArray *jsonExpression = @[
|
|
@"!", @[ @"any", @[ @"==", @[ @"get", @"a" ], @"b" ], @[ @"==", @[ @"get", @"c" ], @"d" ] ]
|
|
];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
XCTAssertEqualObjects([NSPredicate predicateWithMLNJSONObject:jsonExpression], predicate);
|
|
[self testSymmetryWithPredicate:[NSPredicate predicateWithMLNJSONObject:jsonExpression]
|
|
mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT a == nil"];
|
|
NSArray *jsonExpression = @[ @"!", @[ @"==", @[ @"get", @"a" ], [NSNull null] ] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
{
|
|
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT a != nil"];
|
|
NSArray *jsonExpression = @[ @"!", @[ @"!=", @[ @"get", @"a" ], [NSNull null] ] ];
|
|
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, jsonExpression);
|
|
[self testSymmetryWithPredicate:predicate mustRoundTrip:NO];
|
|
}
|
|
}
|
|
|
|
- (void)testSymmetryWithPredicate:(NSPredicate *)forwardPredicate
|
|
mustRoundTrip:(BOOL)mustRoundTrip {
|
|
auto forwardFilter = forwardPredicate.mgl_filter;
|
|
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
|
|
if (mustRoundTrip) {
|
|
// A collection of ints may turn into an aggregate of longs, for
|
|
// example, so compare formats instead of the predicates themselves.
|
|
XCTAssertEqualObjects(forwardPredicate.predicateFormat.stringByRemovingPointerAddresses,
|
|
forwardPredicateAfter.predicateFormat.stringByRemovingPointerAddresses);
|
|
} else {
|
|
XCTAssertEqualObjects(forwardPredicate, forwardPredicateAfter);
|
|
}
|
|
}
|
|
|
|
@end
|