#import #import #import "NSExpression+MGLAdditions.h" @interface MGLExpressionTests : XCTestCase @end @implementation MGLExpressionTests #pragma mark - Utility - (NSComparisonPredicate *)equalityComparisonPredicateWithRightConstantValue:(id)rightConstantValue { NSComparisonPredicate *predicate = [NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:@"foo"] rightExpression:[NSExpression expressionForConstantValue:rightConstantValue] modifier:NSDirectPredicateModifier type:NSEqualToPredicateOperatorType options:0]; return predicate; } #pragma mark - String Tests - (void)testExpressionConversionString { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@"bar"]; mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssert(convertedValue.is() == true); XCTAssertEqualObjects(@(convertedValue.get().c_str()), @"bar"); } #pragma mark - Boolean Tests - (void)testExpressionConversionBooleanTrue { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@YES]; mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssert(convertedValue.is() == true); XCTAssert(convertedValue.get() == true); } - (void)testExpressionConversionBooleanFalse { NSComparisonPredicate *predicate = [self equalityComparisonPredicateWithRightConstantValue:@NO]; mbgl::Value convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssert(convertedValue.is() == true); XCTAssert(convertedValue.get() == false); } #pragma mark - Floating Point Tests - (void)testExpressionConversionDouble { NSComparisonPredicate *predicate; mbgl::Value convertedValue; predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithDouble:DBL_MIN]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), DBL_MIN); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithDouble:DBL_MAX]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), DBL_MAX); } - (void)testExpressionConversionFloat { // Because we can't guarantee precision when using float, and because // we warn the user to this effect in mgl_convertedValueWithValue:, // we just check that things are in the ballpark here with integer values // and some lower-precision checks. NSComparisonPredicate *predicate; mbgl::Value convertedValue; predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:-1]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), -1); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:1]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), 1); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:-23.232342]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertLessThan(-23.24, convertedValue.get()); XCTAssertGreaterThan(-23.23, convertedValue.get()); predicate = [self equalityComparisonPredicateWithRightConstantValue:[NSNumber numberWithFloat:23.232342]]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertLessThan(23.23, convertedValue.get()); XCTAssertGreaterThan(23.24, convertedValue.get()); } #pragma mark - Integer Tests - (void)testExpressionNegativeIntegers { NSComparisonPredicate *predicate; mbgl::Value convertedValue; NSArray *minValues = @[ [NSNumber numberWithShort: SHRT_MIN], [NSNumber numberWithInt: INT_MIN], [NSNumber numberWithLong: LONG_MIN], [NSNumber numberWithLongLong: LLONG_MIN], [NSNumber numberWithInteger: NSIntegerMin] ]; NSArray *maxValues = @[ [NSNumber numberWithShort: SHRT_MAX], [NSNumber numberWithInt: INT_MAX], [NSNumber numberWithLong: LONG_MAX], [NSNumber numberWithLongLong: LLONG_MAX], [NSNumber numberWithInteger: NSIntegerMax] ]; // Negative integers should always come back as int64_t per mbgl::Value definition. // We use the long long value because it can store the highest number on both 32- // and 64-bit and won't overflow. for (NSNumber *min in minValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:min]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), min.longLongValue); } // Positive integers should always come back as uint64_t per mbgl::Value definition. // We use the unsigned long long value because it can store the highest number on // both 32- and 64-bit and won't overflow. for (NSNumber *max in maxValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:max]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), max.unsignedLongLongValue); } } - (void)testExpressionPositiveAndZeroIntegers { NSComparisonPredicate *predicate; mbgl::Value convertedValue; NSArray *minValues = @[ [NSNumber numberWithUnsignedShort: 0], [NSNumber numberWithUnsignedInt: 0], [NSNumber numberWithUnsignedLong: 0], [NSNumber numberWithUnsignedLongLong: 0], [NSNumber numberWithUnsignedInteger: 0] ]; NSArray *maxValues = @[ [NSNumber numberWithUnsignedShort: USHRT_MAX], [NSNumber numberWithUnsignedInt: UINT_MAX], [NSNumber numberWithUnsignedLong: ULONG_MAX], [NSNumber numberWithUnsignedLongLong: ULLONG_MAX], [NSNumber numberWithUnsignedInteger: NSUIntegerMax] ]; // Zero-value integers should always come back as uint64_t per mbgl::Value definition // (using the interpretation that zero is not negative). We use the unsigned long long // value just for parity with the positive integer test. for (NSNumber *min in minValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:min]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), min.unsignedLongLongValue); } // Positive integers should always come back as uint64_t per mbgl::Value definition. // We use the unsigned long long value because it can store the highest number on // both 32- and 64-bit and won't overflow. for (NSNumber *max in maxValues) { predicate = [self equalityComparisonPredicateWithRightConstantValue:max]; convertedValue = predicate.rightExpression.mgl_filterValue; XCTAssertTrue(convertedValue.is()); XCTAssertEqual(convertedValue.get(), max.unsignedLongLongValue); } } @end