diff options
Diffstat (limited to 'platform')
-rw-r--r-- | platform/darwin/src/NSArray+MGLAdditions.mm | 4 | ||||
-rw-r--r-- | platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm | 10 | ||||
-rw-r--r-- | platform/darwin/src/NSDictionary+MGLAdditions.mm | 2 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.h | 10 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.mm | 60 | ||||
-rw-r--r-- | platform/darwin/src/NSPredicate+MGLAdditions.mm | 34 | ||||
-rw-r--r-- | platform/darwin/test/MGLExpressionTests.mm | 54 | ||||
-rw-r--r-- | platform/darwin/test/MGLPredicateTests.mm | 13 |
8 files changed, 95 insertions, 92 deletions
diff --git a/platform/darwin/src/NSArray+MGLAdditions.mm b/platform/darwin/src/NSArray+MGLAdditions.mm index f2c5a096cc..8ec344f580 100644 --- a/platform/darwin/src/NSArray+MGLAdditions.mm +++ b/platform/darwin/src/NSArray+MGLAdditions.mm @@ -17,9 +17,9 @@ vector.push_back(propertyMap); } else { NSExpression *expression = [NSExpression expressionForConstantValue:value]; - vector.push_back([expression mgl_filterValue]); + vector.push_back(expression.mgl_constantMBGLValue); } - } + } return vector; } diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm index 58390b0b81..58b37fae0e 100644 --- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm +++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm @@ -105,7 +105,7 @@ } mbgl::style::InFilter inFilter; inFilter.key = leftExpression.keyPath.UTF8String; - inFilter.values = rightExpression.mgl_filterValues; + inFilter.values = rightExpression.mgl_aggregateMBGLValue; return inFilter; } case NSContainsPredicateOperatorType: { @@ -119,7 +119,7 @@ } mbgl::style::InFilter inFilter; inFilter.key = rightExpression.keyPath.UTF8String; - inFilter.values = leftExpression.mgl_filterValues; + inFilter.values = leftExpression.mgl_aggregateMBGLValue; return inFilter; } case NSBetweenPredicateOperatorType: { @@ -131,7 +131,7 @@ [NSException raise:NSInvalidArgumentException format:@"Right side of BETWEEN predicate must be an array."]; // not NSSet } - auto values = rightExpression.mgl_filterValues; + auto values = rightExpression.mgl_aggregateMBGLValue; if (values.size() != 2) { [NSException raise:NSInvalidArgumentException format:@"Right side of BETWEEN predicate must have two items."]; @@ -182,9 +182,9 @@ NSExpressionType rightType = rightExpression.expressionType; mbgl::Value value; if (leftType == NSKeyPathExpressionType && rightType == NSConstantValueExpressionType) { - value = rightExpression.mgl_filterValue; + value = rightExpression.mgl_constantMBGLValue; } else if (leftType == NSConstantValueExpressionType && rightType == NSKeyPathExpressionType) { - value = leftExpression.mgl_filterValue; + value = leftExpression.mgl_constantMBGLValue; } else { [NSException raise:NSInvalidArgumentException format:@"Comparison predicate must compare an attribute (as a key path) to a constant or vice versa."]; diff --git a/platform/darwin/src/NSDictionary+MGLAdditions.mm b/platform/darwin/src/NSDictionary+MGLAdditions.mm index 1023e91a48..aad7fd8810 100644 --- a/platform/darwin/src/NSDictionary+MGLAdditions.mm +++ b/platform/darwin/src/NSDictionary+MGLAdditions.mm @@ -15,7 +15,7 @@ propertyMap[[key UTF8String]] = [array mgl_vector]; } else { NSExpression *expression = [NSExpression expressionForConstantValue:self[key]]; - propertyMap[[key UTF8String]] = [expression mgl_filterValue]; + propertyMap[[key UTF8String]] = expression.mgl_constantMBGLValue; } } return propertyMap; diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h index 6d0fff5760..c60d6d78ba 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.h +++ b/platform/darwin/src/NSExpression+MGLAdditions.h @@ -2,10 +2,14 @@ #include <mbgl/style/filter.hpp> +NS_ASSUME_NONNULL_BEGIN + @interface NSExpression (MGLAdditions) -- (mbgl::Value)mgl_filterValue; -- (std::vector<mbgl::Value>)mgl_filterValues; -- (mbgl::FeatureIdentifier)mgl_featureIdentifier; +@property (nonatomic, readonly) mbgl::Value mgl_constantMBGLValue; +@property (nonatomic, readonly) std::vector<mbgl::Value> mgl_aggregateMBGLValue; +@property (nonatomic, readonly) mbgl::FeatureIdentifier mgl_featureIdentifier; @end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm index 97f3e11dba..f11a1919cf 100644 --- a/platform/darwin/src/NSExpression+MGLAdditions.mm +++ b/platform/darwin/src/NSExpression+MGLAdditions.mm @@ -2,31 +2,25 @@ @implementation NSExpression (MGLAdditions) -- (std::vector<mbgl::Value>)mgl_filterValues -{ +- (std::vector<mbgl::Value>)mgl_aggregateMBGLValue { if ([self.constantValue isKindOfClass:[NSArray class]] || [self.constantValue isKindOfClass:[NSSet class]]) { std::vector<mbgl::Value> convertedValues; - for (id item in self.constantValue) { - id constantValue = item; - if ([item isKindOfClass:[NSExpression class]]) { - constantValue = [constantValue constantValue]; + for (id value in self.constantValue) { + NSExpression *expression = value; + if (![expression isKindOfClass:[NSExpression class]]) { + expression = [NSExpression expressionForConstantValue:expression]; } - convertedValues.push_back([self mgl_convertedValueWithValue:constantValue]); + convertedValues.push_back(expression.mgl_constantMBGLValue); } return convertedValues; } [NSException raise:NSInvalidArgumentException format:@"Constant value expression must contain an array or set."]; - return { }; -} - -- (mbgl::Value)mgl_filterValue -{ - return [self mgl_convertedValueWithValue:self.constantValue]; + return {}; } -- (mbgl::Value)mgl_convertedValueWithValue:(id)value -{ +- (mbgl::Value)mgl_constantMBGLValue { + id value = self.constantValue; if ([value isKindOfClass:NSString.class]) { return { std::string([(NSString *)value UTF8String]) }; } else if ([value isKindOfClass:NSNumber.class]) { @@ -66,30 +60,26 @@ [NSException raise:NSInvalidArgumentException format:@"Can’t convert %s:%@ to mbgl::Value", [value objCType], value]; } - return { }; + return {}; } -- (mbgl::FeatureIdentifier)mgl_featureIdentifier -{ - id value = self.constantValue; - mbgl::Value mbglValue = [self mgl_filterValue]; +- (mbgl::FeatureIdentifier)mgl_featureIdentifier { + mbgl::Value mbglValue = self.mgl_constantMBGLValue; - if ([value isKindOfClass:NSString.class]) { + if (mbglValue.is<std::string>()) { return mbglValue.get<std::string>(); - } else if ([value isKindOfClass:NSNumber.class]) { - NSNumber *number = (NSNumber *)value; - if ((strcmp([number objCType], @encode(char)) == 0) || - (strcmp([number objCType], @encode(BOOL)) == 0)) { - return mbglValue.get<bool>(); - } else if ( strcmp([number objCType], @encode(double)) == 0 || - strcmp([number objCType], @encode(float)) == 0) { - return mbglValue.get<double>(); - } else if ([number compare:@(0)] == NSOrderedDescending || - [number compare:@(0)] == NSOrderedSame) { - return mbglValue.get<uint64_t>(); - } else if ([number compare:@(0)] == NSOrderedAscending) { - return mbglValue.get<int64_t>(); - } + } + if (mbglValue.is<bool>()) { + return mbglValue.get<bool>(); + } + if (mbglValue.is<double>()) { + return mbglValue.get<double>(); + } + if (mbglValue.is<uint64_t>()) { + return mbglValue.get<uint64_t>(); + } + if (mbglValue.is<int64_t>()) { + return mbglValue.get<int64_t>(); } return {}; diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm index f999df96b0..0ac68095f9 100644 --- a/platform/darwin/src/NSPredicate+MGLAdditions.mm +++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm @@ -5,7 +5,7 @@ class FilterEvaluator { public: - NSArray* getPredicates(std::vector<mbgl::style::Filter> filters) { + NSArray *getPredicates(std::vector<mbgl::style::Filter> filters) { NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:filters.size()]; for (auto filter : filters) { [predicates addObject:mbgl::style::Filter::visit(filter, FilterEvaluator())]; @@ -13,52 +13,52 @@ public: return predicates; } - NSArray* getValues(std::vector<mbgl::Value> values) { + NSExpression *getValues(std::vector<mbgl::Value> values) { NSMutableArray *array = [NSMutableArray arrayWithCapacity:values.size()]; for (auto value : values) { id constantValue = mbgl::Value::visit(value, ValueEvaluator()); [array addObject:[NSExpression expressionForConstantValue:constantValue]]; } - return array; + return [NSExpression expressionForAggregate:array]; } - NSPredicate* operator()(mbgl::style::NullFilter filter) { + NSPredicate *operator()(mbgl::style::NullFilter filter) { return nil; } - NSPredicate* operator()(mbgl::style::EqualsFilter filter) { + NSPredicate *operator()(mbgl::style::EqualsFilter filter) { return [NSPredicate predicateWithFormat:@"%K == %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::NotEqualsFilter filter) { + NSPredicate *operator()(mbgl::style::NotEqualsFilter filter) { return [NSPredicate predicateWithFormat:@"%K != %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::GreaterThanFilter filter) { + NSPredicate *operator()(mbgl::style::GreaterThanFilter filter) { return [NSPredicate predicateWithFormat:@"%K > %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::GreaterThanEqualsFilter filter) { + NSPredicate *operator()(mbgl::style::GreaterThanEqualsFilter filter) { return [NSPredicate predicateWithFormat:@"%K >= %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::LessThanFilter filter) { + NSPredicate *operator()(mbgl::style::LessThanFilter filter) { return [NSPredicate predicateWithFormat:@"%K < %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::LessThanEqualsFilter filter) { + NSPredicate *operator()(mbgl::style::LessThanEqualsFilter filter) { return [NSPredicate predicateWithFormat:@"%K <= %@", @(filter.key.c_str()), mbgl::Value::visit(filter.value, ValueEvaluator())]; } - NSPredicate* operator()(mbgl::style::InFilter filter) { + NSPredicate *operator()(mbgl::style::InFilter filter) { return [NSPredicate predicateWithFormat:@"%K IN %@", @(filter.key.c_str()), getValues(filter.values)]; } - NSPredicate* operator()(mbgl::style::NotInFilter filter) { + NSPredicate *operator()(mbgl::style::NotInFilter filter) { return [NSPredicate predicateWithFormat:@"NOT %K IN %@", @(filter.key.c_str()), getValues(filter.values)]; } - NSPredicate* operator()(mbgl::style::AnyFilter filter) { + NSPredicate *operator()(mbgl::style::AnyFilter filter) { NSArray *subpredicates = getPredicates(filter.filters); if (subpredicates.count) { return [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates]; @@ -66,7 +66,7 @@ public: return [NSPredicate predicateWithValue:NO]; } - NSPredicate* operator()(mbgl::style::AllFilter filter) { + NSPredicate *operator()(mbgl::style::AllFilter filter) { // Convert [all, [>=, key, lower], [<=, key, upper]] to key BETWEEN {lower, upper} if (filter.filters.size() == 2) { auto leftFilter = filter.filters[0]; @@ -108,7 +108,7 @@ public: return [NSPredicate predicateWithValue:YES]; } - NSPredicate* operator()(mbgl::style::NoneFilter filter) { + NSPredicate *operator()(mbgl::style::NoneFilter filter) { NSArray *subpredicates = getPredicates(filter.filters); if (subpredicates.count > 1) { NSCompoundPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:subpredicates]; @@ -120,11 +120,11 @@ public: } } - NSPredicate* operator()(mbgl::style::HasFilter filter) { + NSPredicate *operator()(mbgl::style::HasFilter filter) { return [NSPredicate predicateWithFormat:@"%K != nil", @(filter.key.c_str())]; } - NSPredicate* operator()(mbgl::style::NotHasFilter filter) { + NSPredicate *operator()(mbgl::style::NotHasFilter filter) { return [NSPredicate predicateWithFormat:@"%K == nil", @(filter.key.c_str())]; } diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm index e78f87a99b..00b57c15f0 100644 --- a/platform/darwin/test/MGLExpressionTests.mm +++ b/platform/darwin/test/MGLExpressionTests.mm @@ -28,27 +28,35 @@ - (void)testExpressionConversionString { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@"bar"]; - mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; - XCTAssert(convertedValue.is<std::string>() == true); + mbgl::Value convertedValue = predicate.rightExpression.mgl_constantMBGLValue; + XCTAssertTrue(convertedValue.is<std::string>()); XCTAssertEqualObjects(@(convertedValue.get<std::string>().c_str()), @"bar"); } +- (void)testExpressionConversionStringWithUnicode +{ + NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@"🆔🆗🇦🇶"]; + mbgl::Value convertedValue = predicate.rightExpression.mgl_constantMBGLValue; + XCTAssertTrue(convertedValue.is<std::string>()); + XCTAssertEqual(convertedValue.get<std::string>(), "🆔🆗🇦🇶"); +} + #pragma mark - Boolean Tests - (void)testExpressionConversionBooleanTrue { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@YES]; - mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; - XCTAssert(convertedValue.is<bool>() == true); - XCTAssert(convertedValue.get<bool>() == true); + mbgl::Value convertedValue = predicate.rightExpression.mgl_constantMBGLValue; + XCTAssertTrue(convertedValue.is<bool>()); + XCTAssertEqual(convertedValue.get<bool>(), true); } - (void)testExpressionConversionBooleanFalse { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@NO]; - mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; - XCTAssert(convertedValue.is<bool>() == true); - XCTAssert(convertedValue.get<bool>() == false); + mbgl::Value convertedValue = predicate.rightExpression.mgl_constantMBGLValue; + XCTAssertTrue(convertedValue.is<bool>()); + XCTAssertEqual(convertedValue.get<bool>(), false); } #pragma mark - Floating Point Tests @@ -59,12 +67,12 @@ mbgl::Value convertedValue; predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithDouble:DBL_MIN]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); XCTAssertEqual(convertedValue.get<double>(), DBL_MIN); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithDouble:DBL_MAX]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); XCTAssertEqual(convertedValue.get<double>(), DBL_MAX); } @@ -72,7 +80,7 @@ - (void)testExpressionConversionFloat { // Because we can't guarantee precision when using float, and because - // we warn the user to this effect in mgl_convertedValueWithValue:, + // we warn the user to this effect in -[NSExpression mgl_constantMBGLValue], // we just check that things are in the ballpark here with integer values // and some lower-precision checks. @@ -80,26 +88,24 @@ mbgl::Value convertedValue; predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:-1]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); XCTAssertEqual(convertedValue.get<double>(), -1); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:1]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); XCTAssertEqual(convertedValue.get<double>(), 1); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:-23.232342]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); - XCTAssertLessThan(-23.24, convertedValue.get<double>()); - XCTAssertGreaterThan(-23.23, convertedValue.get<double>()); + XCTAssertEqualWithAccuracy(convertedValue.get<double>(), -23.232342, 0.000001); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:23.232342]]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<double>()); - XCTAssertLessThan(23.23, convertedValue.get<double>()); - XCTAssertGreaterThan(23.24, convertedValue.get<double>()); + XCTAssertEqualWithAccuracy(convertedValue.get<double>(), 23.232342, 0.000001); } #pragma mark - Integer Tests @@ -132,7 +138,7 @@ for (NSNumber *min in minValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:min]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<int64_t>()); XCTAssertEqual(convertedValue.get<int64_t>(), min.longLongValue); } @@ -144,7 +150,7 @@ for (NSNumber *max in maxValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:max]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<uint64_t>()); XCTAssertEqual(convertedValue.get<uint64_t>(), max.unsignedLongLongValue); } @@ -179,7 +185,7 @@ for (NSNumber *min in minValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:min]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<uint64_t>()); XCTAssertEqual(convertedValue.get<uint64_t>(), min.unsignedLongLongValue); } @@ -191,7 +197,7 @@ for (NSNumber *max in maxValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:max]; - convertedValue = predicate.rightExpression.mgl_filterValue; + convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<uint64_t>()); XCTAssertEqual(convertedValue.get<uint64_t>(), max.unsignedLongLongValue); } @@ -202,7 +208,7 @@ - (void)testExpressionConversionNull { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNull null]]; - mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; + mbgl::Value convertedValue = predicate.rightExpression.mgl_constantMBGLValue; XCTAssertTrue(convertedValue.is<mbgl::NullValue>()); } diff --git a/platform/darwin/test/MGLPredicateTests.mm b/platform/darwin/test/MGLPredicateTests.mm index 07466dfd13..fbd144d28a 100644 --- a/platform/darwin/test/MGLPredicateTests.mm +++ b/platform/darwin/test/MGLPredicateTests.mm @@ -369,9 +369,9 @@ namespace mbgl { [self testSymmetryWithFormat:@"a > 1" reverseFormat:@"1 < a" mustRoundTrip:YES]; [self testSymmetryWithFormat:@"a >= 1" reverseFormat:@"1 <= a" mustRoundTrip:YES]; - [self testSymmetryWithFormat:@"a BETWEEN {1, 2}" reverseFormat:nil mustRoundTrip:YES]; + [self testSymmetryWithFormat:@"a BETWEEN {1, 2}" reverseFormat:@"1 <= a && 2 >= a" mustRoundTrip:YES]; [self testSymmetryWithPredicate:[NSPredicate predicateWithFormat:@"a BETWEEN %@", @[@1, @2]] - reversePredicate:nil + reversePredicate:[NSPredicate predicateWithFormat:@"1 <= a && 2 >= a"] mustRoundTrip:YES]; XCTAssertThrowsSpecificNamed([NSPredicate predicateWithFormat:@"{1, 2} BETWEEN a"].mgl_filter, NSException, NSInvalidArgumentException); NSPredicate *betweenSetPredicate = [NSPredicate predicateWithFormat:@"a BETWEEN %@", [NSSet setWithObjects:@1, @2, nil]]; @@ -384,9 +384,11 @@ namespace mbgl { reversePredicate:[NSPredicate predicateWithFormat:@"%@ CONTAINS a", @[@1, @2]] mustRoundTrip:YES]; - [self testSymmetryWithFormat:@"{1, 2} CONTAINS a" reverseFormat:@"a IN {1, 2}" mustRoundTrip:NO]; + // The reverse formats here are a bit backwards because we canonicalize + // a reverse CONTAINS to a forward IN. + [self testSymmetryWithFormat:@"{1, 2} CONTAINS a" reverseFormat:@"{1, 2} CONTAINS a" mustRoundTrip:NO]; [self testSymmetryWithPredicate:[NSPredicate predicateWithFormat:@"%@ CONTAINS a", @[@1, @2]] - reversePredicate:[NSPredicate predicateWithFormat:@"a IN %@", @[@1, @2]] + reversePredicate:[NSPredicate predicateWithFormat:@"%@ CONTAINS a", @[@1, @2]] mustRoundTrip:NO]; } @@ -400,7 +402,8 @@ namespace mbgl { auto forwardFilter = forwardPredicate.mgl_filter; NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter]; if (mustRoundTrip) { - // Aggregates should round-trip, but for some reason only their format strings do. + // A collection of ints may turn into an aggregate of longs, for + // example, so compare formats instead of the predicates themselves. XCTAssertEqualObjects(forwardPredicate.predicateFormat, forwardPredicateAfter.predicateFormat); } |